diff options
Diffstat (limited to 'Build/source/libs/icu-xetex/layout')
60 files changed, 2969 insertions, 831 deletions
diff --git a/Build/source/libs/icu-xetex/layout/AnchorTables.cpp b/Build/source/libs/icu-xetex/layout/AnchorTables.cpp index 94980da676a..24f3cf31df4 100644 --- a/Build/source/libs/icu-xetex/layout/AnchorTables.cpp +++ b/Build/source/libs/icu-xetex/layout/AnchorTables.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -41,9 +41,10 @@ void AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstanc } default: - // Unknown format, set the anchor point to (0, 0) - anchor.fX = 0; - anchor.fY = 0; + // unknown format: just use x, y coordinate, like format 1... + const Format1AnchorTable *f1 = (const Format1AnchorTable *) this; + + f1->getAnchor(fontInstance, anchor); break; } } diff --git a/Build/source/libs/icu-xetex/layout/ArabicLayoutEngine.cpp b/Build/source/libs/icu-xetex/layout/ArabicLayoutEngine.cpp index da0950e9110..424447433ec 100644 --- a/Build/source/libs/icu-xetex/layout/ArabicLayoutEngine.cpp +++ b/Build/source/libs/icu-xetex/layout/ArabicLayoutEngine.cpp @@ -37,14 +37,22 @@ ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fon le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable) { - /**/ fFeatureOrder = ArabicShaping::getFeatureOrder(); + fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount); + fFeatureOrder = TRUE; } ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags) { - // fFeatureOrder = ArabicShaping::getFeatureOrder(); + fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount); + + // NOTE: We don't need to set fFeatureOrder to TRUE here + // because this constructor is only called by the constructor + // for UnicodeArabicOpenTypeLayoutEngine, which uses a pre-built + // GSUB table that has the features in the correct order. + + //fFeatureOrder = TRUE; } ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine() @@ -156,14 +164,14 @@ le_int32 UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage & glyphStorage.adoptCharIndicesArray(tempGlyphStorage); - ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars, 0, tempGlyphCount, FALSE, TRUE, glyphStorage, success); + ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars, 0, tempGlyphCount, FALSE, TRUE, TRUE, glyphStorage, success); LE_DELETE_ARRAY(tempChars); return tempGlyphCount; } -void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool /*mirror*/, LEGlyphStorage &glyphStorage, LEErrorCode &success) +void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool /*mirror*/, le_bool /*filterZeroWidth*/, LEGlyphStorage &glyphStorage, LEErrorCode &success) { if (LE_FAILURE(success)) { return; diff --git a/Build/source/libs/icu-xetex/layout/ArabicLayoutEngine.h b/Build/source/libs/icu-xetex/layout/ArabicLayoutEngine.h index 788c07f5782..68378985336 100644 --- a/Build/source/libs/icu-xetex/layout/ArabicLayoutEngine.h +++ b/Build/source/libs/icu-xetex/layout/ArabicLayoutEngine.h @@ -207,13 +207,14 @@ protected: * @param count - the number of characters to be mapped * @param reverse - if <code>TRUE</code>, the output will be in reverse order * @param mirror - if <code>TRUE</code>, do character mirroring + * @param filterZeroWidth - if <code>TRUE</code> replace ZWJ / ZWNJ with a glyph with no contours. * @param glyphStorage - the glyph storage object. Glyph and char index arrays will be updated. * * @param success - set to an error code if the operation fails * * @internal */ - virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, + virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage, LEErrorCode &success); /** diff --git a/Build/source/libs/icu-xetex/layout/ArabicShaping.cpp b/Build/source/libs/icu-xetex/layout/ArabicShaping.cpp index 36cfd679aa9..9550910ad84 100644 --- a/Build/source/libs/icu-xetex/layout/ArabicShaping.cpp +++ b/Build/source/libs/icu-xetex/layout/ArabicShaping.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -8,48 +8,30 @@ #include "OpenTypeTables.h" #include "ArabicShaping.h" #include "LEGlyphStorage.h" +#include "ClassDefinitionTables.h" U_NAMESPACE_BEGIN +// This table maps Unicode joining types to +// ShapeTypes. +const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] = +{ + ArabicShaping::ST_NOSHAPE_NONE, // [U] + ArabicShaping::ST_NOSHAPE_DUAL, // [C] + ArabicShaping::ST_DUAL, // [D] + ArabicShaping::ST_LEFT, // [L] + ArabicShaping::ST_RIGHT, // [R] + ArabicShaping::ST_TRANSPARENT // [T] +}; + +// Draft Mongolian shaping classes, not provided by the Unicode data files at this time enum { _c_ = ArabicShaping::ST_NOSHAPE_DUAL, _d_ = ArabicShaping::ST_DUAL, _n_ = ArabicShaping::ST_NONE, _r_ = ArabicShaping::ST_RIGHT, _t_ = ArabicShaping::ST_TRANSPARENT, - _x_ = ArabicShaping::ST_NOSHAPE_NONE, - _A_ = ArabicShaping::ST_ALAPH, - _R_ = ArabicShaping::ST_DALATH_RISH -}; - -const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] = -{ -// Arabic block - _t_, _t_, _t_, _t_, _t_, _t_, _x_, _x_, _x_, _x_, _x_, _n_, _x_, _x_, _x_, _n_, // 0x610 - 0x61f - _x_, _n_, _r_, _r_, _r_, _r_, _d_, _r_, _d_, _r_, _d_, _d_, _d_, _d_, _d_, _r_, // 0x620 - 0x62f - _r_, _r_, _r_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _x_, _x_, _x_, _x_, _x_, // 0x630 - 0x63f - _c_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _r_, _d_, _d_, _t_, _t_, _t_, _t_, _t_, // 0x640 - 0x64f - _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _x_, // 0x650 - 0x65f - _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _d_, _d_, // 0x660 - 0x66f - _t_, _r_, _r_, _r_, _n_, _r_, _r_, _r_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x670 - 0x67f - _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, // 0x680 - 0x68f - _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x690 - 0x69f - _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x6a0 - 0x6af - _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x6b0 - 0x6bf - _r_, _d_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _d_, _r_, _d_, _r_, // 0x6c0 - 0x6cf - _d_, _d_, _r_, _r_, _n_, _r_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _x_, _t_, _t_, // 0x6d0 - 0x6df - _t_, _t_, _t_, _t_, _t_, _n_, _n_, _t_, _t_, _n_, _t_, _t_, _t_, _t_, _r_, _r_, // 0x6e0 - 0x6ef - _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _d_, _d_, _d_, _n_, _n_, _d_, // 0x6f0 - 0x6ff -// Syriac - _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _t_, // 0x700 - 0x70f - _A_, _t_, _d_, _d_, _d_, _R_, _R_, _r_, _r_, _r_, _d_, _d_, _d_, _d_, _r_, _d_, // 0x710 - 0x71f - _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _r_, _d_, _R_, _d_, _r_, _d_, _d_, _R_, // 0x720 - 0x72f - _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, // 0x730 - 0x73f - _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _x_, _x_, _r_, _d_, _d_, // 0x740 - 0x74f -// Arabic Supplement - _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _r_, _r_, _r_, _d_, _d_, _d_, _d_, // 0x750 - 0x75f - _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _r_, _r_, _d_, _x_, _x_, // 0x760 - 0x76f - _x_, _x_, _x_, _x_, _x_, _x_, _x_, _x_, _x_, _x_, _x_, _x_, _x_, _x_, _x_, _x_ // 0x770 - 0x77f + _x_ = ArabicShaping::ST_NOSHAPE_NONE }; const ArabicShaping::ShapeType ArabicShaping::mongolianTypes[] = @@ -68,8 +50,7 @@ const ArabicShaping::ShapeType ArabicShaping::mongolianTypes[] = }; /* - shaping array holds types for Arabic/Syriac chars between 0610 and 077f; - mongolian array holds types for Mongolian chars between 1800 and 18af; + shaping array holds types for Arabic chars between 0610 and 0700 other values are either unshaped, or transparent if a mark or format code, except for format codes 200c (zero-width non-joiner) and 200d (dual-width joiner) which are both unshaped and non_joining or @@ -77,97 +58,112 @@ const ArabicShaping::ShapeType ArabicShaping::mongolianTypes[] = */ ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c) { - if (c >= 0x0300 && c <= 0x206f) { - if (/*c >= 0x0300 &&*/ c <= 0x036f) { // Combining Marks - return ST_TRANSPARENT; - } else if (c >= 0x0610 && c <= 0x077f) { // Arabic/Syriac/Arabic Supplement - return shapeTypes[c - 0x0610]; - } else if (c >= 0x1800 && c <= 0x18af) { // Mongolian - return mongolianTypes[c - 0x1800]; - } else if (c == 0x200c) { // ZWNJ - return ST_NOSHAPE_NONE; - } else if (c == 0x200d) { // ZWJ - return ST_NOSHAPE_DUAL; - } else if (c >= 0x202a && c <= 0x202e) { // LRE - RLO - return ST_TRANSPARENT; - } else if (c >= 0x206a /*&& c <= 0x206f*/) { // Inhibit Symmetric Swapping - Nominal Digit Shapes - return ST_TRANSPARENT; - } + const ClassDefinitionTable *joiningTypes = (const ClassDefinitionTable *) ArabicShaping::shapingTypeTable; + le_int32 joiningType = joiningTypes->getGlyphClass(c); + + if (joiningType == JT_RIGHT_JOINING) { // check for Syriac exceptions ALAPH, DALATH, RISH + if (c == 0x0710) + return ST_ALAPH; + if (c == 0x0715 || c == 0x0716 || c == 0x072A || c == 0x072F) + return ST_DALATH_RISH; + } + + if (joiningType == 0) { // check for Mongolian range, not supported by ArabicShaping::shapingTypeTable + if (c >= 0x1800 && c <= 0x18af) + return mongolianTypes[c - 0x1800]; + } + + if (joiningType >= 0 && joiningType < JT_COUNT) { + return shapeTypes[joiningType]; } return ST_NOSHAPE_NONE; } -static const LETag isolFeatureTag = LE_ISOL_FEATURE_TAG; -static const LETag initFeatureTag = LE_INIT_FEATURE_TAG; -static const LETag mediFeatureTag = LE_MEDI_FEATURE_TAG; -static const LETag finaFeatureTag = LE_FINA_FEATURE_TAG; -static const LETag ligaFeatureTag = LE_LIGA_FEATURE_TAG; -static const LETag msetFeatureTag = LE_MSET_FEATURE_TAG; -static const LETag markFeatureTag = LE_MARK_FEATURE_TAG; -static const LETag ccmpFeatureTag = LE_CCMP_FEATURE_TAG; -static const LETag rligFeatureTag = LE_RLIG_FEATURE_TAG; -static const LETag caltFeatureTag = LE_CALT_FEATURE_TAG; -static const LETag dligFeatureTag = LE_DLIG_FEATURE_TAG; -static const LETag cswhFeatureTag = LE_CSWH_FEATURE_TAG; -static const LETag cursFeatureTag = LE_CURS_FEATURE_TAG; -static const LETag kernFeatureTag = LE_KERN_FEATURE_TAG; -static const LETag mkmkFeatureTag = LE_MKMK_FEATURE_TAG; -static const LETag med2FeatureTag = LE_MED2_FEATURE_TAG; -static const LETag fin2FeatureTag = LE_FIN2_FEATURE_TAG; -static const LETag fin3FeatureTag = LE_FIN3_FEATURE_TAG; - -static const LETag emptyTag = 0x00000000; // '' - -static const LETag featureOrder[] = -{ - ccmpFeatureTag, isolFeatureTag, finaFeatureTag, fin2FeatureTag, fin3FeatureTag, mediFeatureTag, - med2FeatureTag, initFeatureTag, rligFeatureTag, caltFeatureTag, ligaFeatureTag, dligFeatureTag, - cswhFeatureTag, msetFeatureTag, cursFeatureTag, kernFeatureTag, markFeatureTag, mkmkFeatureTag, - emptyTag +#define isolFeatureTag LE_ISOL_FEATURE_TAG +#define initFeatureTag LE_INIT_FEATURE_TAG +#define mediFeatureTag LE_MEDI_FEATURE_TAG +#define med2FeatureTag LE_MED2_FEATURE_TAG +#define finaFeatureTag LE_FINA_FEATURE_TAG +#define fin2FeatureTag LE_FIN2_FEATURE_TAG +#define fin3FeatureTag LE_FIN3_FEATURE_TAG +#define ligaFeatureTag LE_LIGA_FEATURE_TAG +#define msetFeatureTag LE_MSET_FEATURE_TAG +#define markFeatureTag LE_MARK_FEATURE_TAG +#define ccmpFeatureTag LE_CCMP_FEATURE_TAG +#define rligFeatureTag LE_RLIG_FEATURE_TAG +#define caltFeatureTag LE_CALT_FEATURE_TAG +#define dligFeatureTag LE_DLIG_FEATURE_TAG +#define cswhFeatureTag LE_CSWH_FEATURE_TAG +#define cursFeatureTag LE_CURS_FEATURE_TAG +#define kernFeatureTag LE_KERN_FEATURE_TAG +#define mkmkFeatureTag LE_MKMK_FEATURE_TAG + +// NOTE: +// The isol, fina, init and medi features must be +// defined in the above order, and have masks that +// are all in the same byte. +#define isolFeatureMask 0x80000000UL +#define finaFeatureMask 0x40000000UL +#define initFeatureMask 0x20000000UL +#define mediFeatureMask 0x10000000UL +#define fin2FeatureMask 0x08000000UL +#define fin3FeatureMask 0x04000000UL +#define med2FeatureMask 0x03000000UL /* two bits, from shifting either fin2 or fin3 */ + +#define ccmpFeatureMask 0x00800000UL +#define rligFeatureMask 0x00400000UL +#define caltFeatureMask 0x00200000UL +#define ligaFeatureMask 0x00100000UL +#define dligFeatureMask 0x00080000UL +#define cswhFeatureMask 0x00040000UL +#define msetFeatureMask 0x00020000UL +#define cursFeatureMask 0x00010000UL +#define kernFeatureMask 0x00008000UL +#define markFeatureMask 0x00004000UL +#define mkmkFeatureMask 0x00002000UL + +#define ISOL_FEATURES (isolFeatureMask | ligaFeatureMask | msetFeatureMask | markFeatureMask | ccmpFeatureMask | rligFeatureMask | caltFeatureMask | dligFeatureMask | cswhFeatureMask | cursFeatureMask | kernFeatureMask | mkmkFeatureMask) + +#define SHAPE_MASK 0xFF000000UL + +static const FeatureMap featureMap[] = { + {ccmpFeatureTag, ccmpFeatureMask}, + {isolFeatureTag, isolFeatureMask}, + {finaFeatureTag, finaFeatureMask}, + {fin2FeatureTag, fin2FeatureMask}, + {fin3FeatureTag, fin3FeatureMask}, + {mediFeatureTag, mediFeatureMask}, + {med2FeatureTag, med2FeatureMask}, + {initFeatureTag, initFeatureMask}, + {rligFeatureTag, rligFeatureMask}, + {caltFeatureTag, caltFeatureMask}, + {ligaFeatureTag, ligaFeatureMask}, + {dligFeatureTag, dligFeatureMask}, + {cswhFeatureTag, cswhFeatureMask}, + {msetFeatureTag, msetFeatureMask}, + {cursFeatureTag, cursFeatureMask}, + {kernFeatureTag, kernFeatureMask}, + {markFeatureTag, markFeatureMask}, + {mkmkFeatureTag, mkmkFeatureMask} }; -const LETag ArabicShaping::tagArray[] = +const FeatureMap *ArabicShaping::getFeatureMap(le_int32 &count) { - isolFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag, - caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag, - - finaFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag, - caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag, - - initFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag, - caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag, - - mediFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag, - caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag, - - fin2FeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag, - caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag, - - fin3FeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag, - caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag, + count = LE_ARRAY_SIZE(featureMap); - med2FeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag, - caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag, - - med2FeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag, - caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag - // this entry repeated so that both fin2 and fin3 map to med2 via a +2 offset -}; - -#define TAGS_PER_GLYPH ((sizeof ArabicShaping::tagArray / sizeof ArabicShaping::tagArray[0]) / 8) - -const LETag *ArabicShaping::getFeatureOrder() -{ - return featureOrder; + return featureMap; } void ArabicShaping::adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage) { LEErrorCode success = LE_NO_ERROR; - const LETag *glyphTags = (const LETag *) glyphStorage.getAuxData(outIndex, success); + FeatureMask featureMask = (FeatureMask) glyphStorage.getAuxData(outIndex, success); + FeatureMask shape = featureMask & SHAPE_MASK; + + shape >>= shapeOffset; - glyphStorage.setAuxData(outIndex, (void *) &glyphTags[TAGS_PER_GLYPH * shapeOffset], NULL, success); + glyphStorage.setAuxData(outIndex, ((featureMask & ~SHAPE_MASK) | shape), NULL, success); } void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax, @@ -232,7 +228,7 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char LEUnicode c = chars[in]; ShapeType t = getShapeType(c); - glyphStorage.setAuxData(out, (void *) tagArray, NULL, success); + glyphStorage.setAuxData(out, ISOL_FEATURES, NULL, success); if ((t & MASK_TRANSPARENT) != 0) { continue; diff --git a/Build/source/libs/icu-xetex/layout/ArabicShaping.h b/Build/source/libs/icu-xetex/layout/ArabicShaping.h index ed1a47a4ab5..937d619a643 100644 --- a/Build/source/libs/icu-xetex/layout/ArabicShaping.h +++ b/Build/source/libs/icu-xetex/layout/ArabicShaping.h @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -21,13 +21,25 @@ class LEGlyphStorage; class ArabicShaping /* not : public UObject because all methods are static */ { public: + // Joining types + enum JoiningTypes + { + JT_NON_JOINING = 0, + JT_JOIN_CAUSING = 1, + JT_DUAL_JOINING = 2, + JT_LEFT_JOINING = 3, + JT_RIGHT_JOINING = 4, + JT_TRANSPARENT = 5, + JT_COUNT = 6 + }; + // shaping bit masks enum ShapingBitMasks { MASK_SHAPE_RIGHT = 1, // if this bit set, shapes to right MASK_SHAPE_LEFT = 2, // if this bit set, shapes to left MASK_TRANSPARENT = 4, // if this bit set, is transparent (ignore other bits) - MASK_NOSHAPE = 8, // if this bit set, don't shape this char, i.e. tatweel + MASK_NOSHAPE = 8, // if this bit set, don't shape this char, i.e. tatweel MASK_ALAPH = 16, // if this bit set, char is Syriac ALAPH MASK_DALATH_RISH = 32 // if this bit set, char is Syriac DALATH/RISH @@ -52,16 +64,15 @@ public: static void shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax, le_bool rightToLeft, LEGlyphStorage &glyphStorage); - static const LETag *getFeatureOrder(); + static const FeatureMap *getFeatureMap(le_int32 &count); private: // forbid instantiation ArabicShaping(); - static const LETag tagArray[]; - static ShapeType getShapeType(LEUnicode c); + static const le_uint8 shapingTypeTable[]; static const ShapeType shapeTypes[]; static const ShapeType mongolianTypes[]; diff --git a/Build/source/libs/icu-xetex/layout/CanonShaping.h b/Build/source/libs/icu-xetex/layout/CanonShaping.h index b875389c254..cdf19595b59 100644 --- a/Build/source/libs/icu-xetex/layout/CanonShaping.h +++ b/Build/source/libs/icu-xetex/layout/CanonShaping.h @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved * */ @@ -13,7 +13,7 @@ U_NAMESPACE_BEGIN class LEGlyphStorage; -class CanonShaping /* not : public UObject because all members are static */ +class U_LAYOUT_API CanonShaping /* not : public UObject because all members are static */ { public: static const le_uint8 glyphSubstitutionTable[]; diff --git a/Build/source/libs/icu-xetex/layout/ContextualSubstSubtables.cpp b/Build/source/libs/icu-xetex/layout/ContextualSubstSubtables.cpp index a1541b9fdd3..1d8f28c8c17 100644 --- a/Build/source/libs/icu-xetex/layout/ContextualSubstSubtables.cpp +++ b/Build/source/libs/icu-xetex/layout/ContextualSubstSubtables.cpp @@ -1,6 +1,5 @@ /* - * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -325,7 +324,11 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor } } -static const LETag emptyTag = 0; +// NOTE: This could be a #define, but that seems to confuse +// the Visual Studio .NET 2003 compiler on the calls to the +// GlyphIterator constructor. It somehow can't decide if +// emptyFeatureList matches an le_uint32 or an le_uint16... +static const FeatureMask emptyFeatureList = 0x00000000UL; le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const @@ -342,7 +345,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset); le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); - GlyphIterator tempIterator(*glyphIterator, emptyTag); + GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) { Offset chainSubRuleTableOffset = @@ -414,7 +417,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro (const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset); le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); - GlyphIterator tempIterator(*glyphIterator, emptyTag); + GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) { Offset chainSubClassRuleTableOffset = @@ -476,7 +479,7 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro const Offset *lookaheadCoverageTableOffsetArray = &inputCoverageTableOffsetArray[inputGlyphCount + 1]; le_uint16 substCount = (le_uint16) SWAPW(lookaheadCoverageTableOffsetArray[lookaheadGlyphCount]); le_int32 position = glyphIterator->getCurrStreamPosition(); - GlyphIterator tempIterator(*glyphIterator, emptyTag); + GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); if (! tempIterator.prev(backtrkGlyphCount)) { return 0; diff --git a/Build/source/libs/icu-xetex/layout/DefaultCharMapper.h b/Build/source/libs/icu-xetex/layout/DefaultCharMapper.h index d2449fcba65..d9aafdcb867 100644 --- a/Build/source/libs/icu-xetex/layout/DefaultCharMapper.h +++ b/Build/source/libs/icu-xetex/layout/DefaultCharMapper.h @@ -1,7 +1,5 @@ /* - * %W% %W% - * - * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -36,6 +34,7 @@ private: static const le_int32 controlCharsCount; static const LEUnicode32 mirroredChars[]; + static const LEUnicode32 srahCderorrim[]; static const le_int32 mirroredCharsCount; diff --git a/Build/source/libs/icu-xetex/layout/GXLayoutEngine.cpp b/Build/source/libs/icu-xetex/layout/GXLayoutEngine.cpp index 3155f022d2d..84327019b50 100644 --- a/Build/source/libs/icu-xetex/layout/GXLayoutEngine.cpp +++ b/Build/source/libs/icu-xetex/layout/GXLayoutEngine.cpp @@ -39,7 +39,7 @@ le_int32 GXLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, return 0; } - mapCharsToGlyphs(chars, offset, count, FALSE, rightToLeft, glyphStorage, success); + mapCharsToGlyphs(chars, offset, count, FALSE, rightToLeft, TRUE, glyphStorage, success); if (LE_FAILURE(success)) { return 0; diff --git a/Build/source/libs/icu-xetex/layout/GlyphIterator.cpp b/Build/source/libs/icu-xetex/layout/GlyphIterator.cpp index a68233c21d6..fda7511724f 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphIterator.cpp +++ b/Build/source/libs/icu-xetex/layout/GlyphIterator.cpp @@ -15,11 +15,11 @@ U_NAMESPACE_BEGIN -GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag, - const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader) +GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, + FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader) : direction(1), position(-1), nextLimit(-1), prevLimit(-1), glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments), - srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureTag(theFeatureTag), featureParam(0), + srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), featureParam(0), glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL) { @@ -52,13 +52,13 @@ GlyphIterator::GlyphIterator(GlyphIterator &that) srcIndex = that.srcIndex; destIndex = that.destIndex; lookupFlags = that.lookupFlags; - featureTag = that.featureTag; + featureMask = that.featureMask; featureParam = that.featureParam; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; } -GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag, le_int32 newFeatureParam) +GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask, le_int32 newFeatureParam) : glyphStorage(that.glyphStorage) { direction = that.direction; @@ -70,7 +70,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag, le_int32 srcIndex = that.srcIndex; destIndex = that.destIndex; lookupFlags = that.lookupFlags; - featureTag = newFeatureTag; + featureMask = newFeatureMask; featureParam = newFeatureParam; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; @@ -88,7 +88,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags) srcIndex = that.srcIndex; destIndex = that.destIndex; lookupFlags = newLookupFlags; - featureTag = that.featureTag; + featureMask = that.featureMask; featureParam = that.featureParam; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; @@ -99,12 +99,12 @@ GlyphIterator::~GlyphIterator() // nothing to do, right? } -void GlyphIterator::reset(le_uint16 newLookupFlags, LETag newFeatureTag) +void GlyphIterator::reset(le_uint16 newLookupFlags, FeatureMask newFeatureMask) { - position = prevLimit; - featureTag = newFeatureTag; + position = prevLimit; + featureMask = newFeatureMask; featureParam = 0; - lookupFlags = newLookupFlags; + lookupFlags = newLookupFlags; } LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count) @@ -375,32 +375,30 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const } } -static const LETag emptyTag = 0; -static const LETag defaultTag = 0xFFFFFFFF; - le_bool GlyphIterator::hasFeatureTag() { - if (featureTag == defaultTag || featureTag == emptyTag) { - featureParam = 0; + featureParam = 0; + + if (featureMask == 0) { return TRUE; } LEErrorCode success = LE_NO_ERROR; - const LETag *tagList = (const LETag *) glyphStorage.getAuxData(position, success); - - if (tagList != NULL) { - for (le_int32 tag = 0; tagList[tag] != emptyTag; tag += 1) { - if (tagList[tag] == featureTag) { - const le_int32 *paramList = (const le_int32 *) glyphStorage.getAuxData2(position, success); - if (paramList != NULL) - featureParam = paramList[tag]; - else - featureParam = 0; - return TRUE; + FeatureMask fm = glyphStorage.getAuxData(position, success); + + if ((fm & featureMask) != 0) { + const le_int32 *paramList = (const le_int32 *) glyphStorage.getAuxParam(position, success); + if (paramList != NULL) { + fm = featureMask; + while ((fm & 0x80000000UL) == 0) { + ++paramList; + fm <<= 1; } + featureParam = *paramList; } + return TRUE; } - + return FALSE; } diff --git a/Build/source/libs/icu-xetex/layout/GlyphIterator.h b/Build/source/libs/icu-xetex/layout/GlyphIterator.h index 677a0fe6ecb..b03ce63c832 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphIterator.h +++ b/Build/source/libs/icu-xetex/layout/GlyphIterator.h @@ -23,12 +23,12 @@ class GlyphPositionAdjustments; class GlyphIterator : public UMemory { public: - GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag, - const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader); + GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, + FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader); GlyphIterator(GlyphIterator &that); - GlyphIterator(GlyphIterator &that, LETag newFeatureTag, le_int32 featureParam = 0); + GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask, le_int32 featureParam = 0); GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags); @@ -85,10 +85,12 @@ private: LEGlyphStorage &glyphStorage; GlyphPositionAdjustments *glyphPositionAdjustments; - le_int32 srcIndex; - le_int32 destIndex; - le_uint16 lookupFlags; - LETag featureTag; + + le_int32 srcIndex; + le_int32 destIndex; + le_uint16 lookupFlags; + FeatureMask featureMask; + le_int32 featureParam; const GlyphClassDefinitionTable *glyphClassDefinitionTable; const MarkAttachClassDefinitionTable *markAttachClassDefinitionTable; diff --git a/Build/source/libs/icu-xetex/layout/GlyphPositionAdjustments.h b/Build/source/libs/icu-xetex/layout/GlyphPositionAdjustments.h index 39cfd6e3811..31146e56f9b 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphPositionAdjustments.h +++ b/Build/source/libs/icu-xetex/layout/GlyphPositionAdjustments.h @@ -223,7 +223,7 @@ inline void GlyphPositionAdjustments::Adjustment::adjustYAdvance(float yAdjustme inline GlyphPositionAdjustments::EntryExitPoint::EntryExitPoint() : fFlags(0) { - fEntryPoint.fX = fEntryPoint.fY = fExitPoint.fX = fEntryPoint.fY = 0; + fEntryPoint.fX = fEntryPoint.fY = fExitPoint.fX = fExitPoint.fY = 0; } inline GlyphPositionAdjustments::EntryExitPoint::~EntryExitPoint() diff --git a/Build/source/libs/icu-xetex/layout/GlyphPositioningTables.cpp b/Build/source/libs/icu-xetex/layout/GlyphPositioningTables.cpp index 42b7726dbd9..b9187b4a295 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphPositioningTables.cpp +++ b/Build/source/libs/icu-xetex/layout/GlyphPositioningTables.cpp @@ -1,5 +1,4 @@ /* - * * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -20,9 +19,9 @@ U_NAMESPACE_BEGIN void GlyphPositioningTableHeader::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft, LETag scriptTag, LETag languageTag, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, - const LEFontInstance *fontInstance, const LETag *featureOrder) const + const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const { - GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureOrder); + GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder); processor.process(glyphStorage, glyphPositionAdjustments, rightToLeft, glyphDefinitionTableHeader, fontInstance); diff --git a/Build/source/libs/icu-xetex/layout/GlyphPositioningTables.h b/Build/source/libs/icu-xetex/layout/GlyphPositioningTables.h index c8b6487a754..a07c8c26716 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphPositioningTables.h +++ b/Build/source/libs/icu-xetex/layout/GlyphPositioningTables.h @@ -1,5 +1,4 @@ /* - * * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -30,7 +29,7 @@ struct GlyphPositioningTableHeader : public GlyphLookupTableHeader void process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft, LETag scriptTag, LETag languageTag, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, - const LEFontInstance *fontInstance, const LETag *featureOrder) const; + const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const; }; enum GlyphPositioningSubtableTypes diff --git a/Build/source/libs/icu-xetex/layout/GlyphPosnLookupProc.cpp b/Build/source/libs/icu-xetex/layout/GlyphPosnLookupProc.cpp index 71dafed8bd2..6f923a1389c 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphPosnLookupProc.cpp +++ b/Build/source/libs/icu-xetex/layout/GlyphPosnLookupProc.cpp @@ -1,6 +1,5 @@ /* - * - * (C) Copyright IBM Corp. 1998 - 2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998 - 2005 - All Rights Reserved * */ @@ -34,13 +33,13 @@ typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubt GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor( const GlyphPositioningTableHeader *glyphPositioningTableHeader, - LETag scriptTag, LETag languageTag, const LETag *featureOrder) + LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) : LookupProcessor( (char *) glyphPositioningTableHeader, SWAPW(glyphPositioningTableHeader->scriptListOffset), SWAPW(glyphPositioningTableHeader->featureListOffset), SWAPW(glyphPositioningTableHeader->lookupListOffset), - scriptTag, languageTag, featureOrder) + scriptTag, languageTag, featureMap, featureMapCount, featureOrder) { // anything? } diff --git a/Build/source/libs/icu-xetex/layout/GlyphPosnLookupProc.h b/Build/source/libs/icu-xetex/layout/GlyphPosnLookupProc.h index 08ca7e829d4..ee3606565d3 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphPosnLookupProc.h +++ b/Build/source/libs/icu-xetex/layout/GlyphPosnLookupProc.h @@ -1,6 +1,5 @@ /* - * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -28,7 +27,7 @@ class GlyphPositioningLookupProcessor : public LookupProcessor { public: GlyphPositioningLookupProcessor(const GlyphPositioningTableHeader *glyphPositioningTableHeader, - LETag scriptTag, LETag languageTag, const LETag *featureOrder); + LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder); virtual ~GlyphPositioningLookupProcessor(); diff --git a/Build/source/libs/icu-xetex/layout/GlyphSubstLookupProc.cpp b/Build/source/libs/icu-xetex/layout/GlyphSubstLookupProc.cpp index a033badf3c6..eb25680cce1 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphSubstLookupProc.cpp +++ b/Build/source/libs/icu-xetex/layout/GlyphSubstLookupProc.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -27,13 +27,13 @@ U_NAMESPACE_BEGIN GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor( const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader, - LETag scriptTag, LETag languageTag, const LEGlyphFilter *filter, const LETag *featureOrder) + LETag scriptTag, LETag languageTag, const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) : LookupProcessor( (char *) glyphSubstitutionTableHeader, SWAPW(glyphSubstitutionTableHeader->scriptListOffset), SWAPW(glyphSubstitutionTableHeader->featureListOffset), SWAPW(glyphSubstitutionTableHeader->lookupListOffset), - scriptTag, languageTag, featureOrder), fFilter(filter) + scriptTag, languageTag, featureMap, featureMapCount, featureOrder), fFilter(filter) { // anything? } diff --git a/Build/source/libs/icu-xetex/layout/GlyphSubstLookupProc.h b/Build/source/libs/icu-xetex/layout/GlyphSubstLookupProc.h index 4471b63ae0e..d8c5684a03b 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphSubstLookupProc.h +++ b/Build/source/libs/icu-xetex/layout/GlyphSubstLookupProc.h @@ -1,7 +1,5 @@ /* - * %W% %E% - * - * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -30,7 +28,7 @@ class GlyphSubstitutionLookupProcessor : public LookupProcessor { public: GlyphSubstitutionLookupProcessor(const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader, - LETag scriptTag, LETag languageTag, const LEGlyphFilter *filter = NULL, const LETag *featureOrder = NULL); + LETag scriptTag, LETag languageTag, const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder); virtual ~GlyphSubstitutionLookupProcessor(); diff --git a/Build/source/libs/icu-xetex/layout/GlyphSubstitutionTables.cpp b/Build/source/libs/icu-xetex/layout/GlyphSubstitutionTables.cpp index 8efdfe8faf5..661b30f3ab5 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphSubstitutionTables.cpp +++ b/Build/source/libs/icu-xetex/layout/GlyphSubstitutionTables.cpp @@ -19,9 +19,9 @@ U_NAMESPACE_BEGIN le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, - const LEGlyphFilter *filter, const LETag *featureOrder) const + const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const { - GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureOrder); + GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder); return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL); } diff --git a/Build/source/libs/icu-xetex/layout/GlyphSubstitutionTables.h b/Build/source/libs/icu-xetex/layout/GlyphSubstitutionTables.h index 2bc21edd78e..620da29c932 100644 --- a/Build/source/libs/icu-xetex/layout/GlyphSubstitutionTables.h +++ b/Build/source/libs/icu-xetex/layout/GlyphSubstitutionTables.h @@ -26,8 +26,8 @@ struct GlyphDefinitionTableHeader; struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader { le_int32 process(LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag, - const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, - const LEGlyphFilter *filter = NULL, const LETag *featureOrder = NULL) const; + const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEGlyphFilter *filter, + const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const; }; enum GlyphSubstitutionSubtableTypes diff --git a/Build/source/libs/icu-xetex/layout/HanLayoutEngine.cpp b/Build/source/libs/icu-xetex/layout/HanLayoutEngine.cpp index 0344f35450a..ae0d9dc7d4d 100644 --- a/Build/source/libs/icu-xetex/layout/HanLayoutEngine.cpp +++ b/Build/source/libs/icu-xetex/layout/HanLayoutEngine.cpp @@ -13,16 +13,37 @@ #include "HanLayoutEngine.h" #include "ScriptAndLanguageTags.h" #include "LEGlyphStorage.h" +#include "OpenTypeTables.h" U_NAMESPACE_BEGIN UOBJECT_DEFINE_RTTI_IMPLEMENTATION(HanOpenTypeLayoutEngine) +#define loclFeatureTag LE_LOCL_FEATURE_TAG +#define smplFeatureTag LE_SMPL_FEATURE_TAG +#define tradFeatureTag LE_TRAD_FEATURE_TAG + +#define loclFeatureMask 0x80000000UL +#define smplFeatureMask 0x40000000UL +#define tradFeatureMask 0x20000000UL + +static const FeatureMap featureMap[] = +{ + {loclFeatureTag, loclFeatureMask}, + {smplFeatureTag, smplFeatureMask}, + {tradFeatureTag, tradFeatureMask} +}; + +static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap); + +#define features (loclFeatureMask) + HanOpenTypeLayoutEngine::HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable) { - // nothing else to do... + fFeatureMap = featureMap; + fFeatureMapCount = featureMapCount; } HanOpenTypeLayoutEngine::~HanOpenTypeLayoutEngine() @@ -30,14 +51,6 @@ HanOpenTypeLayoutEngine::~HanOpenTypeLayoutEngine() // nothing to do } -static const LETag emptyTag = 0x00000000; - -static const LETag loclFeatureTag = LE_LOCL_FEATURE_TAG; -static const LETag smplFeatureTag = LE_SMPL_FEATURE_TAG; -static const LETag tradFeatureTag = LE_TRAD_FEATURE_TAG; - -static const LETag features[] = {loclFeatureTag, emptyTag}; - le_int32 HanOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool /*rightToLeft*/, LEUnicode *&/*outChars*/, LEGlyphStorage &glyphStorage, LEErrorCode &success) { @@ -62,7 +75,7 @@ le_int32 HanOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], l // flag from the language tag lookups, so we can use these features // with the default LangSys... for (le_int32 i = 0; i < count; i += 1) { - glyphStorage.setAuxData(i, (void *) features, NULL, success); + glyphStorage.setAuxData(i, features, NULL, success); } return count; diff --git a/Build/source/libs/icu-xetex/layout/HangulLayoutEngine.cpp b/Build/source/libs/icu-xetex/layout/HangulLayoutEngine.cpp new file mode 100644 index 00000000000..0782b85c7e8 --- /dev/null +++ b/Build/source/libs/icu-xetex/layout/HangulLayoutEngine.cpp @@ -0,0 +1,338 @@ +/* + * HangulLayoutEngine.cpp: OpenType processing for Han fonts. + * + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved. + */ + +#include "LETypes.h" +#include "LEScripts.h" +#include "LELanguages.h" + +#include "LayoutEngine.h" +#include "OpenTypeLayoutEngine.h" +#include "HangulLayoutEngine.h" +#include "ScriptAndLanguageTags.h" +#include "LEGlyphStorage.h" +#include "OpenTypeTables.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(HangulOpenTypeLayoutEngine) + + +#define FEATURE_MAP(name) {name ## FeatureTag, name ## FeatureMask} + +#define LJMO_FIRST 0x1100 +#define LJMO_LAST 0x1159 +#define LJMO_FILL 0x115F +#define LJMO_COUNT 19 + +#define VJMO_FIRST 0x1161 +#define VJMO_LAST 0x11A2 +#define VJMO_FILL 0x1160 +#define VJMO_COUNT 21 + +#define TJMO_FIRST 0x11A7 +#define TJMO_LAST 0x11F9 +#define TJMO_COUNT 28 + +#define HSYL_FIRST 0xAC00 +#define HSYL_COUNT 11172 +#define HSYL_LVCNT (VJMO_COUNT * TJMO_COUNT) + +// Character classes +enum +{ + CC_L = 0, + CC_V, + CC_T, + CC_LV, + CC_LVT, + CC_X, + CC_COUNT +}; + +// Action flags +#define AF_L 1 +#define AF_V 2 +#define AF_T 4 + +// Actions +#define a_N 0 +#define a_L (AF_L) +#define a_V (AF_V) +#define a_T (AF_T) +#define a_VT (AF_V | AF_T) +#define a_LV (AF_L | AF_V) +#define a_LVT (AF_L | AF_V | AF_T) + +typedef struct +{ + int32_t newState; + int32_t actionFlags; +} StateTransition; + +static const StateTransition stateTable[][CC_COUNT] = +{ +// L V T LV LVT X + { {1, a_L}, {2, a_LV}, {3, a_LVT}, {2, a_LV}, {3, a_LVT}, {4, a_T}}, // 0 - start + { {1, a_L}, {2, a_V}, {3, a_VT}, {2, a_LV}, {3, a_LVT}, {-1, a_V}}, // 1 - L+ + {{-1, a_N}, {2, a_V}, {3, a_T}, {-1, a_N}, {-1, a_N}, {-1, a_N}}, // 2 - L+V+ + {{-1, a_N}, {-1, a_N}, {3, a_T}, {-1, a_N}, {-1, a_N}, {-1, a_N}}, // 3 - L+V+T* + {{-1, a_N}, {-1, a_N}, {-1, a_N}, {-1, a_N}, {-1, a_N}, {4, a_T}} // 4 - X+ +}; + + +#define ccmpFeatureTag LE_CCMP_FEATURE_TAG +#define ljmoFeatureTag LE_LJMO_FEATURE_TAG +#define vjmoFeatureTag LE_VJMO_FEATURE_TAG +#define tjmoFeatureTag LE_TJMO_FEATURE_TAG + +#define ccmpFeatureMask 0x80000000UL +#define ljmoFeatureMask 0x40000000UL +#define vjmoFeatureMask 0x20000000UL +#define tjmoFeatureMask 0x10000000UL + +static const FeatureMap featureMap[] = +{ + {ccmpFeatureTag, ccmpFeatureMask}, + {ljmoFeatureTag, ljmoFeatureMask}, + {vjmoFeatureTag, vjmoFeatureMask}, + {tjmoFeatureTag, tjmoFeatureMask} +}; + +static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap); + +#define nullFeatures 0 +#define ljmoFeatures (ccmpFeatureMask | ljmoFeatureMask) +#define vjmoFeatures (ccmpFeatureMask | vjmoFeatureMask | ljmoFeatureMask | tjmoFeatureMask) +#define tjmoFeatures (ccmpFeatureMask | tjmoFeatureMask | ljmoFeatureMask | vjmoFeatureMask) + +static le_int32 compose(LEUnicode lead, LEUnicode vowel, LEUnicode trail, LEUnicode &syllable) +{ + le_int32 lIndex = lead - LJMO_FIRST; + le_int32 vIndex = vowel - VJMO_FIRST; + le_int32 tIndex = trail - TJMO_FIRST; + le_int32 result = 3; + + if ((lIndex < 0 || lIndex >= LJMO_COUNT ) || (vIndex < 0 || vIndex >= VJMO_COUNT)) { + return 0; + } + + if (tIndex <= 0 || tIndex >= TJMO_COUNT) { + tIndex = 0; + result = 2; + } + + syllable = (LEUnicode) ((lIndex * VJMO_COUNT + vIndex) * TJMO_COUNT + tIndex + HSYL_FIRST); + + return result; +} + +static le_int32 decompose(LEUnicode syllable, LEUnicode &lead, LEUnicode &vowel, LEUnicode &trail) +{ + le_int32 sIndex = syllable - HSYL_FIRST; + + if (sIndex < 0 || sIndex >= HSYL_COUNT) { + return 0; + } + + lead = LJMO_FIRST + (sIndex / HSYL_LVCNT); + vowel = VJMO_FIRST + (sIndex % HSYL_LVCNT) / TJMO_COUNT; + trail = TJMO_FIRST + (sIndex % TJMO_COUNT); + + if (trail == TJMO_FIRST) { + return 2; + } + + return 3; +} + +static le_int32 getCharClass(LEUnicode ch, LEUnicode &lead, LEUnicode &vowel, LEUnicode &trail) +{ + lead = LJMO_FILL; + vowel = VJMO_FILL; + trail = TJMO_FIRST; + + if (ch >= LJMO_FIRST && ch <= LJMO_LAST) { + lead = ch; + return CC_L; + } + + if (ch >= VJMO_FIRST && ch <= VJMO_LAST) { + vowel = ch; + return CC_V; + } + + if (ch > TJMO_FIRST && ch <= TJMO_LAST) { + trail = ch; + return CC_T; + } + + le_int32 c = decompose(ch, lead, vowel, trail); + + if (c == 2) { + return CC_LV; + } + + if (c == 3) { + return CC_LVT; + } + + trail = ch; + return CC_X; +} + +HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/, + le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) + : OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, gsubTable) +{ + fFeatureMap = featureMap; + fFeatureMapCount = featureMapCount; + fFeatureOrder = TRUE; +} + +HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/, + le_int32 typoFlags) + : OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags) +{ + fFeatureMap = featureMap; + fFeatureMapCount = featureMapCount; + fFeatureOrder = TRUE; +} + +HangulOpenTypeLayoutEngine::~HangulOpenTypeLayoutEngine() +{ + // nothing to do +} + +le_int32 HangulOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, + LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success) +{ + if (LE_FAILURE(success)) { + return 0; + } + + if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { + success = LE_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + le_int32 worstCase = count * 3; + + outChars = LE_NEW_ARRAY(LEUnicode, worstCase); + + if (outChars == NULL) { + success = LE_MEMORY_ALLOCATION_ERROR; + return 0; + } + + glyphStorage.allocateGlyphArray(worstCase, rightToLeft, success); + glyphStorage.allocateAuxData(success); + + if (LE_FAILURE(success)) { + LE_DELETE_ARRAY(outChars); + return 0; + } + + le_int32 outCharCount = 0; + le_int32 limit = offset + count; + le_int32 i = offset; + + while (i < limit) { + le_int32 state = 0; + le_int32 inStart = i; + le_int32 outStart = outCharCount; + + while( i < limit) { + LEUnicode lead = 0; + LEUnicode vowel = 0; + LEUnicode trail = 0; + int32_t chClass = getCharClass(chars[i], lead, vowel, trail); + const StateTransition transition = stateTable[state][chClass]; + + if (chClass == CC_X) { + /* Any character of type X will be stored as a trail jamo */ + if ((transition.actionFlags & AF_T) != 0) { + outChars[outCharCount] = trail; + glyphStorage.setCharIndex(outCharCount, i-offset, success); + glyphStorage.setAuxData(outCharCount++, nullFeatures, NULL, success); + } + } else { + /* Any Hangul will be fully decomposed. Output the decomposed characters. */ + if ((transition.actionFlags & AF_L) != 0) { + outChars[outCharCount] = lead; + glyphStorage.setCharIndex(outCharCount, i-offset, success); + glyphStorage.setAuxData(outCharCount++, ljmoFeatures, NULL, success); + } + + if ((transition.actionFlags & AF_V) != 0) { + outChars[outCharCount] = vowel; + glyphStorage.setCharIndex(outCharCount, i-offset, success); + glyphStorage.setAuxData(outCharCount++, vjmoFeatures, NULL, success); + } + + if ((transition.actionFlags & AF_T) != 0) { + outChars[outCharCount] = trail; + glyphStorage.setCharIndex(outCharCount, i-offset, success); + glyphStorage.setAuxData(outCharCount++, tjmoFeatures, NULL, success); + } + } + + state = transition.newState; + + /* Negative next state means stop. */ + if (state < 0) { + break; + } + + i += 1; + } + + le_int32 inLength = i - inStart; + le_int32 outLength = outCharCount - outStart; + + /* + * See if the syllable can be composed into a single character. There are 5 + * possible cases: + * + * Input Decomposed to Compose to + * LV L, V LV + * LVT L, V, T LVT + * L, V L, V LV, DEL + * LV, T L, V, T LVT, DEL + * L, V, T L, V, T LVT, DEL, DEL + */ + if ((inLength >= 1 && inLength <= 3) && (outLength == 2 || outLength == 3)) { + LEUnicode syllable = 0x0000; + LEUnicode lead = outChars[outStart]; + LEUnicode vowel = outChars[outStart + 1]; + LEUnicode trail = outLength == 3? outChars[outStart + 2] : TJMO_FIRST; + + /* + * If the composition consumes the whole decomposed syllable, + * we can use it. + */ + if (compose(lead, vowel, trail, syllable) == outLength) { + outCharCount = outStart; + outChars[outCharCount] = syllable; + glyphStorage.setCharIndex(outCharCount, inStart-offset, success); + glyphStorage.setAuxData(outCharCount++, nullFeatures, NULL, success); + + /* + * Replace the rest of the input characters with DEL. + */ + for(le_int32 d = inStart + 1; d < i; d += 1) { + outChars[outCharCount] = 0xFFFF; + glyphStorage.setCharIndex(outCharCount, d - offset, success); + glyphStorage.setAuxData(outCharCount++, nullFeatures, NULL, success); + } + } + } + } + + glyphStorage.adoptGlyphCount(outCharCount); + return outCharCount; +} + +U_NAMESPACE_END diff --git a/Build/source/libs/icu-xetex/layout/HangulLayoutEngine.h b/Build/source/libs/icu-xetex/layout/HangulLayoutEngine.h new file mode 100644 index 00000000000..e77c3b97644 --- /dev/null +++ b/Build/source/libs/icu-xetex/layout/HangulLayoutEngine.h @@ -0,0 +1,125 @@ + +/* + * + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved + * + */ + +#ifndef __HANGULAYOUTENGINE_H +#define __HANGULAYOUTENGINE_H + +#include "LETypes.h" +#include "LEFontInstance.h" +#include "LEGlyphFilter.h" +#include "LayoutEngine.h" +#include "OpenTypeLayoutEngine.h" + +#include "GlyphSubstitutionTables.h" +#include "GlyphDefinitionTables.h" +#include "GlyphPositioningTables.h" + +U_NAMESPACE_BEGIN + +class MPreFixups; +class LEGlyphStorage; + +/** + * This class implements OpenType layout for Old Hangul OpenType fonts, as + * specified by Microsoft in "Creating and Supporting OpenType Fonts for + * The Korean Hangul Script" (http://www.microsoft.com/typography/otfntdev/hangulot/default.htm) + * + * This class overrides the characterProcessing method to do Hangul character processing. + * (See the MS spec. for more details) + * + * @internal + */ +class HangulOpenTypeLayoutEngine : public OpenTypeLayoutEngine +{ +public: + /** + * This is the main constructor. It constructs an instance of HangulOpenTypeLayoutEngine for + * a particular font, script and language. It takes the GSUB table as a parameter since + * LayoutEngine::layoutEngineFactory has to read the GSUB table to know that it has an + * Hangul OpenType font. + * + * @param fontInstance - the font + * @param scriptCode - the script + * @param langaugeCode - the language + * @param gsubTable - the GSUB table + * + * @see LayoutEngine::layoutEngineFactory + * @see OpenTypeLayoutEngine + * @see ScriptAndLangaugeTags.h for script and language codes + * + * @internal + */ + HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, + le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable); + + /** + * This constructor is used when the font requires a "canned" GSUB table which can't be known + * until after this constructor has been invoked. + * + * @param fontInstance - the font + * @param scriptCode - the script + * @param langaugeCode - the language + * + * @see OpenTypeLayoutEngine + * @see ScriptAndLangaugeTags.h for script and language codes + * + * @internal + */ + HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, + le_int32 typoFlags); + + /** + * The destructor, virtual for correct polymorphic invocation. + * + * @internal + */ + virtual ~HangulOpenTypeLayoutEngine(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +protected: + + /** + * This method does Hangul OpenType character processing. It assigns the OpenType feature + * tags to the characters, and may compose a character sequence into a modern Hangul syllable, + * or decompose a modern Hangul syllable if it forms part of an old Hangul syllable. + * + * Input parameters: + * @param chars - the input character context + * @param offset - the index of the first character to process + * @param count - the number of characters to process + * @param max - the number of characters in the input context + * @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run + * @param glyphStorage - the glyph storage object. The glyph and character index arrays will be set. + * the auxillary data array will be set to the feature tags. + * + * Output parameters: + * @param success - set to an error code if the operation fails + * + * @return the output character count + * + * @internal + */ + virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, + LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success); +}; + +U_NAMESPACE_END +#endif + diff --git a/Build/source/libs/icu-xetex/layout/IndicClassTables.cpp b/Build/source/libs/icu-xetex/layout/IndicClassTables.cpp index 75cc583544d..a190afa7591 100644 --- a/Build/source/libs/icu-xetex/layout/IndicClassTables.cpp +++ b/Build/source/libs/icu-xetex/layout/IndicClassTables.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved * */ @@ -12,8 +12,6 @@ U_NAMESPACE_BEGIN -#define ARRAY_SIZE(array) (sizeof array / sizeof array[0]) - // Split matra table indices #define _x1 (1 << CF_INDEX_SHIFT) #define _x2 (2 << CF_INDEX_SHIFT) @@ -33,6 +31,7 @@ U_NAMESPACE_BEGIN #define _sb (CC_STRESS_MARK | CF_POS_BELOW) #define _iv (CC_INDEPENDENT_VOWEL) #define _i2 (CC_INDEPENDENT_VOWEL_2) +#define _i3 (CC_INDEPENDENT_VOWEL_3) #define _ct (CC_CONSONANT | CF_CONSONANT) #define _cn (CC_CONSONANT_WITH_NUKTA | CF_CONSONANT) #define _nu (CC_NUKTA) @@ -44,6 +43,7 @@ U_NAMESPACE_BEGIN #define _lm (_dv | CF_LENGTH_MARK) #define _l1 (CC_SPLIT_VOWEL_PIECE_1 | CF_POS_BEFORE) #define _a1 (CC_SPLIT_VOWEL_PIECE_1 | CF_POS_ABOVE) +#define _b2 (CC_SPLIT_VOWEL_PIECE_2 | CF_POS_BELOW) #define _r2 (CC_SPLIT_VOWEL_PIECE_2 | CF_POS_AFTER) #define _m2 (CC_SPLIT_VOWEL_PIECE_2 | CF_LENGTH_MARK) #define _m3 (CC_SPLIT_VOWEL_PIECE_3 | CF_LENGTH_MARK) @@ -100,13 +100,13 @@ static const IndicClassTable::CharClass bengCharClasses[] = static const IndicClassTable::CharClass punjCharClasses[] = { _xx, _ma, _ma, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _xx, _iv, // 0A00 - 0A0F - _iv, _xx, _xx, _iv, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0A10 - 0A1F + _iv, _xx, _xx, _i3, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0A10 - 0A1F _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _bb, // 0A20 - 0A2F _vt, _xx, _ct, _cn, _xx, _bb, _cn, _xx, _ct, _bb, _xx, _xx, _nu, _xx, _dr, _dl, // 0A30 - 0A3F - _dr, _db, _db, _xx, _xx, _xx, _xx, _da, _da, _xx, _xx, _da, _da, _vr, _xx, _xx, // 0A40 - 0A4F + _dr, _b2, _db, _xx, _xx, _xx, _xx, _da, _da, _xx, _xx, _a1, _da, _vr, _xx, _xx, // 0A40 - 0A4F _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _cn, _cn, _cn, _ct, _xx, _cn, _xx, // 0A50 - 0A5F _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0A60 - 0A6F - _ma, _ma, _ct, _ct, _xx // 0A70 - 0A74 + _ma, _ma, _xx, _xx, _xx // 0A70 - 0A74 }; static const IndicClassTable::CharClass gujrCharClasses[] = @@ -134,7 +134,7 @@ static const IndicClassTable::CharClass oryaCharClasses[] = static const IndicClassTable::CharClass tamlCharClasses[] = { - _xx, _xx, _ma, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _iv, _iv, // 0B80 - 0B8F + _xx, _xx, _ma, _xx, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _iv, _iv, // 0B80 - 0B8F _iv, _xx, _iv, _iv, _iv, _ct, _xx, _xx, _xx, _ct, _ct, _xx, _ct, _xx, _ct, _ct, // 0B90 - 0B9F _xx, _xx, _xx, _ct, _ct, _xx, _xx, _xx, _ct, _ct, _ct, _xx, _xx, _xx, _ct, _ct, // 0BA0 - 0BAF _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _ct, _ct, _xx, _xx, _xx, _xx, _r2, _dr, // 0BB0 - 0BBF @@ -185,6 +185,18 @@ static const IndicClassTable::CharClass mlymCharClasses[] = _xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0D50 - 0D5F _iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0D60 - 0D6F }; + +static const IndicClassTable::CharClass sinhCharClasses[] = +{ + _xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, // 0D80 - 0D8F + _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _ct, _ct, _ct, _ct, _ct, _ct, // 0D90 - 0D9F + _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0DA0 - 0DAF + _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _xx, _xx, // 0DB0 - 0DBF + _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _vr, _xx, _xx, _xx, _xx, _dr, // 0DC0 - 0DCF + _dr, _dr, _da, _da, _db, _xx, _db, _xx, _dr, _dl, _s1, _dl, _s2, _s3, _s4, _dr, // 0DD0 - 0DDF + _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0DE0 - 0DEF + _xx, _xx, _dr, _dr, _xx // 0DF0 - 0DF4 +}; // // Split matra tables @@ -198,10 +210,13 @@ static const SplitMatra tamlSplitTable[] = {{0x0BC6, 0x0BBE}, {0x0BC7, 0x0BBE}, static const SplitMatra teluSplitTable[] = {{0x0C46, 0x0C56}}; static const SplitMatra kndaSplitTable[] = {{0x0CBF, 0x0CD5}, {0x0CC6, 0x0CD5}, {0x0CC6, 0x0CD6}, {0x0CC6, 0x0CC2}, - {0x0CC6, 0x0CC2, 0x0CD5}}; + {0x0CC6, 0x0CC2, 0x0CD5}}; static const SplitMatra mlymSplitTable[] = {{0x0D46, 0x0D3E}, {0x0D47, 0x0D3E}, {0x0D46, 0x0D57}}; + +static const SplitMatra sinhSplitTable[] = {{0x0DD9, 0x0DCA}, {0x0DD9, 0x0DCF}, {0x0DD9, 0x0DCF,0x0DCA}, + {0x0DD9, 0x0DDF}}; // // Script Flags // @@ -209,15 +224,16 @@ static const SplitMatra mlymSplitTable[] = {{0x0D46, 0x0D3E}, {0x0D47, 0x0D3E}, // FIXME: post 'GSUB' reordering of MATRA_PRE's for Malayalam and Tamil // FIXME: reformed Malayalam needs to reorder VATTU to before base glyph... // FIXME: eyelash RA only for Devanagari?? -#define DEVA_SCRIPT_FLAGS (SF_EYELASH_RA | SF_NO_POST_BASE_LIMIT) -#define BENG_SCRIPT_FLAGS (SF_REPH_AFTER_BELOW | SF_NO_POST_BASE_LIMIT) -#define PUNJ_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT) -#define GUJR_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT) -#define ORYA_SCRIPT_FLAGS (SF_REPH_AFTER_BELOW | SF_NO_POST_BASE_LIMIT) -#define TAML_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT) -#define TELU_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | 3) -#define KNDA_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | 3) -#define MLYM_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT) +#define DEVA_SCRIPT_FLAGS (SF_EYELASH_RA | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH) +#define BENG_SCRIPT_FLAGS (SF_REPH_AFTER_BELOW | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH) +#define PUNJ_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH) +#define GUJR_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH) +#define ORYA_SCRIPT_FLAGS (SF_REPH_AFTER_BELOW | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH) +#define TAML_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH) +#define TELU_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | SF_FILTER_ZERO_WIDTH | 3) +#define KNDA_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | SF_FILTER_ZERO_WIDTH | 3) +#define MLYM_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH) +#define SINH_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT) // // Indic Class Tables @@ -240,10 +256,12 @@ static const IndicClassTable kndaClassTable = {0x0C80, 0x0CEF, 4, KNDA_SCRIPT_FL static const IndicClassTable mlymClassTable = {0x0D00, 0x0D6F, 3, MLYM_SCRIPT_FLAGS, mlymCharClasses, mlymSplitTable}; +static const IndicClassTable sinhClassTable = {0x0D80, 0x0DF4, 3, SINH_SCRIPT_FLAGS, sinhCharClasses, sinhSplitTable}; + // // IndicClassTable addresses // -static const IndicClassTable * const indicClassTables[] = { +static const IndicClassTable * const indicClassTables[scriptCodeCount] = { NULL, /* 'zyyy' (COMMON) */ NULL, /* 'qaai' (INHERITED) */ NULL, /* 'arab' (ARABIC) */ @@ -251,7 +269,7 @@ static const IndicClassTable * const indicClassTables[] = { &bengClassTable, /* 'beng' (BENGALI) */ NULL, /* 'bopo' (BOPOMOFO) */ NULL, /* 'cher' (CHEROKEE) */ - NULL, /* 'qaac' (COPTIC) */ + NULL, /* 'copt' (COPTIC) */ NULL, /* 'cyrl' (CYRILLIC) */ NULL, /* 'dsrt' (DESERET) */ &devaClassTable, /* 'deva' (DEVANAGARI) */ @@ -277,7 +295,7 @@ static const IndicClassTable * const indicClassTables[] = { NULL, /* 'ital' (OLD-ITALIC) */ &oryaClassTable, /* 'orya' (ORIYA) */ NULL, /* 'runr' (RUNIC) */ - NULL, /* 'sinh' (SINHALA) */ + &sinhClassTable, /* 'sinh' (SINHALA) */ NULL, /* 'syrc' (SYRIAC) */ &tamlClassTable, /* 'taml' (TAMIL) */ &teluClassTable, /* 'telu' (TELUGU) */ @@ -298,7 +316,56 @@ static const IndicClassTable * const indicClassTables[] = { NULL, /* 'shaw' (SHAVIAN) */ NULL, /* 'tale' (TAI_LE) */ NULL, /* 'ugar' (UGARITIC) */ - NULL /* 'hrkt' (KATAKANA_OR_HIRAGANA) */ + NULL, /* 'hrkt' (KATAKANA_OR_HIRAGANA) */ + NULL, /* 'bugi' (BUGINESE) */ + NULL, /* 'glag' (GLAGOLITIC) */ + NULL, /* 'khar' (KHAROSHTHI) */ + NULL, /* 'sylo' (SYLOTI_NAGRI) */ + NULL, /* 'talu' (NEW_TAI_LUE) */ + NULL, /* 'tfng' (TIFINAGH) */ + NULL, /* 'xpeo' (OLD_PERSIAN) */ + NULL, /* 'bali' (BALINESE) */ + NULL, /* 'batk' (BATK) */ + NULL, /* 'blis' (BLIS) */ + NULL, /* 'brah' (BRAH) */ + NULL, /* 'cham' (CHAM) */ + NULL, /* 'cirt' (CIRT) */ + NULL, /* 'cyrs' (CYRS) */ + NULL, /* 'egyd' (EGYD) */ + NULL, /* 'egyh' (EGYH) */ + NULL, /* 'egyp' (EGYP) */ + NULL, /* 'geok' (GEOK) */ + NULL, /* 'hans' (HANS) */ + NULL, /* 'hant' (HANT) */ + NULL, /* 'hmng' (HMNG) */ + NULL, /* 'hung' (HUNG) */ + NULL, /* 'inds' (INDS) */ + NULL, /* 'java' (JAVA) */ + NULL, /* 'kali' (KALI) */ + NULL, /* 'latf' (LATF) */ + NULL, /* 'latg' (LATG) */ + NULL, /* 'lepc' (LEPC) */ + NULL, /* 'lina' (LINA) */ + NULL, /* 'mand' (MAND) */ + NULL, /* 'maya' (MAYA) */ + NULL, /* 'mero' (MERO) */ + NULL, /* 'nko ' (NKO) */ + NULL, /* 'orkh' (ORKH) */ + NULL, /* 'perm' (PERM) */ + NULL, /* 'phag' (PHAGS_PA) */ + NULL, /* 'phnx' (PHOENICIAN) */ + NULL, /* 'plrd' (PLRD) */ + NULL, /* 'roro' (RORO) */ + NULL, /* 'sara' (SARA) */ + NULL, /* 'syre' (SYRE) */ + NULL, /* 'syrj' (SYRJ) */ + NULL, /* 'syrn' (SYRN) */ + NULL, /* 'teng' (TENG) */ + NULL, /* 'vai ' (VAII) */ + NULL, /* 'visp' (VISP) */ + NULL, /* 'xsux' (CUNEIFORM) */ + NULL, /* 'zxxx' (ZXXX) */ + NULL /* 'zzzz' (UNKNOWN) */ }; IndicClassTable::CharClass IndicClassTable::getCharClass(LEUnicode ch) const @@ -338,4 +405,15 @@ le_int32 IndicReordering::getWorstCaseExpansion(le_int32 scriptCode) return classTable->getWorstCaseExpansion(); } +le_bool IndicReordering::getFilterZeroWidth(le_int32 scriptCode) +{ + const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode); + + if (classTable == NULL) { + return TRUE; + } + + return classTable->getFilterZeroWidth(); +} + U_NAMESPACE_END diff --git a/Build/source/libs/icu-xetex/layout/IndicLayoutEngine.cpp b/Build/source/libs/icu-xetex/layout/IndicLayoutEngine.cpp index 09f564be2b6..ec83e73e462 100644 --- a/Build/source/libs/icu-xetex/layout/IndicLayoutEngine.cpp +++ b/Build/source/libs/icu-xetex/layout/IndicLayoutEngine.cpp @@ -28,13 +28,17 @@ IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontI le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable), fMPreFixups(NULL) { - fFeatureOrder = IndicReordering::getFeatureOrder(); + fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount); + fFeatureOrder = TRUE; + + fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode); } IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fMPreFixups(NULL) { - fFeatureOrder = IndicReordering::getFeatureOrder(); + fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount); + fFeatureOrder = TRUE; } IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine() diff --git a/Build/source/libs/icu-xetex/layout/IndicReordering.cpp b/Build/source/libs/icu-xetex/layout/IndicReordering.cpp index 7bae77ecb80..184afa3848a 100644 --- a/Build/source/libs/icu-xetex/layout/IndicReordering.cpp +++ b/Build/source/libs/icu-xetex/layout/IndicReordering.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved * */ @@ -13,42 +13,82 @@ U_NAMESPACE_BEGIN -class ReorderingOutput : public UMemory { +#define loclFeatureTag LE_LOCL_FEATURE_TAG +#define initFeatureTag LE_INIT_FEATURE_TAG +#define nuktFeatureTag LE_NUKT_FEATURE_TAG +#define akhnFeatureTag LE_AKHN_FEATURE_TAG +#define rphfFeatureTag LE_RPHF_FEATURE_TAG +#define blwfFeatureTag LE_BLWF_FEATURE_TAG +#define halfFeatureTag LE_HALF_FEATURE_TAG +#define pstfFeatureTag LE_PSTF_FEATURE_TAG +#define vatuFeatureTag LE_VATU_FEATURE_TAG +#define presFeatureTag LE_PRES_FEATURE_TAG +#define blwsFeatureTag LE_BLWS_FEATURE_TAG +#define abvsFeatureTag LE_ABVS_FEATURE_TAG +#define pstsFeatureTag LE_PSTS_FEATURE_TAG +#define halnFeatureTag LE_HALN_FEATURE_TAG + +#define blwmFeatureTag LE_BLWM_FEATURE_TAG +#define abvmFeatureTag LE_ABVM_FEATURE_TAG +#define distFeatureTag LE_DIST_FEATURE_TAG + +#define loclFeatureMask 0x80000000UL +#define rphfFeatureMask 0x40000000UL +#define blwfFeatureMask 0x20000000UL +#define halfFeatureMask 0x10000000UL +#define pstfFeatureMask 0x08000000UL +#define nuktFeatureMask 0x04000000UL +#define akhnFeatureMask 0x02000000UL +#define vatuFeatureMask 0x01000000UL +#define presFeatureMask 0x00800000UL +#define blwsFeatureMask 0x00400000UL +#define abvsFeatureMask 0x00200000UL +#define pstsFeatureMask 0x00100000UL +#define halnFeatureMask 0x00080000UL +#define blwmFeatureMask 0x00040000UL +#define abvmFeatureMask 0x00020000UL +#define distFeatureMask 0x00010000UL +#define initFeatureMask 0x00008000UL + +class IndicReorderingOutput : public UMemory { private: - le_int32 fOutIndex; + le_int32 fOutIndex; LEUnicode *fOutChars; LEGlyphStorage &fGlyphStorage; - LEUnicode fMpre; - le_int32 fMpreIndex; + LEUnicode fMpre; + le_int32 fMpreIndex; - LEUnicode fMbelow; - le_int32 fMbelowIndex; + LEUnicode fMbelow; + le_int32 fMbelowIndex; - LEUnicode fMabove; - le_int32 fMaboveIndex; + LEUnicode fMabove; + le_int32 fMaboveIndex; - LEUnicode fMpost; - le_int32 fMpostIndex; + LEUnicode fMpost; + le_int32 fMpostIndex; - LEUnicode fLengthMark; - le_int32 fLengthMarkIndex; + LEUnicode fLengthMark; + le_int32 fLengthMarkIndex; - const LETag *fMatraTags; + LEUnicode fVirama; + le_int32 fViramaIndex; + + FeatureMask fMatraFeatures; - le_int32 fMPreOutIndex; + le_int32 fMPreOutIndex; MPreFixups *fMPreFixups; - LEUnicode fVMabove; - LEUnicode fVMpost; - le_int32 fVMIndex; - const LETag *fVMTags; + LEUnicode fVMabove; + LEUnicode fVMpost; + le_int32 fVMIndex; + FeatureMask fVMFeatures; - LEUnicode fSMabove; - LEUnicode fSMbelow; - le_int32 fSMIndex; - const LETag *fSMTags; + LEUnicode fSMabove; + LEUnicode fSMbelow; + le_int32 fSMIndex; + FeatureMask fSMFeatures; void saveMatra(LEUnicode matra, le_int32 matraIndex, IndicClassTable::CharClass matraClass) { @@ -56,6 +96,9 @@ private: if (IndicClassTable::isLengthMark(matraClass)) { fLengthMark = matra; fLengthMarkIndex = matraIndex; + } else if (IndicClassTable::isVirama(matraClass)) { + fVirama = matra; + fViramaIndex = matraIndex; } else { switch (matraClass & CF_POS_MASK) { case CF_POS_BEFORE: @@ -86,48 +129,52 @@ private: } public: - ReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage, MPreFixups *mpreFixups) + IndicReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage, MPreFixups *mpreFixups) : fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage), fMpre(0), fMpreIndex(0), fMbelow(0), fMbelowIndex(0), fMabove(0), fMaboveIndex(0), - fMpost(0), fMpostIndex(0), fLengthMark(0), fLengthMarkIndex(0), fMatraTags(NULL), - fMPreOutIndex(-1), fMPreFixups(mpreFixups), - fVMabove(0), fVMpost(0), fVMIndex(0), fVMTags(NULL), - fSMabove(0), fSMbelow(0), fSMIndex(0), fSMTags(NULL) + fMpost(0), fMpostIndex(0), fLengthMark(0), fLengthMarkIndex(0), fVirama(0), fViramaIndex(0), + fMatraFeatures(0), fMPreOutIndex(-1), fMPreFixups(mpreFixups), + fVMabove(0), fVMpost(0), fVMIndex(0), fVMFeatures(0), + fSMabove(0), fSMbelow(0), fSMIndex(0), fSMFeatures(0) { // nothing else to do... } - ~ReorderingOutput() + ~IndicReorderingOutput() { // nothing to do here... } void reset() { - fMpre = fMbelow = fMabove = fMpost = fLengthMark = 0; + fMpre = fMbelow = fMabove = fMpost = fLengthMark = fVirama = 0; fMPreOutIndex = -1; fVMabove = fVMpost = 0; fSMabove = fSMbelow = 0; } - void writeChar(LEUnicode ch, le_uint32 charIndex, const LETag *charTags) + void writeChar(LEUnicode ch, le_uint32 charIndex, FeatureMask charFeatures) { LEErrorCode success = LE_NO_ERROR; fOutChars[fOutIndex] = ch; fGlyphStorage.setCharIndex(fOutIndex, charIndex, success); - fGlyphStorage.setAuxData(fOutIndex, (void *) charTags, NULL, success); + fGlyphStorage.setAuxData(fOutIndex, charFeatures, NULL, success); fOutIndex += 1; } - le_bool noteMatra(const IndicClassTable *classTable, LEUnicode matra, le_uint32 matraIndex, const LETag *matraTags) + le_bool noteMatra(const IndicClassTable *classTable, LEUnicode matra, le_uint32 matraIndex, FeatureMask matraFeatures, le_bool wordStart) { IndicClassTable::CharClass matraClass = classTable->getCharClass(matra); - fMatraTags = matraTags; + fMatraFeatures = matraFeatures; + + if (wordStart) { + fMatraFeatures |= initFeatureMask; + } if (IndicClassTable::isMatra(matraClass)) { if (IndicClassTable::isSplitMatra(matraClass)) { @@ -150,12 +197,12 @@ public: return FALSE; } - void noteVowelModifier(const IndicClassTable *classTable, LEUnicode vowelModifier, le_uint32 vowelModifierIndex, const LETag *vowelModifierTags) + void noteVowelModifier(const IndicClassTable *classTable, LEUnicode vowelModifier, le_uint32 vowelModifierIndex, FeatureMask vowelModifierFeatures) { IndicClassTable::CharClass vmClass = classTable->getCharClass(vowelModifier); fVMIndex = vowelModifierIndex; - fVMTags = vowelModifierTags; + fVMFeatures = vowelModifierFeatures; if (IndicClassTable::isVowelModifier(vmClass)) { switch (vmClass & CF_POS_MASK) { @@ -174,12 +221,12 @@ public: } } - void noteStressMark(const IndicClassTable *classTable, LEUnicode stressMark, le_uint32 stressMarkIndex, const LETag *stressMarkTags) + void noteStressMark(const IndicClassTable *classTable, LEUnicode stressMark, le_uint32 stressMarkIndex, FeatureMask stressMarkFeatures) { IndicClassTable::CharClass smClass = classTable->getCharClass(stressMark); fSMIndex = stressMarkIndex; - fSMTags = stressMarkTags; + fSMFeatures = stressMarkFeatures; if (IndicClassTable::isStressMark(smClass)) { switch (smClass & CF_POS_MASK) { @@ -205,67 +252,75 @@ public: } } + // Handles virama in Sinhala split vowels. + void writeVirama() + { + if (fVirama != 0) { + writeChar(fVirama, fViramaIndex, fMatraFeatures); + } + } + void writeMpre() { if (fMpre != 0) { fMPreOutIndex = fOutIndex; - writeChar(fMpre, fMpreIndex, fMatraTags); + writeChar(fMpre, fMpreIndex, fMatraFeatures); } } void writeMbelow() { if (fMbelow != 0) { - writeChar(fMbelow, fMbelowIndex, fMatraTags); + writeChar(fMbelow, fMbelowIndex, fMatraFeatures); } } void writeMabove() { if (fMabove != 0) { - writeChar(fMabove, fMaboveIndex, fMatraTags); + writeChar(fMabove, fMaboveIndex, fMatraFeatures); } } void writeMpost() { if (fMpost != 0) { - writeChar(fMpost, fMpostIndex, fMatraTags); + writeChar(fMpost, fMpostIndex, fMatraFeatures); } } void writeLengthMark() { if (fLengthMark != 0) { - writeChar(fLengthMark, fLengthMarkIndex, fMatraTags); + writeChar(fLengthMark, fLengthMarkIndex, fMatraFeatures); } } void writeVMabove() { if (fVMabove != 0) { - writeChar(fVMabove, fVMIndex, fVMTags); + writeChar(fVMabove, fVMIndex, fVMFeatures); } } void writeVMpost() { if (fVMpost != 0) { - writeChar(fVMpost, fVMIndex, fVMTags); + writeChar(fVMpost, fVMIndex, fVMFeatures); } } void writeSMabove() { if (fSMabove != 0) { - writeChar(fSMabove, fSMIndex, fSMTags); + writeChar(fSMabove, fSMIndex, fSMFeatures); } } void writeSMbelow() { if (fSMbelow != 0) { - writeChar(fSMbelow, fSMIndex, fSMTags); + writeChar(fSMbelow, fSMIndex, fSMFeatures); } } @@ -280,66 +335,60 @@ enum C_DOTTED_CIRCLE = 0x25CC }; -static const LETag emptyTag = 0x00000000; // '' - -static const LETag nuktFeatureTag = LE_NUKT_FEATURE_TAG; -static const LETag akhnFeatureTag = LE_AKHN_FEATURE_TAG; -static const LETag rphfFeatureTag = LE_RPHF_FEATURE_TAG; -static const LETag blwfFeatureTag = LE_BLWF_FEATURE_TAG; -static const LETag halfFeatureTag = LE_HALF_FEATURE_TAG; -static const LETag pstfFeatureTag = LE_PSTF_FEATURE_TAG; -static const LETag vatuFeatureTag = LE_VATU_FEATURE_TAG; -static const LETag presFeatureTag = LE_PRES_FEATURE_TAG; -static const LETag blwsFeatureTag = LE_BLWS_FEATURE_TAG; -static const LETag abvsFeatureTag = LE_ABVS_FEATURE_TAG; -static const LETag pstsFeatureTag = LE_PSTS_FEATURE_TAG; -static const LETag halnFeatureTag = LE_HALN_FEATURE_TAG; - -static const LETag blwmFeatureTag = LE_BLWM_FEATURE_TAG; -static const LETag abvmFeatureTag = LE_ABVM_FEATURE_TAG; -static const LETag distFeatureTag = LE_DIST_FEATURE_TAG; - -// These are in the order in which the features need to be applied -// for correct processing -static const LETag featureOrder[] = -{ - nuktFeatureTag, akhnFeatureTag, rphfFeatureTag, blwfFeatureTag, halfFeatureTag, pstfFeatureTag, - vatuFeatureTag, presFeatureTag, blwsFeatureTag, abvsFeatureTag, pstsFeatureTag, halnFeatureTag, - blwmFeatureTag, abvmFeatureTag, distFeatureTag, emptyTag -}; +// TODO: Find better names for these! +#define tagArray4 (loclFeatureMask | nuktFeatureMask | akhnFeatureMask | vatuFeatureMask | presFeatureMask | blwsFeatureMask | abvsFeatureMask | pstsFeatureMask | halnFeatureMask | blwmFeatureMask | abvmFeatureMask | distFeatureMask) +#define tagArray3 (pstfFeatureMask | tagArray4) +#define tagArray2 (halfFeatureMask | tagArray3) +#define tagArray1 (blwfFeatureMask | tagArray2) +#define tagArray0 (rphfFeatureMask | tagArray1) -// The order of these is determined so that the tag array of each glyph can start -// at an offset into this array -// FIXME: do we want a seperate tag array for each kind of character?? -// FIXME: are there cases where this ordering causes glyphs to get tags -// that they shouldn't? -static const LETag tagArray[] = +static const FeatureMap featureMap[] = { - rphfFeatureTag, blwfFeatureTag, halfFeatureTag, pstfFeatureTag, nuktFeatureTag, akhnFeatureTag, - vatuFeatureTag, presFeatureTag, blwsFeatureTag, abvsFeatureTag, pstsFeatureTag, halnFeatureTag, - blwmFeatureTag, abvmFeatureTag, distFeatureTag, emptyTag + {loclFeatureTag, loclFeatureMask}, + {initFeatureTag, initFeatureMask}, + {nuktFeatureTag, nuktFeatureMask}, + {akhnFeatureTag, akhnFeatureMask}, + {rphfFeatureTag, rphfFeatureMask}, + {blwfFeatureTag, blwfFeatureMask}, + {halfFeatureTag, halfFeatureMask}, + {pstfFeatureTag, pstfFeatureMask}, + {vatuFeatureTag, vatuFeatureMask}, + {presFeatureTag, presFeatureMask}, + {blwsFeatureTag, blwsFeatureMask}, + {abvsFeatureTag, abvsFeatureMask}, + {pstsFeatureTag, pstsFeatureMask}, + {halnFeatureTag, halnFeatureMask}, + {blwmFeatureTag, blwmFeatureMask}, + {abvmFeatureTag, abvmFeatureMask}, + {distFeatureTag, distFeatureMask} }; +static const le_int32 featureCount = LE_ARRAY_SIZE(featureMap); + static const le_int8 stateTable[][CC_COUNT] = { -// xx vm sm iv i2 ct cn nu dv s1 s2 s3 vr zw - { 1, 1, 1, 5, 8, 3, 2, 1, 5, 9, 5, 1, 1, 1}, // 0 - ground state - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 1 - exit state - {-1, 6, 1, -1, -1, -1, -1, -1, 5, 9, 5, 5, 4, -1}, // 2 - consonant with nukta - {-1, 6, 1, -1, -1, -1, -1, 2, 5, 9, 5, 5, 4, -1}, // 3 - consonant - {-1, -1, -1, -1, -1, 3, 2, -1, -1, -1, -1, -1, -1, 7}, // 4 - consonant virama - {-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 5 - dependent vowels - {-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - vowel mark - {-1, -1, -1, -1, -1, 3, 2, -1, -1, -1, -1, -1, -1, -1}, // 7 - ZWJ, ZWNJ - {-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1}, // 8 - independent vowels that can take a virama - {-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, 10, 5, -1, -1}, // 9 - first part of split vowel - {-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1} // 10 - second part of split vowel - +// xx vm sm iv i2 i3 ct cn nu dv s1 s2 s3 vr zw + { 1, 6, 1, 5, 8, 11, 3, 2, 1, 5, 9, 5, 5, 1, 1}, // 0 - ground state + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 1 - exit state + {-1, 6, 1, -1, -1, -1, -1, -1, -1, 5, 9, 5, 5, 4, 12}, // 2 - consonant with nukta + {-1, 6, 1, -1, -1, -1, -1, -1, 2, 5, 9, 5, 5, 4, 12}, // 3 - consonant + {-1, -1, -1, -1, -1, -1, 3, 2, -1, -1, -1, -1, -1, -1, 7}, // 4 - consonant virama + {-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 5 - dependent vowels + {-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - vowel mark + {-1, -1, -1, -1, -1, -1, 3, 2, -1, -1, -1, -1, -1, -1, -1}, // 7 - consonant virama ZWJ, consonant ZWJ virama + {-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1}, // 8 - independent vowels that can take a virama + {-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 5, -1, -1}, // 9 - first part of split vowel + {-1, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1}, // 10 - second part of split vowel + {-1, 6, 1, -1, -1, -1, -1, -1, -1, 5, 9, 5, 5, 4, -1}, // 11 - independent vowels that can take an iv + {-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1} // 12 - consonant ZWJ (TODO: Take everything else that can be after a consonant?) }; -const LETag *IndicReordering::getFeatureOrder() + +const FeatureMap *IndicReordering::getFeatureMap(le_int32 &count) { - return featureOrder; + count = featureCount; + + return featureMap; } le_int32 IndicReordering::findSyllable(const IndicClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount) @@ -373,8 +422,9 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le mpreFixups = new MPreFixups(charCount); } - ReorderingOutput output(outChars, glyphStorage, mpreFixups); + IndicReorderingOutput output(outChars, glyphStorage, mpreFixups); le_int32 i, prev = 0; + le_bool lastInWord = FALSE; while (prev < charCount) { le_int32 syllable = findSyllable(classTable, chars, prev, charCount); @@ -384,34 +434,39 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le if (classTable->isStressMark(chars[markStart - 1])) { markStart -= 1; - output.noteStressMark(classTable, chars[markStart], markStart, &tagArray[1]); + output.noteStressMark(classTable, chars[markStart], markStart, tagArray1); } - if (classTable->isVowelModifier(chars[markStart - 1])) { + if (markStart != prev && classTable->isVowelModifier(chars[markStart - 1])) { markStart -= 1; - output.noteVowelModifier(classTable, chars[markStart], markStart, &tagArray[1]); + output.noteVowelModifier(classTable, chars[markStart], markStart, tagArray1); } matra = markStart - 1; - while (output.noteMatra(classTable, chars[matra], matra, &tagArray[1]) && matra != prev) { + while (output.noteMatra(classTable, chars[matra], matra, tagArray1, !lastInWord) && matra != prev) { matra -= 1; } + lastInWord = TRUE; + switch (classTable->getCharClass(chars[prev]) & CF_CLASS_MASK) { case CC_RESERVED: + lastInWord = FALSE; + /* fall through */ + case CC_INDEPENDENT_VOWEL: case CC_ZERO_WIDTH_MARK: for (i = prev; i < syllable; i += 1) { - output.writeChar(chars[i], i, &tagArray[1]); + output.writeChar(chars[i], i, tagArray1); } break; case CC_NUKTA: case CC_VIRAMA: - output.writeChar(C_DOTTED_CIRCLE, prev, &tagArray[1]); - output.writeChar(chars[prev], prev, &tagArray[1]); + output.writeChar(C_DOTTED_CIRCLE, prev, tagArray1); + output.writeChar(chars[prev], prev, tagArray1); break; case CC_DEPENDENT_VOWEL: @@ -422,7 +477,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le case CC_STRESS_MARK: output.writeMpre(); - output.writeChar(C_DOTTED_CIRCLE, prev, &tagArray[1]); + output.writeChar(C_DOTTED_CIRCLE, prev, tagArray1); output.writeMbelow(); output.writeSMbelow(); @@ -442,6 +497,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le } output.writeLengthMark(); + output.writeVirama(); if ((classTable->scriptFlags & SF_REPH_AFTER_BELOW) == 0) { output.writeVMabove(); @@ -452,6 +508,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le break; case CC_INDEPENDENT_VOWEL_2: + case CC_INDEPENDENT_VOWEL_3: case CC_CONSONANT: case CC_CONSONANT_WITH_NUKTA: { @@ -522,9 +579,9 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le // Write eyelash RA // NOTE: baseLimit == prev + 3 iff eyelash RA present... if (baseLimit == prev + 3) { - output.writeChar(chars[prev], prev, &tagArray[2]); - output.writeChar(chars[prev + 1], prev + 1, &tagArray[2]); - output.writeChar(chars[prev + 2], prev + 2, &tagArray[2]); + output.writeChar(chars[prev], prev, tagArray2); + output.writeChar(chars[prev + 1], prev + 1, tagArray2); + output.writeChar(chars[prev + 2], prev + 2, tagArray2); } // write any pre-base consonants @@ -533,21 +590,21 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le for (i = baseLimit; i < baseConsonant; i += 1) { LEUnicode ch = chars[i]; // Don't put 'blwf' on first consonant. - const LETag *tag = (i == baseLimit? &tagArray[2] : &tagArray[1]); + FeatureMask features = (i == baseLimit? tagArray2 : tagArray1); IndicClassTable::CharClass charClass = classTable->getCharClass(ch); if (IndicClassTable::isConsonant(charClass)) { if (IndicClassTable::isVattu(charClass) && supressVattu) { - tag = &tagArray[4]; + features = tagArray4; } supressVattu = IndicClassTable::isVattu(charClass); } else if (IndicClassTable::isVirama(charClass) && chars[i + 1] == C_SIGN_ZWNJ) { - tag = &tagArray[4]; + features = tagArray4; } - output.writeChar(ch, i, tag); + output.writeChar(ch, i, features); } le_int32 bcSpan = baseConsonant + 1; @@ -569,7 +626,7 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le // write base consonant for (i = baseConsonant; i < bcSpan; i += 1) { - output.writeChar(chars[i], i, &tagArray[4]); + output.writeChar(chars[i], i, tagArray4); } if ((classTable->scriptFlags & SF_MATRAS_AFTER_BASE) != 0) { @@ -582,12 +639,12 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le // write below-base consonants if (baseConsonant != lastConsonant) { for (i = bcSpan + 1; i < postBase; i += 1) { - output.writeChar(chars[i], i, &tagArray[1]); + output.writeChar(chars[i], i, tagArray1); } if (postBase > lastConsonant) { // write halant that was after base consonant - output.writeChar(chars[bcSpan], bcSpan, &tagArray[1]); + output.writeChar(chars[bcSpan], bcSpan, tagArray1); } } @@ -600,8 +657,8 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le if ((classTable->scriptFlags & SF_REPH_AFTER_BELOW) != 0) { if (baseLimit == prev + 2) { - output.writeChar(chars[prev], prev, &tagArray[0]); - output.writeChar(chars[prev + 1], prev + 1, &tagArray[0]); + output.writeChar(chars[prev], prev, tagArray0); + output.writeChar(chars[prev + 1], prev + 1, tagArray0); } output.writeVMabove(); @@ -613,16 +670,16 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le if (baseConsonant != lastConsonant) { if (postBase <= lastConsonant) { for (i = postBase; i <= lastConsonant; i += 1) { - output.writeChar(chars[i], i, &tagArray[3]); + output.writeChar(chars[i], i, tagArray3); } // write halant that was after base consonant - output.writeChar(chars[bcSpan], bcSpan, &tagArray[1]); + output.writeChar(chars[bcSpan], bcSpan, tagArray1); } // write the training halant, if there is one if (lastConsonant < matra && classTable->isVirama(chars[matra])) { - output.writeChar(chars[matra], matra, &tagArray[4]); + output.writeChar(chars[matra], matra, tagArray4); } } @@ -632,12 +689,13 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le } output.writeLengthMark(); + output.writeVirama(); // write reph if ((classTable->scriptFlags & SF_REPH_AFTER_BELOW) == 0) { if (baseLimit == prev + 2) { - output.writeChar(chars[prev], prev, &tagArray[0]); - output.writeChar(chars[prev + 1], prev + 1, &tagArray[0]); + output.writeChar(chars[prev], prev, tagArray0); + output.writeChar(chars[prev + 1], prev + 1, tagArray0); } output.writeVMabove(); diff --git a/Build/source/libs/icu-xetex/layout/IndicReordering.h b/Build/source/libs/icu-xetex/layout/IndicReordering.h index 8eeccc87fd1..5a1938e9158 100644 --- a/Build/source/libs/icu-xetex/layout/IndicReordering.h +++ b/Build/source/libs/icu-xetex/layout/IndicReordering.h @@ -27,16 +27,17 @@ U_NAMESPACE_BEGIN #define CC_STRESS_MARK 2U #define CC_INDEPENDENT_VOWEL 3U #define CC_INDEPENDENT_VOWEL_2 4U -#define CC_CONSONANT 5U -#define CC_CONSONANT_WITH_NUKTA 6U -#define CC_NUKTA 7U -#define CC_DEPENDENT_VOWEL 8U -#define CC_SPLIT_VOWEL_PIECE_1 9U -#define CC_SPLIT_VOWEL_PIECE_2 10U -#define CC_SPLIT_VOWEL_PIECE_3 11U -#define CC_VIRAMA 12U -#define CC_ZERO_WIDTH_MARK 13U -#define CC_COUNT 14U +#define CC_INDEPENDENT_VOWEL_3 5U +#define CC_CONSONANT 6U +#define CC_CONSONANT_WITH_NUKTA 7U +#define CC_NUKTA 8U +#define CC_DEPENDENT_VOWEL 9U +#define CC_SPLIT_VOWEL_PIECE_1 10U +#define CC_SPLIT_VOWEL_PIECE_2 11U +#define CC_SPLIT_VOWEL_PIECE_3 12U +#define CC_VIRAMA 13U +#define CC_ZERO_WIDTH_MARK 14U +#define CC_COUNT 15U // Character class flags #define CF_CLASS_MASK 0x0000FFFFU @@ -63,6 +64,7 @@ U_NAMESPACE_BEGIN #define SF_REPH_AFTER_BELOW 0x40000000U #define SF_EYELASH_RA 0x20000000U #define SF_MPRE_FIXUP 0x10000000U +#define SF_FILTER_ZERO_WIDTH 0x08000000U #define SF_POST_BASE_LIMIT_MASK 0x0000FFFFU #define SF_NO_POST_BASE_LIMIT 0x00007FFFU @@ -85,6 +87,7 @@ struct IndicClassTable const SplitMatra *splitMatraTable; inline le_int32 getWorstCaseExpansion() const; + inline le_bool getFilterZeroWidth() const; CharClass getCharClass(LEUnicode ch) const; @@ -125,13 +128,15 @@ class IndicReordering /* not : public UObject because all methods are static */ public: static le_int32 getWorstCaseExpansion(le_int32 scriptCode); + static le_bool getFilterZeroWidth(le_int32 scriptCode); + static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode, LEUnicode *outChars, LEGlyphStorage &glyphStorage, MPreFixups **outMPreFixups); static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage); - static const LETag *getFeatureOrder(); + static const FeatureMap *getFeatureMap(le_int32 &count); private: // do not instantiate @@ -146,6 +151,11 @@ inline le_int32 IndicClassTable::getWorstCaseExpansion() const return worstCaseExpansion; } +inline le_bool IndicClassTable::getFilterZeroWidth() const +{ + return (scriptFlags & SF_FILTER_ZERO_WIDTH) != 0; +} + inline const SplitMatra *IndicClassTable::getSplitMatra(CharClass charClass) const { le_int32 index = (charClass & CF_INDEX_MASK) >> CF_INDEX_SHIFT; diff --git a/Build/source/libs/icu-xetex/layout/KernTable.cpp b/Build/source/libs/icu-xetex/layout/KernTable.cpp index 2a0e0715853..7ba46ee9504 100644 --- a/Build/source/libs/icu-xetex/layout/KernTable.cpp +++ b/Build/source/libs/icu-xetex/layout/KernTable.cpp @@ -6,6 +6,8 @@ */ #include "KernTable.h" +#include "LEFontInstance.h" +#include "LEGlyphStorage.h" #include "LESwaps.h" @@ -51,6 +53,21 @@ struct KernTableHeader { #define COVERAGE_CROSS 0x4 #define COVERAGE_OVERRIDE 0x8 +/* + * This implementation has support for only one subtable, so if the font has + * multiple subtables, only the first will be used. If this turns out to + * be a problem in practice we should add it. + * + * This also supports only version 0 of the kern table header, only + * Apple supports the latter. + * + * This implementation isn't careful about the kern table flags, and + * might invoke kerning when it is not supposed to. That too I'm + * leaving for a bug fix. + * + * TODO: support multiple subtables + * TODO: respect header flags + */ KernTable::KernTable(const LEFontInstance* font, const void* tableData) : pairs(0), font(font) { @@ -58,7 +75,6 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData) if (header == 0) { #if DEBUG fprintf(stderr, "no kern data\n"); - fflush(stderr); #endif return; } @@ -73,7 +89,6 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData) fprintf(stderr, " "); } } - fflush(stderr); #endif if (header->version == 0 && SWAPW(header->nTables) > 0) { @@ -106,7 +121,6 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData) #if DEBUG fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairs); fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift); - fflush(stderr); { // dump part of the pair list @@ -137,7 +151,6 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData) } } } - fflush(stderr); } #endif } @@ -150,7 +163,6 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData) * Process the glyph positions. The positions array has two floats for each * glyph, plus a trailing pair to mark the end of the last glyph. */ -//void KernTable::process(const LEGlyphID glyphs[], float* positions, le_int32 glyphCount) void KernTable::process(LEGlyphStorage& storage) { if (pairs) { @@ -170,12 +182,11 @@ void KernTable::process(LEGlyphStorage& storage) const PairInfo* p = pairs; const PairInfo* tp = (const PairInfo*)((char*)p + rangeShift); if (key > tp->key()) { - p = tp; + p = tp; } #if DEBUG fprintf(stderr, "binary search for %0.8x\n", key); - fflush(stderr); #endif le_uint32 probe = searchRange; @@ -184,8 +195,7 @@ void KernTable::process(LEGlyphStorage& storage) tp = (const PairInfo*)((char*)p + probe); le_uint32 tkey = tp->key(); #if DEBUG - fprintf(stdout, " %.3d (%0.8x)\n", ((char*)tp - (char*)pairs)/KERN_PAIRINFO_SIZE, tkey); - fflush(stdout); + fprintf(stdout, " %.3d (%0.8x)\n", ((char*)tp - (char*)pairs)/KERN_PAIRINFO_SIZE, tkey); #endif if (tkey <= key) { if (tkey == key) { diff --git a/Build/source/libs/icu-xetex/layout/KernTable.h b/Build/source/libs/icu-xetex/layout/KernTable.h index ccbeed19870..b8322cf1fe6 100644 --- a/Build/source/libs/icu-xetex/layout/KernTable.h +++ b/Build/source/libs/icu-xetex/layout/KernTable.h @@ -13,13 +13,15 @@ #endif #include "LETypes.h" -#include "LEFontInstance.h" -#include "LEGlyphStorage.h" +//#include "LEFontInstance.h" +//#include "LEGlyphStorage.h" #include <stdio.h> U_NAMESPACE_BEGIN struct PairInfo; +class LEFontInstance; +class LEGlyphStorage; /** * Windows type 0 kerning table support only for now. diff --git a/Build/source/libs/icu-xetex/layout/KhmerLayoutEngine.cpp b/Build/source/libs/icu-xetex/layout/KhmerLayoutEngine.cpp index 57e76161920..7538eac5568 100644 --- a/Build/source/libs/icu-xetex/layout/KhmerLayoutEngine.cpp +++ b/Build/source/libs/icu-xetex/layout/KhmerLayoutEngine.cpp @@ -1,6 +1,5 @@ /* - * * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * * This file is a modification of the ICU file IndicLayoutEngine.cpp @@ -22,14 +21,16 @@ KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontI le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable) { - fFeatureOrder = KhmerReordering::getFeatureOrder(); + fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount); + fFeatureOrder = TRUE; } KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags) { - fFeatureOrder = KhmerReordering::getFeatureOrder(); + fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount); + fFeatureOrder = TRUE; } KhmerOpenTypeLayoutEngine::~KhmerOpenTypeLayoutEngine() diff --git a/Build/source/libs/icu-xetex/layout/KhmerReordering.cpp b/Build/source/libs/icu-xetex/layout/KhmerReordering.cpp index 8d1045569a2..4f1c442a825 100644 --- a/Build/source/libs/icu-xetex/layout/KhmerReordering.cpp +++ b/Build/source/libs/icu-xetex/layout/KhmerReordering.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved * * This file is a modification of the ICU file IndicReordering.cpp * by Jens Herden and Javier Sola for Khmer language @@ -8,6 +8,7 @@ */ #include "LETypes.h" +#include "OpenTypeTables.h" #include "KhmerReordering.h" #include "LEGlyphStorage.h" @@ -123,7 +124,7 @@ const KhmerClassTable *KhmerClassTable::getKhmerClassTable() -class ReorderingOutput : public UMemory { +class KhmerReorderingOutput : public UMemory { private: le_int32 fOutIndex; LEUnicode *fOutChars; @@ -132,25 +133,25 @@ private: public: - ReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage) + KhmerReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage) : fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage) { // nothing else to do... } - ~ReorderingOutput() + ~KhmerReorderingOutput() { // nothing to do here... } - void writeChar(LEUnicode ch, le_uint32 charIndex, const LETag *charTags) + void writeChar(LEUnicode ch, le_uint32 charIndex, FeatureMask charFeatures) { LEErrorCode success = LE_NO_ERROR; fOutChars[fOutIndex] = ch; fGlyphStorage.setCharIndex(fOutIndex, charIndex, success); - fGlyphStorage.setAuxData(fOutIndex, (void *) charTags, NULL, success); + fGlyphStorage.setAuxData(fOutIndex, charFeatures, NULL, success); fOutIndex += 1; } @@ -162,102 +163,67 @@ public: }; -static const LETag emptyTag = 0x00000000; // '' -//TODO remove unused flags -//static const LETag nuktFeatureTag = LE_NUKT_FEATURE_TAG; -//static const LETag akhnFeatureTag = LE_AKHN_FEATURE_TAG; -//static const LETag rphfFeatureTag = LE_RPHF_FEATURE_TAG; -static const LETag blwfFeatureTag = LE_BLWF_FEATURE_TAG; -//static const LETag halfFeatureTag = LE_HALF_FEATURE_TAG; -static const LETag pstfFeatureTag = LE_PSTF_FEATURE_TAG; -//static const LETag vatuFeatureTag = LE_VATU_FEATURE_TAG; -static const LETag presFeatureTag = LE_PRES_FEATURE_TAG; -static const LETag blwsFeatureTag = LE_BLWS_FEATURE_TAG; -static const LETag abvsFeatureTag = LE_ABVS_FEATURE_TAG; -static const LETag pstsFeatureTag = LE_PSTS_FEATURE_TAG; -//static const LETag halnFeatureTag = LE_HALN_FEATURE_TAG; - -static const LETag blwmFeatureTag = LE_BLWM_FEATURE_TAG; -static const LETag abvmFeatureTag = LE_ABVM_FEATURE_TAG; -static const LETag distFeatureTag = LE_DIST_FEATURE_TAG; - -static const LETag prefFeatureTag = LE_PREF_FEATURE_TAG; -static const LETag abvfFeatureTag = LE_ABVF_FEATURE_TAG; -static const LETag cligFeatureTag = LE_CLIG_FEATURE_TAG; -static const LETag mkmkFeatureTag = LE_MKMK_FEATURE_TAG; +#define blwfFeatureTag LE_BLWF_FEATURE_TAG +#define pstfFeatureTag LE_PSTF_FEATURE_TAG +#define presFeatureTag LE_PRES_FEATURE_TAG +#define blwsFeatureTag LE_BLWS_FEATURE_TAG +#define abvsFeatureTag LE_ABVS_FEATURE_TAG +#define pstsFeatureTag LE_PSTS_FEATURE_TAG + +#define blwmFeatureTag LE_BLWM_FEATURE_TAG +#define abvmFeatureTag LE_ABVM_FEATURE_TAG +#define distFeatureTag LE_DIST_FEATURE_TAG + +#define prefFeatureTag LE_PREF_FEATURE_TAG +#define abvfFeatureTag LE_ABVF_FEATURE_TAG +#define cligFeatureTag LE_CLIG_FEATURE_TAG +#define mkmkFeatureTag LE_MKMK_FEATURE_TAG + +#define prefFeatureMask 0x80000000UL +#define blwfFeatureMask 0x40000000UL +#define abvfFeatureMask 0x20000000UL +#define pstfFeatureMask 0x10000000UL +#define presFeatureMask 0x08000000UL +#define blwsFeatureMask 0x04000000UL +#define abvsFeatureMask 0x02000000UL +#define pstsFeatureMask 0x01000000UL +#define cligFeatureMask 0x00800000UL +#define distFeatureMask 0x00400000UL +#define blwmFeatureMask 0x00200000UL +#define abvmFeatureMask 0x00100000UL +#define mkmkFeatureMask 0x00080000UL + +#define tagPref (prefFeatureMask | presFeatureMask | cligFeatureMask | distFeatureMask) +#define tagAbvf (abvfFeatureMask | abvsFeatureMask | cligFeatureMask | distFeatureMask | abvmFeatureMask | mkmkFeatureMask) +#define tagPstf (blwfFeatureMask | blwsFeatureMask | prefFeatureMask | presFeatureMask | pstfFeatureMask | pstsFeatureMask | cligFeatureMask | distFeatureMask | blwmFeatureMask) +#define tagBlwf (blwfFeatureMask | blwsFeatureMask | cligFeatureMask | distFeatureMask | blwmFeatureMask | mkmkFeatureMask) +#define tagDefault (prefFeatureMask | blwfFeatureMask | presFeatureMask | blwsFeatureMask | cligFeatureMask | distFeatureMask | abvmFeatureMask | blwmFeatureMask | mkmkFeatureMask) + + // These are in the order in which the features need to be applied // for correct processing -static const LETag featureOrder[] = +static const FeatureMap featureMap[] = { // Shaping features - prefFeatureTag, blwfFeatureTag, abvfFeatureTag, pstfFeatureTag, - presFeatureTag, blwsFeatureTag, abvsFeatureTag, pstsFeatureTag, - cligFeatureTag, - - // Positioning features - distFeatureTag, blwmFeatureTag, abvmFeatureTag, mkmkFeatureTag, - emptyTag -}; - -static const LETag tagPref[] = -{ - prefFeatureTag, presFeatureTag, - cligFeatureTag, + {prefFeatureTag, prefFeatureMask}, + {blwfFeatureTag, blwfFeatureMask}, + {abvfFeatureTag, abvfFeatureMask}, + {pstfFeatureTag, pstfFeatureMask}, + {presFeatureTag, presFeatureMask}, + {blwsFeatureTag, blwsFeatureMask}, + {abvsFeatureTag, abvsFeatureMask}, + {pstsFeatureTag, pstsFeatureMask}, + {cligFeatureTag, cligFeatureMask}, // Positioning features - distFeatureTag, - emptyTag + {distFeatureTag, distFeatureMask}, + {blwmFeatureTag, blwmFeatureMask}, + {abvmFeatureTag, abvmFeatureMask}, + {mkmkFeatureTag, mkmkFeatureMask}, }; -static const LETag tagAbvf[] = -{ - abvfFeatureTag, abvsFeatureTag, - cligFeatureTag, - - // Positioning features - distFeatureTag, abvmFeatureTag, mkmkFeatureTag, - emptyTag -}; - -static const LETag tagPstf[] = -{ - blwfFeatureTag, blwsFeatureTag, - prefFeatureTag, presFeatureTag, - - pstfFeatureTag, pstsFeatureTag, - cligFeatureTag, - - // Positioning features - distFeatureTag, blwmFeatureTag, - emptyTag -}; - -static const LETag tagBlwf[] = -{ - blwfFeatureTag, blwsFeatureTag, - cligFeatureTag, - - // Positioning features - distFeatureTag, blwmFeatureTag, mkmkFeatureTag, - emptyTag -}; - - -// TODO do we need all of them? -static const LETag tagDefault[] = -{ - // Shaping feature - prefFeatureTag, blwfFeatureTag, /*abvfFeatureTag,*/ /*pstfFeatureTag, */ - presFeatureTag, blwsFeatureTag, /*abvsFeatureTag,*/ /*pstsFeatureTag,*/ - cligFeatureTag, - - // Positioning features - distFeatureTag, abvmFeatureTag, blwmFeatureTag, mkmkFeatureTag, - emptyTag -}; - - +static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap); // The stateTable is used to calculate the end (the length) of a well // formed Khmer Syllable. @@ -337,12 +303,12 @@ static const le_int8 khmerStateTable[][KhmerClassTable::CC_COUNT] = {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, // 9 - First consonant or type 3 after ceong {-1, 11, 11, 11, -1, -1, -1, -1, -1, -1, -1, -1}, // 10 - Second Coeng (no register shifter before) {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, // 11 - Second coeng consonant (or ind. vowel) no register shifter before - {-1, -1, 1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, // 12 - Second ZWNJ before a register shifter + {-1, -1, -1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, // 12 - Second ZWNJ before a register shifter {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, // 13 - Second register shifter {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, // 14 - ZWJ before vowel {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, // 15 - ZWNJ before vowel {-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 1, 18}, // 16 - dependent vowel - {-1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 18}, // 17 - sign above + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 18}, // 17 - sign above {-1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1}, // 18 - ZWJ after vowel {-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, // 19 - Third coeng {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, // 20 - dependent vowel after a Robat @@ -350,9 +316,11 @@ static const le_int8 khmerStateTable[][KhmerClassTable::CC_COUNT] = }; -const LETag *KhmerReordering::getFeatureOrder() +const FeatureMap *KhmerReordering::getFeatureMap(le_int32 &count) { - return featureOrder; + count = featureMapCount; + + return featureMap; } @@ -387,7 +355,7 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le { const KhmerClassTable *classTable = KhmerClassTable::getKhmerClassTable(); - ReorderingOutput output(outChars, glyphStorage); + KhmerReorderingOutput output(outChars, glyphStorage); KhmerClassTable::CharClass charClass; le_int32 i, prev = 0, coengRo; @@ -407,13 +375,13 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le // if a split vowel, write the pre part. In Khmer the pre part // is the same for all split vowels, same glyph as pre vowel C_VOWEL_E if (charClass & KhmerClassTable::CF_SPLIT_VOWEL) { - output.writeChar(C_VOWEL_E, i, &tagPref[0]); + output.writeChar(C_VOWEL_E, i, tagPref); break; // there can be only one vowel } // if a vowel with pos before write it out if (charClass & KhmerClassTable::CF_POS_BEFORE) { - output.writeChar(chars[i], i, &tagPref[0]); + output.writeChar(chars[i], i, tagPref); break; // there can be only one vowel } @@ -430,8 +398,8 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le // write coeng + ro if found if (coengRo > -1) { - output.writeChar(C_COENG, coengRo, &tagPref[0]); - output.writeChar(C_RO, coengRo + 1, &tagPref[0]); + output.writeChar(C_COENG, coengRo, tagPref); + output.writeChar(C_RO, coengRo + 1, tagPref); } // shall we add a dotted circle? @@ -439,7 +407,7 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le // a character that has the Dotted circle flag (a character that cannot be a base) // then write a dotted circle if (classTable->getCharClass(chars[prev]) & KhmerClassTable::CF_DOTTED_CIRCLE) { - output.writeChar(C_DOTTED_CIRCLE, prev, &tagDefault[0]); + output.writeChar(C_DOTTED_CIRCLE, prev, tagDefault); } // copy what is left to the output, skipping before vowels and coeng Ro if they are present @@ -459,15 +427,15 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le switch (charClass & KhmerClassTable::CF_POS_MASK) { case KhmerClassTable::CF_POS_ABOVE : - output.writeChar(chars[i], i, &tagAbvf[0]); + output.writeChar(chars[i], i, tagAbvf); break; case KhmerClassTable::CF_POS_AFTER : - output.writeChar(chars[i], i, &tagPstf[0]); + output.writeChar(chars[i], i, tagPstf); break; case KhmerClassTable::CF_POS_BELOW : - output.writeChar(chars[i], i, &tagBlwf[0]); + output.writeChar(chars[i], i, tagBlwf); break; default: @@ -476,14 +444,14 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le if ( (charClass & KhmerClassTable::CF_COENG) && i + 1 < syllable ) { if ( (classTable->getCharClass(chars[i + 1]) & KhmerClassTable::CF_CLASS_MASK) == KhmerClassTable::CC_CONSONANT3) { - output.writeChar(chars[i], i, &tagPstf[0]); + output.writeChar(chars[i], i, tagPstf); i += 1; - output.writeChar(chars[i], i, &tagPstf[0]); + output.writeChar(chars[i], i, tagPstf); } else { - output.writeChar(chars[i], i, &tagBlwf[0]); + output.writeChar(chars[i], i, tagBlwf); i += 1; - output.writeChar(chars[i], i, &tagBlwf[0]); + output.writeChar(chars[i], i, tagBlwf); } break; } @@ -502,13 +470,13 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le && ( (classTable->getCharClass(chars[i + 3]) & KhmerClassTable::CF_CLASS_MASK) == C_VOWEL_AA) && ( (classTable->getCharClass(chars[i + 4]) & KhmerClassTable::CF_CLASS_MASK) == C_SIGN_NIKAHIT) ) ) { - output.writeChar(chars[i], i, &tagBlwf[0]); + output.writeChar(chars[i], i, tagBlwf); break; } } // default - any other characters - output.writeChar(chars[i], i, &tagDefault[0]); + output.writeChar(chars[i], i, tagDefault); break; } // switch } // for diff --git a/Build/source/libs/icu-xetex/layout/KhmerReordering.h b/Build/source/libs/icu-xetex/layout/KhmerReordering.h index 71b4021d5eb..eecd12dff63 100644 --- a/Build/source/libs/icu-xetex/layout/KhmerReordering.h +++ b/Build/source/libs/icu-xetex/layout/KhmerReordering.h @@ -1,6 +1,5 @@ /* - * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * * This file is a modification of the ICU file IndicReordering.h * by Jens Herden and Javier Sola for Khmer language @@ -15,8 +14,8 @@ * \internal */ -// #include "LETypes.h" -// #include "OpenTypeTables.h" +#include "LETypes.h" +#include "OpenTypeTables.h" U_NAMESPACE_BEGIN @@ -118,7 +117,7 @@ public: static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode, LEUnicode *outChars, LEGlyphStorage &glyphStorage); - static const LETag *getFeatureOrder(); + static const FeatureMap *getFeatureMap(le_int32 &count); private: // do not instantiate diff --git a/Build/source/libs/icu-xetex/layout/LEFontInstance.cpp b/Build/source/libs/icu-xetex/layout/LEFontInstance.cpp index e36c2a0fc68..f05125f1459 100644 --- a/Build/source/libs/icu-xetex/layout/LEFontInstance.cpp +++ b/Build/source/libs/icu-xetex/layout/LEFontInstance.cpp @@ -1,7 +1,7 @@ /* ******************************************************************************* * - * Copyright (C) 1999-2004, International Business Machines + * Copyright (C) 1999-2006, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -20,6 +20,16 @@ U_NAMESPACE_BEGIN UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEFontInstance) +LECharMapper::~LECharMapper() +{ + // nothing to do. +} + +LEFontInstance::~LEFontInstance() +{ + // nothing to do +} + const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int32 *offset, le_int32 limit, le_int32 script, LEErrorCode &success) const { @@ -37,7 +47,7 @@ const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int } void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, - le_bool reverse, const LECharMapper *mapper, LEGlyphStorage &glyphStorage) const + le_bool reverse, const LECharMapper *mapper, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage) const { le_int32 i, out = 0, dir = 1; @@ -58,7 +68,7 @@ void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, } } - glyphStorage[out] = mapCharToGlyph(code, mapper); + glyphStorage[out] = mapCharToGlyph(code, mapper, filterZeroWidth); if (code >= 0x10000) { i += 1; @@ -69,19 +79,72 @@ void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const { + return mapCharToGlyph(ch, mapper, TRUE); +} + +LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const +{ LEUnicode32 mappedChar = mapper->mapChar(ch); if (mappedChar == 0xFFFE || mappedChar == 0xFFFF) { return 0xFFFF; } - if (mappedChar == 0x200C || mappedChar == 0x200D) { - return 1; + if (filterZeroWidth && (mappedChar == 0x200C || mappedChar == 0x200D)) { + return canDisplay(mappedChar)? 0x0001 : 0xFFFF; } return mapCharToGlyph(mappedChar); } +le_bool LEFontInstance::canDisplay(LEUnicode32 ch) const +{ + return LE_GET_GLYPH(mapCharToGlyph(ch)) != 0; +} + +float LEFontInstance::xUnitsToPoints(float xUnits) const +{ + return (xUnits * getXPixelsPerEm()) / (float) getUnitsPerEM(); +} + +float LEFontInstance::yUnitsToPoints(float yUnits) const +{ + return (yUnits * getYPixelsPerEm()) / (float) getUnitsPerEM(); +} + +void LEFontInstance::unitsToPoints(LEPoint &units, LEPoint &points) const +{ + points.fX = xUnitsToPoints(units.fX); + points.fY = yUnitsToPoints(units.fY); +} + +float LEFontInstance::xPixelsToUnits(float xPixels) const +{ + return (xPixels * getUnitsPerEM()) / (float) getXPixelsPerEm(); +} + +float LEFontInstance::yPixelsToUnits(float yPixels) const +{ + return (yPixels * getUnitsPerEM()) / (float) getYPixelsPerEm(); +} + +void LEFontInstance::pixelsToUnits(LEPoint &pixels, LEPoint &units) const +{ + units.fX = xPixelsToUnits(pixels.fX); + units.fY = yPixelsToUnits(pixels.fY); +} + +void LEFontInstance::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const +{ + pixels.fX = xUnitsToPoints(xFunits) * getScaleFactorX(); + pixels.fY = yUnitsToPoints(yFunits) * getScaleFactorY(); +} + +le_int32 LEFontInstance::getLineHeight() const +{ + return getAscent() + getDescent() + getLeading(); +} + void LEFontInstance::getKernPair(LEGlyphID leftGlyph, LEGlyphID rightGlyph, LEPoint &kern) const { kern.fX = kern.fY = 0; diff --git a/Build/source/libs/icu-xetex/layout/LEFontInstance.h b/Build/source/libs/icu-xetex/layout/LEFontInstance.h index 37a6c98cabc..6d636b8fa31 100644 --- a/Build/source/libs/icu-xetex/layout/LEFontInstance.h +++ b/Build/source/libs/icu-xetex/layout/LEFontInstance.h @@ -1,7 +1,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved * */ @@ -32,7 +32,7 @@ public: * Destructor. * @stable ICU 3.2 */ - virtual inline ~LECharMapper() {}; + virtual ~LECharMapper(); /** * This method does the adjustments. @@ -50,7 +50,7 @@ public: * This is a forward reference to the class which holds the per-glyph * storage. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ class LEGlyphStorage; @@ -76,7 +76,7 @@ class LEGlyphStorage; * methods with some default behavior such as returning constant values, or using the * values from the first subfont. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ class U_LAYOUT_API LEFontInstance : public UObject { @@ -88,7 +88,7 @@ public: * * @stable ICU 2.8 */ - virtual inline ~LEFontInstance() {}; + virtual ~LEFontInstance(); /** * Get a physical font which can render the given text. For composite fonts, @@ -181,7 +181,7 @@ public: * * @stable ICU 3.2 */ - virtual inline le_bool canDisplay(LEUnicode32 ch) const; + virtual le_bool canDisplay(LEUnicode32 ch) const; /** * This method returns the number of design units in @@ -209,13 +209,32 @@ public: * @param count - the number of characters * @param reverse - if <code>TRUE</code>, store the glyph indices in reverse order. * @param mapper - the character mapper. + * @param filterZeroWidth - <code>TRUE</code> if ZWJ / ZWNJ characters should map to a glyph w/ no contours. * @param glyphStorage - the object which contains the output glyph array * * @see LECharMapper * - * @draft ICU 3.0 + * @draft ICU 3.6 */ - virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, const LECharMapper *mapper, LEGlyphStorage &glyphStorage) const; + virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, const LECharMapper *mapper, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage) const; + + /** + * This method maps a single character to a glyph index, using the + * font's character to glyph map. The default implementation of this + * method calls the mapper, and then calls <code>mapCharToGlyph(mappedCh)</code>. + * + * @param ch - the character + * @param mapper - the character mapper + * @param filterZeroWidth - <code>TRUE</code> if ZWJ / ZWNJ characters should map to a glyph w/ no contours. + * + * @return the glyph index + * + * @see LECharMapper + * + * @draft ICU 3.6 + */ + virtual LEGlyphID mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const; + /** * This method maps a single character to a glyph index, using the @@ -305,7 +324,7 @@ public: * * @stable ICU 3.2 */ - virtual inline float xUnitsToPoints(float xUnits) const; + virtual float xUnitsToPoints(float xUnits) const; /** * This method converts font design units in the @@ -317,7 +336,7 @@ public: * * @stable ICU 3.2 */ - virtual inline float yUnitsToPoints(float yUnits) const; + virtual float yUnitsToPoints(float yUnits) const; /** * This method converts font design units to points. @@ -327,7 +346,7 @@ public: * * @stable ICU 3.2 */ - virtual inline void unitsToPoints(LEPoint &units, LEPoint &points) const; + virtual void unitsToPoints(LEPoint &units, LEPoint &points) const; /** * This method converts pixels in the @@ -339,7 +358,7 @@ public: * * @stable ICU 3.2 */ - virtual inline float xPixelsToUnits(float xPixels) const; + virtual float xPixelsToUnits(float xPixels) const; /** * This method converts pixels in the @@ -351,7 +370,7 @@ public: * * @stable ICU 3.2 */ - virtual inline float yPixelsToUnits(float yPixels) const; + virtual float yPixelsToUnits(float yPixels) const; /** * This method converts pixels to font design units. @@ -361,7 +380,7 @@ public: * * @stable ICU 3.2 */ - virtual inline void pixelsToUnits(LEPoint &pixels, LEPoint &units) const; + virtual void pixelsToUnits(LEPoint &pixels, LEPoint &units) const; /** * Get the X scale factor from the font's transform. The default @@ -403,7 +422,7 @@ public: * * @stable ICU 3.2 */ - virtual inline void transformFunits(float xFunits, float yFunits, LEPoint &pixels) const; + virtual void transformFunits(float xFunits, float yFunits, LEPoint &pixels) const; /** * This is a convenience method used to convert @@ -492,59 +511,16 @@ public: static UClassID getStaticClassID(); /** - * Returns true if writing direction is vertical. + * Returns kern value for a glyph pair, if the font has a kern pair list. */ - virtual inline bool getLayoutDirVertical() const; + virtual void getKernPair(LEGlyphID leftGlyph, LEGlyphID rightGlyph, LEPoint &kern) const; /** - * Returns kern value for a glyph pair, if the font has a kern pair list. + * Returns true if writing direction is vertical. */ - virtual void getKernPair(LEGlyphID leftGlyph, LEGlyphID rightGlyph, LEPoint &kern) const; + virtual inline bool getLayoutDirVertical() const; }; -inline le_bool LEFontInstance::canDisplay(LEUnicode32 ch) const -{ - return LE_GET_GLYPH(mapCharToGlyph(ch)) != 0; -} - -inline float LEFontInstance::xUnitsToPoints(float xUnits) const -{ - return (xUnits * getXPixelsPerEm()) / (float) getUnitsPerEM(); -} - -inline float LEFontInstance::yUnitsToPoints(float yUnits) const -{ - return (yUnits * getYPixelsPerEm()) / (float) getUnitsPerEM(); -} - -inline void LEFontInstance::unitsToPoints(LEPoint &units, LEPoint &points) const -{ - points.fX = xUnitsToPoints(units.fX); - points.fY = yUnitsToPoints(units.fY); -} - -inline float LEFontInstance::xPixelsToUnits(float xPixels) const -{ - return (xPixels * getUnitsPerEM()) / (float) getXPixelsPerEm(); -} - -inline float LEFontInstance::yPixelsToUnits(float yPixels) const -{ - return (yPixels * getUnitsPerEM()) / (float) getYPixelsPerEm(); -} - -inline void LEFontInstance::pixelsToUnits(LEPoint &pixels, LEPoint &units) const -{ - units.fX = xPixelsToUnits(pixels.fX); - units.fY = yPixelsToUnits(pixels.fY); -} - -inline void LEFontInstance::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const -{ - pixels.fX = xUnitsToPoints(xFunits) * getScaleFactorX(); - pixels.fY = yUnitsToPoints(yFunits) * getScaleFactorY(); -} - inline float LEFontInstance::fixedToFloat(le_int32 fixed) { return (float) (fixed / 65536.0); @@ -555,11 +531,6 @@ inline le_int32 LEFontInstance::floatToFixed(float theFloat) return (le_int32) (theFloat * 65536.0); } -inline le_int32 LEFontInstance::getLineHeight() const -{ - return getAscent() + getDescent() + getLeading(); -} - inline bool LEFontInstance::getLayoutDirVertical() const { return false; diff --git a/Build/source/libs/icu-xetex/layout/LEGlyphStorage.cpp b/Build/source/libs/icu-xetex/layout/LEGlyphStorage.cpp index 55cbbbfcb21..1b595159a11 100644 --- a/Build/source/libs/icu-xetex/layout/LEGlyphStorage.cpp +++ b/Build/source/libs/icu-xetex/layout/LEGlyphStorage.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (C) 1998-2004, International Business Machines + * Copyright (C) 1998-2006, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -13,6 +13,11 @@ U_NAMESPACE_BEGIN UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEGlyphStorage) +LEInsertionCallback::~LEInsertionCallback() +{ + // nothing to do... +} + LEGlyphStorage::LEGlyphStorage() : fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL), fAuxData(NULL), fAuxParam(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0) @@ -38,6 +43,7 @@ void LEGlyphStorage::reset() LE_DELETE_ARRAY(fAuxData); fAuxData = NULL; } + if (fAuxParam != NULL) { LE_DELETE_ARRAY(fAuxParam); fAuxParam = NULL; @@ -119,7 +125,8 @@ le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success) } if (fPositions != NULL) { - LE_DELETE_ARRAY(fPositions); + success = LE_INTERNAL_ERROR; + return -1; } fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1)); @@ -139,7 +146,12 @@ le_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success) return -1; } - fAuxData = LE_NEW_ARRAY(void *, fGlyphCount); + if (fAuxData != NULL || fAuxParam != NULL) { + success = LE_INTERNAL_ERROR; + return -1; + } + + fAuxData = LE_NEW_ARRAY(le_uint32, fGlyphCount); fAuxParam = LE_NEW_ARRAY(void *, fGlyphCount); if (fAuxData == NULL || fAuxParam == NULL) { @@ -311,7 +323,7 @@ void LEGlyphStorage::setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErr fCharIndices[glyphIndex] = charIndex; } -void LEGlyphStorage::getAuxData(void *auxData[], LEErrorCode &success) const +void LEGlyphStorage::getAuxData(le_uint32 auxData[], LEErrorCode &success) const { if (LE_FAILURE(success)) { return; @@ -330,26 +342,26 @@ void LEGlyphStorage::getAuxData(void *auxData[], LEErrorCode &success) const LE_ARRAY_COPY(auxData, fAuxData, fGlyphCount); } -void *LEGlyphStorage::getAuxData(le_int32 glyphIndex, LEErrorCode &success) const +le_uint32 LEGlyphStorage::getAuxData(le_int32 glyphIndex, LEErrorCode &success) const { if (LE_FAILURE(success)) { - return NULL; + return 0; } if (fAuxData == NULL) { success = LE_NO_LAYOUT_ERROR; - return NULL; + return 0; } if (glyphIndex < 0 || glyphIndex >= fGlyphCount) { success = LE_INDEX_OUT_OF_BOUNDS_ERROR; - return NULL; + return 0; } return fAuxData[glyphIndex]; } -void *LEGlyphStorage::getAuxData2(le_int32 glyphIndex, LEErrorCode &success) const +void *LEGlyphStorage::getAuxParam(le_int32 glyphIndex, LEErrorCode &success) const { if (LE_FAILURE(success)) { return NULL; @@ -368,7 +380,7 @@ void *LEGlyphStorage::getAuxData2(le_int32 glyphIndex, LEErrorCode &success) con return fAuxParam[glyphIndex]; } -void LEGlyphStorage::setAuxData(le_int32 glyphIndex, void *auxData, void *auxParam, LEErrorCode &success) +void LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, void *auxParam, LEErrorCode &success) { if (LE_FAILURE(success)) { return; @@ -499,6 +511,7 @@ void LEGlyphStorage::adoptAuxDataArrays(LEGlyphStorage &from) if (fAuxData != NULL) { LE_DELETE_ARRAY(fAuxData); } + if (fAuxParam != NULL) { LE_DELETE_ARRAY(fAuxParam); } @@ -539,8 +552,9 @@ le_int32 LEGlyphStorage::applyInsertions() fCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount); if (fAuxData != NULL) { - fAuxData = (void **) LE_GROW_ARRAY(fAuxData, newGlyphCount); + fAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount); } + if (fAuxParam != NULL) { fAuxParam = (void **) LE_GROW_ARRAY(fAuxParam, newGlyphCount); } diff --git a/Build/source/libs/icu-xetex/layout/LEGlyphStorage.h b/Build/source/libs/icu-xetex/layout/LEGlyphStorage.h index 34e3f3df93b..3855a4fd716 100644 --- a/Build/source/libs/icu-xetex/layout/LEGlyphStorage.h +++ b/Build/source/libs/icu-xetex/layout/LEGlyphStorage.h @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (C) 1998-2005, International Business Machines + * Copyright (C) 1998-2006, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -29,7 +29,7 @@ U_NAMESPACE_BEGIN * * @see LEInsertionList.h * - * @draft ICU 3.0 + * @draft ICU 3.6 */ class U_LAYOUT_API LEGlyphStorage : public UObject, protected LEInsertionCallback { @@ -67,10 +67,9 @@ private: * * @internal */ - void **fAuxData; + le_uint32 *fAuxData; void **fAuxParam; - /** * The insertion list, used to grow the above arrays. * @@ -106,7 +105,7 @@ protected: * * @see LEInsertionList.h * - * @draft ICU 3.0 + * @stable ICU 3.0 */ virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]); @@ -116,11 +115,15 @@ public: * Allocates an empty <code>LEGlyphStorage</code> object. You must call * <code>allocateGlyphArray, allocatePositions and allocateAuxData</code> * to allocate the data. + * + * @stable ICU 3.0 */ LEGlyphStorage(); /** * The destructor. This will deallocate all of the arrays. + * + * @stable ICU 3.0 */ ~LEGlyphStorage(); @@ -129,7 +132,7 @@ public: * * @return the number of glyphs in the glyph array * - * @draft ICU 3.0 + * @stable ICU 3.0 */ inline le_int32 getGlyphCount() const; @@ -141,7 +144,7 @@ public: * @param glyphs - the destiniation glyph array * @param success - set to an error code if the operation fails * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const; @@ -155,7 +158,7 @@ public: * @param extraBits - this value will be ORed with each glyph index * @param success - set to an error code if the operation fails * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const; @@ -167,7 +170,7 @@ public: * @param charIndices - the destiniation character index array * @param success - set to an error code if the operation fails * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void getCharIndices(le_int32 charIndices[], LEErrorCode &success) const; @@ -180,7 +183,7 @@ public: * @param indexBase - an offset which will be added to each index * @param success - set to an error code if the operation fails * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const; @@ -193,7 +196,7 @@ public: * @param positions - the destiniation position array * @param success - set to an error code if the operation fails * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void getGlyphPositions(float positions[], LEErrorCode &success) const; @@ -209,7 +212,7 @@ public: * @param y - the glyph's Y position * @param success - set to an error code if the operation fails * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const; @@ -223,7 +226,7 @@ public: * @param success set to an error code if the storage cannot be allocated of if the initial * glyph count is not positive. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success); @@ -235,7 +238,7 @@ public: * * @return the number of X, Y position pairs allocated. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ le_int32 allocatePositions(LEErrorCode &success); @@ -246,7 +249,7 @@ public: * * @return the size of the auxillary data array. * - * @draft ICU 3.0 + * @draft ICU 3.6 */ le_int32 allocateAuxData(LEErrorCode &success); @@ -256,9 +259,9 @@ public: * @param auxData the auxillary data array will be copied to this address * @param success set to an error code if the data cannot be copied * - * @draft ICU 3.0 + * @draft ICU 3.6 */ - void getAuxData(void *auxData[], LEErrorCode &success) const; + void getAuxData(le_uint32 auxData[], LEErrorCode &success) const; /** * Get the glyph ID for a particular glyph. @@ -268,7 +271,7 @@ public: * * @return the glyph ID * - * @draft ICU 3.0 + * @stable ICU 3.0 */ LEGlyphID getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const; @@ -280,7 +283,7 @@ public: * * @return the character index * - * @draft ICU 3.0 + * @stable ICU 3.0 */ le_int32 getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const; @@ -293,10 +296,10 @@ public: * * @return the auxillary data * - * @draft ICU 3.0 + * @draft ICU 3.6 */ - void *getAuxData(le_int32 glyphIndex, LEErrorCode &success) const; - void *getAuxData2(le_int32 glyphIndex, LEErrorCode &success) const; + le_uint32 getAuxData(le_int32 glyphIndex, LEErrorCode &success) const; + void *getAuxParam(le_int32 glyphIndex, LEErrorCode &success) const; /** * This operator allows direct access to the glyph array @@ -306,7 +309,7 @@ public: * * @return a reference to the given location in the glyph array * - * @draft ICU 3.0 + * @stable ICU 3.0 */ inline LEGlyphID &operator[](le_int32 glyphIndex) const; @@ -324,7 +327,7 @@ public: * * @see LEInsetionList.h * - * @draft ICU 3.0 + * @stable ICU 3.0 */ LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount); @@ -338,7 +341,7 @@ public: * * @see LEInsertionList.h * - * @draft ICU 3.0 + * @stable ICU 3.0 */ le_int32 applyInsertions(); @@ -349,7 +352,7 @@ public: * @param glyphID the new glyph ID * @param success will be set to an error code if the glyph ID cannot be set. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success); @@ -360,7 +363,7 @@ public: * @param charIndex the new char index * @param success will be set to an error code if the char index cannot be set. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success); @@ -372,7 +375,7 @@ public: * @param y the new Y position * @param success will be set to an error code if the position cannot be set. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success); @@ -384,7 +387,7 @@ public: * @param yAdjust the adjustment to the glyph's Y position * @param success will be set to an error code if the glyph's position cannot be adjusted. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success); @@ -396,9 +399,9 @@ public: * @param auxParam the new secondary auxiliary data (parameter) * @param success will be set to an error code if the auxiliary data cannot be set. * - * @draft ICU 3.0 + * @draft ICU 3.6 */ - void setAuxData(le_int32 glyphIndex, void *auxData, void *auxParam, LEErrorCode &success); + void setAuxData(le_int32 glyphIndex, le_uint32 auxData, void *auxParam, LEErrorCode &success); /** * Delete the glyph array and replace it with the one @@ -408,7 +411,7 @@ public: * @param from the <code>LEGlyphStorage</code> object from which * to get the new glyph array. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void adoptGlyphArray(LEGlyphStorage &from); @@ -420,7 +423,7 @@ public: * @param from the <code>LEGlyphStorage</code> object from which * to get the new char indices array. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void adoptCharIndicesArray(LEGlyphStorage &from); @@ -432,7 +435,7 @@ public: * @param from the <code>LEGlyphStorage</code> object from which * to get the new position array. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void adoptPositionArray(LEGlyphStorage &from); @@ -444,7 +447,7 @@ public: * @param from the <code>LEGlyphStorage</code> object from which * to get the new auxillary data array. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void adoptAuxDataArrays(LEGlyphStorage &from); @@ -455,7 +458,7 @@ public: * @param from the <code>LEGlyphStorage</code> object from which * to get the new glyph count. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void adoptGlyphCount(LEGlyphStorage &from); @@ -464,7 +467,7 @@ public: * * @param newGlyphCount the new glyph count. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void adoptGlyphCount(le_int32 newGlyphCount); @@ -474,21 +477,21 @@ public: * to layout a different characer array. (This method is also called * by the destructor) * - * @draft ICU 3.0 + * @stable ICU 3.0 */ void reset(); /** * ICU "poor man's RTTI", returns a UClassID for the actual class. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ virtual UClassID getDynamicClassID() const; /** * ICU "poor man's RTTI", returns a UClassID for this class. * - * @draft ICU 3.0 + * @stable ICU 3.0 */ static UClassID getStaticClassID(); }; diff --git a/Build/source/libs/icu-xetex/layout/LEInsertionList.h b/Build/source/libs/icu-xetex/layout/LEInsertionList.h index 2d67c2a5df1..a894295280d 100644 --- a/Build/source/libs/icu-xetex/layout/LEInsertionList.h +++ b/Build/source/libs/icu-xetex/layout/LEInsertionList.h @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (C) 1998-2004, International Business Machines + * Copyright (C) 1998-2006, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -20,7 +20,7 @@ struct InsertionRecord; * * @internal */ -class LEInsertionCallback +class U_LAYOUT_API LEInsertionCallback { public: /** @@ -37,6 +37,11 @@ public: * @internal */ virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]) = 0; + + /** + * The destructor + */ + virtual ~LEInsertionCallback(); }; /** diff --git a/Build/source/libs/icu-xetex/layout/LELanguages.h b/Build/source/libs/icu-xetex/layout/LELanguages.h index 6248237ee80..563ddcfd179 100644 --- a/Build/source/libs/icu-xetex/layout/LELanguages.h +++ b/Build/source/libs/icu-xetex/layout/LELanguages.h @@ -1,9 +1,11 @@ /* * - * (C) Copyright IBM Corp. 1998-2005. All Rights Reserved. + * (C) Copyright IBM Corp. 1998-2006. All Rights Reserved. * * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * YOU REALLY KNOW WHAT YOU'RE DOING. + * + * Generated on: 08/21/2006 02:35:14 PM HST */ #ifndef __LELANGUAGES_H @@ -12,7 +14,7 @@ #include "LETypes.h" /** - * \file + * \file * \brief C++ API: List of language codes for LayoutEngine */ @@ -23,7 +25,7 @@ U_NAMESPACE_BEGIN * this is just a list of languages which the LayoutEngine * supports. * - * @draft ICU 3.0 + * @draft ICU 3.6 */ enum LanguageCodes { diff --git a/Build/source/libs/icu-xetex/layout/LEScripts.h b/Build/source/libs/icu-xetex/layout/LEScripts.h index a0593d2afa4..f8e7ac5b151 100644 --- a/Build/source/libs/icu-xetex/layout/LEScripts.h +++ b/Build/source/libs/icu-xetex/layout/LEScripts.h @@ -1,28 +1,30 @@ /* * - * (C) Copyright IBM Corp. 1998-2005. All Rights Reserved. + * (C) Copyright IBM Corp. 1998-2006. All Rights Reserved. * * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * YOU REALLY KNOW WHAT YOU'RE DOING. + * + * Generated on: 08/21/2006 02:35:13 PM HST */ #ifndef __LESCRIPTS_H #define __LESCRIPTS_H #include "LETypes.h" + /** - * \file + * \file * \brief C++ API: Constants for Unicode script values */ - U_NAMESPACE_BEGIN /** * Constants for Unicode script values, generated using * ICU4J's <code>UScript</code> class. * - * @draft ICU 3.0 + * @draft ICU 3.6 */ enum ScriptCodes { @@ -33,7 +35,7 @@ enum ScriptCodes { bengScriptCode = 4, bopoScriptCode = 5, cherScriptCode = 6, - qaacScriptCode = 7, + coptScriptCode = 7, cyrlScriptCode = 8, dsrtScriptCode = 9, devaScriptCode = 10, @@ -81,8 +83,57 @@ enum ScriptCodes { taleScriptCode = 52, ugarScriptCode = 53, hrktScriptCode = 54, + bugiScriptCode = 55, + glagScriptCode = 56, + kharScriptCode = 57, + syloScriptCode = 58, + taluScriptCode = 59, + tfngScriptCode = 60, + xpeoScriptCode = 61, + baliScriptCode = 62, + batkScriptCode = 63, + blisScriptCode = 64, + brahScriptCode = 65, + chamScriptCode = 66, + cirtScriptCode = 67, + cyrsScriptCode = 68, + egydScriptCode = 69, + egyhScriptCode = 70, + egypScriptCode = 71, + geokScriptCode = 72, + hansScriptCode = 73, + hantScriptCode = 74, + hmngScriptCode = 75, + hungScriptCode = 76, + indsScriptCode = 77, + javaScriptCode = 78, + kaliScriptCode = 79, + latfScriptCode = 80, + latgScriptCode = 81, + lepcScriptCode = 82, + linaScriptCode = 83, + mandScriptCode = 84, + mayaScriptCode = 85, + meroScriptCode = 86, + nkooScriptCode = 87, + orkhScriptCode = 88, + permScriptCode = 89, + phagScriptCode = 90, + phnxScriptCode = 91, + plrdScriptCode = 92, + roroScriptCode = 93, + saraScriptCode = 94, + syreScriptCode = 95, + syrjScriptCode = 96, + syrnScriptCode = 97, + tengScriptCode = 98, + vaiiScriptCode = 99, + vispScriptCode = 100, + xsuxScriptCode = 101, + zxxxScriptCode = 102, + zzzzScriptCode = 103, - scriptCodeCount = 55 + scriptCodeCount = 104 }; U_NAMESPACE_END diff --git a/Build/source/libs/icu-xetex/layout/LETypes.h b/Build/source/libs/icu-xetex/layout/LETypes.h index 31670d51845..51da9cb513c 100644 --- a/Build/source/libs/icu-xetex/layout/LETypes.h +++ b/Build/source/libs/icu-xetex/layout/LETypes.h @@ -1,7 +1,6 @@ - /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -267,6 +266,14 @@ struct LEPoint typedef struct LEPoint LEPoint; #endif + +/** + * A convenience macro to get the length of an array. + * + * @internal + */ +#define LE_ARRAY_SIZE(array) (sizeof array / sizeof array[0]) + #ifdef LE_USE_CMEMORY /** * A convenience macro for copying an array. diff --git a/Build/source/libs/icu-xetex/layout/LayoutEngine.cpp b/Build/source/libs/icu-xetex/layout/LayoutEngine.cpp index 3bfb6c9d96b..381460c067f 100644 --- a/Build/source/libs/icu-xetex/layout/LayoutEngine.cpp +++ b/Build/source/libs/icu-xetex/layout/LayoutEngine.cpp @@ -1,7 +1,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved * */ @@ -13,9 +13,11 @@ #include "ArabicLayoutEngine.h" #include "CanonShaping.h" #include "HanLayoutEngine.h" +#include "HangulLayoutEngine.h" #include "IndicLayoutEngine.h" #include "KhmerLayoutEngine.h" #include "ThaiLayoutEngine.h" +#include "TibetanLayoutEngine.h" #include "GXLayoutEngine.h" #include "ScriptAndLanguageTags.h" #include "CharSubstitutionFilter.h" @@ -32,8 +34,6 @@ U_NAMESPACE_BEGIN -#define ARRAY_SIZE(array) (sizeof array / sizeof array[0]) - const LEUnicode32 DefaultCharMapper::controlChars[] = { 0x0009, 0x000A, 0x000D, /*0x200C, 0x200D,*/ 0x200E, 0x200F, @@ -41,29 +41,7 @@ const LEUnicode32 DefaultCharMapper::controlChars[] = { 0x206A, 0x206B, 0x206C, 0x206D, 0x206E, 0x206F }; -const le_int32 DefaultCharMapper::controlCharsCount = ARRAY_SIZE(controlChars); - -const LEUnicode32 DefaultCharMapper::mirroredChars[] = { - 0x0028, 0x0029, // ascii paired punctuation - 0x003c, 0x003e, - 0x005b, 0x005d, - 0x007b, 0x007d, - 0x2045, 0x2046, // math symbols (not complete) - 0x207d, 0x207e, - 0x208d, 0x208e, - 0x2264, 0x2265, - 0x3008, 0x3009, // chinese paired punctuation - 0x300a, 0x300b, - 0x300c, 0x300d, - 0x300e, 0x300f, - 0x3010, 0x3011, - 0x3014, 0x3015, - 0x3016, 0x3017, - 0x3018, 0x3019, - 0x301a, 0x301b -}; - -const le_int32 DefaultCharMapper::mirroredCharsCount = ARRAY_SIZE(mirroredChars); +const le_int32 DefaultCharMapper::controlCharsCount = LE_ARRAY_SIZE(controlChars); LEUnicode32 DefaultCharMapper::mapChar(LEUnicode32 ch) const { @@ -76,12 +54,10 @@ LEUnicode32 DefaultCharMapper::mapChar(LEUnicode32 ch) const } if (fMirror) { - le_int32 index = OpenTypeUtilities::search((le_uint32) ch, (le_uint32 *)mirroredChars, mirroredCharsCount); + le_int32 index = OpenTypeUtilities::search((le_uint32) ch, (le_uint32 *)DefaultCharMapper::mirroredChars, DefaultCharMapper::mirroredCharsCount); if (mirroredChars[index] == ch) { - le_int32 mirrorOffset = ((index & 1) == 0) ? 1 : -1; - - return mirroredChars[index + mirrorOffset]; + return DefaultCharMapper::srahCderorrim[index]; } } @@ -110,11 +86,18 @@ CharSubstitutionFilter::~CharSubstitutionFilter() UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine) -static const LETag emptyTag = 0x00000000; +#define ccmpFeatureTag LE_CCMP_FEATURE_TAG -static const LETag ccmpFeatureTag = LE_CCMP_FEATURE_TAG; +#define ccmpFeatureMask 0x80000000UL -static const LETag canonFeatures[] = {ccmpFeatureTag, emptyTag}; +#define canonFeatures (ccmpFeatureMask) + +static const FeatureMap canonFeatureMap[] = +{ + {ccmpFeatureTag, ccmpFeatureMask} +}; + +static const le_int32 canonFeatureMapCount = LE_ARRAY_SIZE(canonFeatureMap); LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags) : fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode), @@ -161,7 +144,7 @@ void LayoutEngine::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEE } le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, - LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success) + LEUnicode *&outChars, LEGlyphStorage &/*glyphStorage*/, LEErrorCode &success) { if (LE_FAILURE(success)) { return 0; @@ -181,6 +164,13 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance); const LEUnicode *inChars = &chars[offset]; LEUnicode *reordered = NULL; + LEGlyphStorage fakeGlyphStorage; + + fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success); + + if (LE_FAILURE(success)) { + return 0; + } // This is the cheapest way to get mark reordering only for Hebrew. // We could just do the mark reordering for all scripts, but most @@ -193,12 +183,11 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off return 0; } - CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, glyphStorage); + CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage); inChars = reordered; - } + } - glyphStorage.allocateGlyphArray(count, rightToLeft, success); - glyphStorage.allocateAuxData(success); + fakeGlyphStorage.allocateAuxData(success); if (LE_FAILURE(success)) { return 0; @@ -210,21 +199,21 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off } for (i = 0; i < count; i += 1, out += dir) { - glyphStorage[out] = (LEGlyphID) inChars[i]; - glyphStorage.setAuxData(out, (void *) canonFeatures, NULL, success); + fakeGlyphStorage[out] = (LEGlyphID) inChars[i]; + fakeGlyphStorage.setAuxData(out, canonFeatures, NULL, success); } if (reordered != NULL) { LE_DELETE_ARRAY(reordered); } - outCharCount = canonGSUBTable->process(glyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, NULL); + outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE); - out = (rightToLeft? count - 1 : 0); + out = (rightToLeft? outCharCount - 1 : 0); outChars = LE_NEW_ARRAY(LEUnicode, outCharCount); for (i = 0; i < outCharCount; i += 1, out += dir) { - outChars[out] = (LEUnicode) LE_GET_GLYPH(glyphStorage[i]); + outChars[out] = (LEUnicode) LE_GET_GLYPH(fakeGlyphStorage[i]); } delete substitutionFilter; @@ -249,10 +238,10 @@ le_int32 LayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, l le_int32 outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, glyphStorage, success); if (outChars != NULL) { - mapCharsToGlyphs(outChars, 0, outCharCount, rightToLeft, rightToLeft, glyphStorage, success); + mapCharsToGlyphs(outChars, 0, outCharCount, rightToLeft, rightToLeft, TRUE, glyphStorage, success); LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work... } else { - mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success); + mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, TRUE, glyphStorage, success); } return glyphStorage.getGlyphCount(); @@ -409,7 +398,7 @@ const void *LayoutEngine::getFontTable(LETag tableTag) const return fFontInstance->getFontTable(tableTag); } -void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, +void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage, LEErrorCode &success) { if (LE_FAILURE(success)) { @@ -420,7 +409,7 @@ void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le DefaultCharMapper charMapper(TRUE, mirror); - fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, glyphStorage); + fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, filterZeroWidth, glyphStorage); } // Input: characters, font? @@ -439,6 +428,10 @@ le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_ } le_int32 glyphCount; + + if (fGlyphStorage->getGlyphCount() > 0) { + fGlyphStorage->reset(); + } glyphCount = computeGlyphs(chars, offset, count, max, rightToLeft, *fGlyphStorage, success); positionGlyphs(*fGlyphStorage, x, y, success); @@ -483,6 +476,7 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan case guruScriptCode: case tamlScriptCode: case teluScriptCode: + case sinhScriptCode: result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); break; @@ -492,6 +486,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); break; + case hangScriptCode: + result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); + break; + case haniScriptCode: languageTag = OpenTypeLayoutEngine::getLangSysTag(languageCode); @@ -513,6 +511,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan break; + case tibtScriptCode: + result = new TibetanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); + break; + case khmrScriptCode: result = new KhmerOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); break; @@ -537,6 +539,7 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan case guruScriptCode: case tamlScriptCode: case teluScriptCode: + case sinhScriptCode: { result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); break; diff --git a/Build/source/libs/icu-xetex/layout/LayoutEngine.h b/Build/source/libs/icu-xetex/layout/LayoutEngine.h index 43403351173..172d4e1798a 100644 --- a/Build/source/libs/icu-xetex/layout/LayoutEngine.h +++ b/Build/source/libs/icu-xetex/layout/LayoutEngine.h @@ -1,7 +1,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved * */ @@ -254,6 +254,7 @@ protected: * @param count - the number of characters to be mapped * @param reverse - if <code>TRUE</code>, the output will be in reverse order * @param mirror - if <code>TRUE</code>, do character mirroring + * @param filterZeroWidth - if <code>TRUE</code> replace ZWJ / ZWNJ with a glyph with no contours. * @param glyphStorage - the object which holds the per-glyph storage. The glyph and char * indices arrays will be filled in. * @param success - set to an error code if the operation fails @@ -262,7 +263,7 @@ protected: * * @internal */ - virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, LEGlyphStorage &glyphStorage, LEErrorCode &success); + virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage, LEErrorCode &success); /** * This is a convenience method that forces the advance width of mark @@ -313,7 +314,7 @@ public: /** * This method will invoke the layout steps in their correct order by calling - * the computeGlyphs, positionGlyphs and adjustGlyphPosition methods.. It will + * the computeGlyphs, positionGlyphs and adjustGlyphPosition methods. It will * compute the glyph, character index and position arrays. * * @param chars - the input character context @@ -327,8 +328,12 @@ public: * * @return the number of glyphs in the glyph array * - * Note; the glyph, character index and position array can be accessed - * using the getter method below. + * Note: The glyph, character index and position array can be accessed + * using the getter methods below. + * + * Note: If you call this method more than once, you must call the reset() + * method first to free the glyph, character index and position arrays + * allocated by the previous call. * * @stable ICU 2.8 */ diff --git a/Build/source/libs/icu-xetex/layout/LookupProcessor.cpp b/Build/source/libs/icu-xetex/layout/LookupProcessor.cpp index 985fb7c3408..107fd496480 100644 --- a/Build/source/libs/icu-xetex/layout/LookupProcessor.cpp +++ b/Build/source/libs/icu-xetex/layout/LookupProcessor.cpp @@ -19,12 +19,6 @@ U_NAMESPACE_BEGIN -const LETag LookupProcessor::notSelected = 0x00000000; -const LETag LookupProcessor::defaultFeature = 0xFFFFFFFF; - -static const LETag emptyTag = 0x00000000; - - le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const { @@ -64,13 +58,13 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj for (le_uint16 order = 0; order < lookupOrderCount; order += 1) { le_uint16 lookup = lookupOrderArray[order]; - LETag selectTag = lookupSelectArray[lookup]; + FeatureMask selectMask = lookupSelectArray[lookup]; - if (selectTag != notSelected) { + if (selectMask != 0) { const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup); le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags); - glyphIterator.reset(lookupFlags, selectTag); + glyphIterator.reset(lookupFlags, selectMask); while (glyphIterator.findFeatureTag()) { le_uint32 delta = 1; @@ -98,7 +92,7 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt return delta; } -le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, LETag featureTag, le_int32 order) +le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, FeatureMask featureMask, le_int32 order) { le_uint16 lookupCount = featureTable? SWAPW(featureTable->lookupCount) : 0; le_int32 store = order; @@ -106,10 +100,8 @@ le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, LETag for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) { le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]); - if (lookupSelectArray[lookupListIndex] == notSelected) { - lookupSelectArray[lookupListIndex] = featureTag; - lookupOrderArray[store++] = lookupListIndex; - } + lookupSelectArray[lookupListIndex] |= featureMask; + lookupOrderArray[store++] = lookupListIndex; } return store - order; @@ -117,9 +109,9 @@ le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, LETag LookupProcessor::LookupProcessor(const char *baseAddress, Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset, - LETag scriptTag, LETag languageTag, const LETag *featureOrder) + LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures) : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL), - requiredFeatureTag(notSelected), lookupOrderArray(NULL), lookupOrderCount(0) + lookupOrderArray(NULL), lookupOrderCount(0) { const ScriptListTable *scriptListTable = NULL; const LangSysTable *langSysTable = NULL; @@ -152,39 +144,66 @@ LookupProcessor::LookupProcessor(const char *baseAddress, requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex); - lookupSelectArray = LE_NEW_ARRAY(LETag, lookupListCount); + lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount); for (int i = 0; i < lookupListCount; i += 1) { - lookupSelectArray[i] = notSelected; + lookupSelectArray[i] = 0; } le_int32 count, order = 0; - const FeatureTable *featureTable = 0; + le_int32 featureReferences = 0; + const FeatureTable *featureTable = NULL; LETag featureTag; - lookupOrderArray = LE_NEW_ARRAY(le_uint16, lookupListCount); + const FeatureTable *requiredFeatureTable = NULL; + LETag requiredFeatureTag = 0x00000000U; + + // Count the total number of lookups referenced by all features. This will + // be the maximum number of entries in the lookupOrderArray. We can't use + // lookupListCount because some lookups might be referenced by more than + // one feature. + for (le_int32 feature = 0; feature < featureCount; feature += 1) { + le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]); + + featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); + featureReferences += SWAPW(featureTable->lookupCount); + } if (requiredFeatureIndex != 0xFFFF) { - featureTable = featureListTable->getFeatureTable(requiredFeatureIndex, &featureTag); - order += selectLookups(featureTable, defaultFeature, order); + requiredFeatureTable = featureListTable->getFeatureTable(requiredFeatureIndex, &requiredFeatureTag); + featureReferences += SWAPW(featureTable->lookupCount); } - if (featureOrder != NULL) { - if (order > 1) { - OpenTypeUtilities::sort(lookupOrderArray, order); + lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences); + + for (le_int32 f = 0; f < featureMapCount; f += 1) { + FeatureMap fm = featureMap[f]; + count = 0; + + // If this is the required feature, add its lookups + if (requiredFeatureTag == fm.tag) { + count += selectLookups(requiredFeatureTable, fm.mask, order); } - for (le_int32 tag = 0; featureOrder[tag] != emptyTag; tag += 1) { - featureTag = featureOrder[tag]; - count = 0; + if (orderFeatures) { + // If we added lookups from the required feature, sort them + if (count > 1) { + OpenTypeUtilities::sort(lookupOrderArray, order); + } for (le_uint16 feature = 0; feature < featureCount; feature += 1) { le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]); + + // don't add the required feature to the list more than once... + // TODO: Do we need this check? (Spec. says required feature won't be in feature list...) + if (featureIndex == requiredFeatureIndex) { + continue; + } featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); - if (featureTag == featureOrder[tag]) { - count += selectLookups(featureTable, featureTag, order + count); + if (featureTag == fm.tag) { + count += selectLookups(featureTable, fm.mask, order + count); } } @@ -193,24 +212,51 @@ LookupProcessor::LookupProcessor(const char *baseAddress, } order += count; - } - } else { - for (le_uint16 feature = 0; feature < featureCount; feature += 1) { - le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]); + } else { + for (le_uint16 feature = 0; feature < featureCount; feature += 1) { + le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]); - // don't add the required feature to the list more than once... - if (featureIndex == requiredFeatureIndex) { - continue; - } + // don't add the required feature to the list more than once... + // NOTE: This check is commented out because the spec. says that + // the required feature won't be in the feature list, and because + // any duplicate entries will be removed below. +#if 0 + if (featureIndex == requiredFeatureIndex) { + continue; + } +#endif - featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); - count = selectLookups(featureTable, featureTag, order); - order += count; + featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); + + if (featureTag == fm.tag) { + order += selectLookups(featureTable, fm.mask, order); + } + } } + } - if (order > 1) { - OpenTypeUtilities::sort(lookupOrderArray, order); + if (!orderFeatures && (order > 1)) { + OpenTypeUtilities::sort(lookupOrderArray, order); + + // If there's no specified feature order, + // we will apply the lookups in the order + // that they're in the font. If a particular + // lookup may be referenced by more than one feature, + // it will apprear in the lookupOrderArray more than + // once, so remove any duplicate entries in the sorted array. + le_int32 out = 1; + + for (le_int32 in = 1; in < order; in += 1) { + if (lookupOrderArray[out - 1] != lookupOrderArray[in]) { + if (out != in) { + lookupOrderArray[out] = lookupOrderArray[in]; + } + + out += 1; + } } + + order = out; } lookupOrderCount = order; diff --git a/Build/source/libs/icu-xetex/layout/LookupProcessor.h b/Build/source/libs/icu-xetex/layout/LookupProcessor.h index 136a0541f57..bc05ae63b79 100644 --- a/Build/source/libs/icu-xetex/layout/LookupProcessor.h +++ b/Build/source/libs/icu-xetex/layout/LookupProcessor.h @@ -33,9 +33,6 @@ struct LookupTable; class LookupProcessor : public UMemory { public: - static const LETag notSelected; - static const LETag defaultFeature; - le_int32 process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEFontInstance *fontInstance) const; @@ -49,19 +46,18 @@ public: virtual ~LookupProcessor(); protected: - LookupProcessor(const char *baseAddress, + LookupProcessor(const char *baseAddress, Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset, - LETag scriptTag, LETag languageTag, const LETag *featureOrder); + LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures); - LookupProcessor(); + LookupProcessor(); - le_int32 selectLookups(const FeatureTable *featureTable, LETag featureTag, le_int32 order); + le_int32 selectLookups(const FeatureTable *featureTable, FeatureMask featureMask, le_int32 order); const LookupListTable *lookupListTable; const FeatureListTable *featureListTable; - LETag *lookupSelectArray; - LETag requiredFeatureTag; + FeatureMask *lookupSelectArray; le_uint16 *lookupOrderArray; le_uint32 lookupOrderCount; diff --git a/Build/source/libs/icu-xetex/layout/MakeShapingTypeData.pl b/Build/source/libs/icu-xetex/layout/MakeShapingTypeData.pl new file mode 100644 index 00000000000..4062b403170 --- /dev/null +++ b/Build/source/libs/icu-xetex/layout/MakeShapingTypeData.pl @@ -0,0 +1,90 @@ +#! /usr/bin/perl + +# script to create ShapingTypeData.cpp from UCD file DerivedJoiningType.txt +# written by JK, 2007-01-16 +# This script may be distributed and used freely + +%types = ( + 'C' => 1, + 'D' => 2, + 'R' => 4, + 'T' => 5 +); + +@ranges = (); + +sub addRange +{ + my ($s, $e, $t) = @_; + + if ((scalar @ranges > 0) + && ($ranges[$#ranges]->[2] == $t) + && ($ranges[$#ranges]->[1] == $s - 1)) { + $ranges[$#ranges]->[1] = $e; + return; + } + + push @ranges, [ $s, $e, $t ]; +} + +# read the DerivedJoiningType.txt file and remember all the ranges +while (<>) { + if (m/^([0-9A-F]{4})\s+; ([CDRT]) \#/) { + # single codepoint + $start = hex $1; + $end = $start; + $type = $types{$2}; + addRange($start, $end, $type); + next; + } + if (m/^([0-9A-F]{4})\.\.([0-9A-F]{4})\s+; ([CDRT]) \#/) { + # range of codes + $start = hex $1; + $end = hex $2; + $type = $types{$3}; + addRange($start, $end, $type); + next; + } +} + +# write the ShapingTypeData.cpp file + +$date = `date +"%F %T %Z"`; +print <<__EOT__; +/* + * + * (C) Copyright SIL International. 2007. + * (C) Copyright IBM Corp. 1998-2005. + * Based on code distributed with ICU 3.6 + * and the Unicode Character Database, version 5.0.0 + * + * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS + * YOU REALLY KNOW WHAT YOU'RE DOING. + * + * Generated on: $date + */ + +#include "LETypes.h" +#include "ArabicShaping.h" + +U_NAMESPACE_BEGIN + +const le_uint8 ArabicShaping::shapingTypeTable[] = { +__EOT__ + +printf " 0x%02X, 0x%02X, /* classFormat */\n", 0, 2; +printf " 0x%02X, 0x%02X, /* classRangeCount */\n", + (scalar @ranges) / 256, (scalar @ranges) % 256; +print join(",\n", map { + sprintf " 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X", + $_->[0] / 256, $_->[0] % 256, + $_->[1] / 256, $_->[1] % 256, + $_->[2] / 256, $_->[2] % 256, + } sort { $a->[0] <=> $b->[0] } @ranges); + +print <<__EOT__; + +}; + +U_NAMESPACE_END +__EOT__ diff --git a/Build/source/libs/icu-xetex/layout/Makefile.in b/Build/source/libs/icu-xetex/layout/Makefile.in index 6d6ef6b53b7..b1224521c9f 100644 --- a/Build/source/libs/icu-xetex/layout/Makefile.in +++ b/Build/source/libs/icu-xetex/layout/Makefile.in @@ -1,13 +1,18 @@ -## Copyright (c) 1999-2005, International Business Machines Corporation and -## others. All Rights Reserved. +#****************************************************************************** +# +# Copyright (C) 1999-2006, International Business Machines +# Corporation and others. All Rights Reserved. +# +#****************************************************************************** ## Makefile.in for ICU - layout -## Install directory information +## Source directory information srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = .. +## All the flags and other definitions are included here. include $(top_builddir)/icudefs.mk ## Build directory information @@ -26,7 +31,7 @@ endif ifneq ($(ENABLE_SHARED),) SO_TARGET = $(LIBDIR)/$(LIBICU)$(TARGET_STUBNAME)$(ICULIBSUFFIX).$(SO) -ALL_SO_TARGETS = $(SO_TARGET) $(MIDDLE_SO_TARGET) $(FINAL_SO_TARGET) +ALL_SO_TARGETS = $(SO_TARGET) $(MIDDLE_SO_TARGET) $(FINAL_SO_TARGET) $(SHARED_OBJECT) ifeq ($(ENABLE_SO_VERSION_DATA),1) SO_VERSION_DATA = layout.res @@ -45,9 +50,12 @@ DYNAMICCPPFLAGS = $(SHAREDLIBCPPFLAGS) DYNAMICCFLAGS = $(SHAREDLIBCFLAGS) DYNAMICCXXFLAGS = $(SHAREDLIBCXXFLAGS) -LDFLAGS += $(LDFLAGSICULE) -CPPFLAGS += -I$(srcdir) -I$(top_builddir)/common -I$(top_srcdir)/common -I$(srcdir)/unicode -I$(srcdir)/.. $(LIBCPPFLAGS) +ifneq ($(top_builddir),$(top_srcdir)) +CPPFLAGS += -I$(top_builddir)/common +endif +CPPFLAGS += -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)/common -I$(srcdir)/unicode $(LIBCPPFLAGS) DEFS += -DU_LAYOUT_IMPLEMENTATION +LDFLAGS += $(LDFLAGSICULE) LIBS = $(LIBICUUC) $(DEFAULT_LIBS) OBJECTS = LEFontInstance.o \ @@ -105,26 +113,33 @@ MarkArrays.o \ MarkToBasePosnSubtables.o \ MarkToLigaturePosnSubtables.o \ MarkToMarkPosnSubtables.o \ +MirroredCharData.o \ MPreFixups.o \ MultipleSubstSubtables.o \ OpenTypeUtilities.o \ PairPositioningSubtables.o \ ScriptAndLanguage.o \ ScriptAndLanguageTags.o \ +ShapingTypeData.o \ SinglePositioningSubtables.o \ SingleSubstitutionSubtables.o \ SubstitutionLookups.o \ ValueRecords.o \ KhmerLayoutEngine.o \ KhmerReordering.o \ +TibetanLayoutEngine.o \ +TibetanReordering.o \ +HangulLayoutEngine.o \ KernTable.o +## Header files to install +HEADERS= $(srcdir)/LayoutEngine.h $(srcdir)/LE*.h + STATIC_OBJECTS = $(OBJECTS:.o=.$(STATIC_O)) DEPS = $(OBJECTS:.o=.d) -## Header files to install -HEADERS= $(srcdir)/LayoutEngine.h $(srcdir)/LE*.h +-include Makefile.local ## List of phony targets .PHONY : all all-local install install-local clean clean-local \ @@ -144,7 +159,7 @@ check: all check-local all-local: $(ALL_TARGETS) -install-local: install-headers install-library +install-local: install-headers install-library install-library: all-local $(MKINSTALLDIRS) $(DESTDIR)$(libdir) @@ -170,7 +185,6 @@ ifneq ($(MIDDLE_IMPORT_LIB),$(FINAL_IMPORT_LIB)) endif endif - install-headers: $(MKINSTALLDIRS) $(DESTDIR)$(includedir)/layout @for file in $(HEADERS); do \ @@ -182,7 +196,7 @@ dist-local: clean-local: test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES) - $(RMV) $(OBJECTS) $(ALL_TARGETS) $(SO_VERSION_DATA) + $(RMV) $(OBJECTS) $(STATIC_OBJECTS) $(ALL_TARGETS) $(SO_VERSION_DATA) distclean-local: clean-local $(RMV) Makefile @@ -199,15 +213,14 @@ $(TARGET): $(TARGET)($(STATIC_OBJECTS)) endif ifneq ($(ENABLE_SHARED),) -$(FINAL_SO_TARGET): $(OBJECTS) $(SO_VERSION_DATA) +$(SHARED_OBJECT): $(OBJECTS) $(SO_VERSION_DATA) $(SHLIB.cc) $(LD_SONAME) $(OUTOPT)$@ $^ $(LIBS) ifeq ($(OS390BATCH),1) -$(BATCH_TARGET): $(OBJECTS) +$(BATCH_TARGET):$(OBJECTS) $(SHLIB.cc) $(LD_SONAME) $(OUTOPT)$@ $^ $(BATCH_LIBS) endif # OS390BATCH - -endif +endif # ENABLE_SHARED ifeq (,$(MAKECMDGOALS)) -include $(DEPS) @@ -217,4 +230,3 @@ ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),) endif endif - diff --git a/Build/source/libs/icu-xetex/layout/MarkToMarkPosnSubtables.cpp b/Build/source/libs/icu-xetex/layout/MarkToMarkPosnSubtables.cpp index 66d1b9dd1c2..3f571f5e39c 100644 --- a/Build/source/libs/icu-xetex/layout/MarkToMarkPosnSubtables.cpp +++ b/Build/source/libs/icu-xetex/layout/MarkToMarkPosnSubtables.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -65,6 +65,11 @@ le_int32 MarkToMarkPositioningSubtable::process(GlyphIterator *glyphIterator, co const AnchorTable *anchorTable = (const AnchorTable *) ((char *) mark2Array + anchorTableOffset); LEPoint mark2Anchor, markAdvance, pixels; + if (anchorTableOffset == 0) { + // this seems to mean that the marks don't attach... + return 0; + } + anchorTable->getAnchor(mark2Glyph, fontInstance, mark2Anchor); fontInstance->getGlyphAdvance(markGlyph, pixels); diff --git a/Build/source/libs/icu-xetex/layout/MirroredCharData.cpp b/Build/source/libs/icu-xetex/layout/MirroredCharData.cpp new file mode 100644 index 00000000000..b813371708f --- /dev/null +++ b/Build/source/libs/icu-xetex/layout/MirroredCharData.cpp @@ -0,0 +1,108 @@ +/* + * + * (C) Copyright IBM Corp. 1998-2005. All Rights Reserved. + * + * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS + * YOU REALLY KNOW WHAT YOU'RE DOING. + * + * Generated on: 07/20/2005 10:43:59 AM PDT + */ + +#include "LETypes.h" +#include "DefaultCharMapper.h" + +U_NAMESPACE_BEGIN + +const LEUnicode32 DefaultCharMapper::mirroredChars[] = { + 0x0028, 0x0029, 0x003C, 0x003E, 0x005B, 0x005D, 0x007B, 0x007D, + 0x00AB, 0x00BB, 0x2039, 0x203A, 0x2045, 0x2046, 0x207D, 0x207E, + 0x208D, 0x208E, 0x2208, 0x2209, 0x220A, 0x220B, 0x220C, 0x220D, + 0x2215, 0x223C, 0x223D, 0x2243, 0x2252, 0x2253, 0x2254, 0x2255, + 0x2264, 0x2265, 0x2266, 0x2267, 0x2268, 0x2269, 0x226A, 0x226B, + 0x226E, 0x226F, 0x2270, 0x2271, 0x2272, 0x2273, 0x2274, 0x2275, + 0x2276, 0x2277, 0x2278, 0x2279, 0x227A, 0x227B, 0x227C, 0x227D, + 0x227E, 0x227F, 0x2280, 0x2281, 0x2282, 0x2283, 0x2284, 0x2285, + 0x2286, 0x2287, 0x2288, 0x2289, 0x228A, 0x228B, 0x228F, 0x2290, + 0x2291, 0x2292, 0x2298, 0x22A2, 0x22A3, 0x22A6, 0x22A8, 0x22A9, + 0x22AB, 0x22B0, 0x22B1, 0x22B2, 0x22B3, 0x22B4, 0x22B5, 0x22B6, + 0x22B7, 0x22C9, 0x22CA, 0x22CB, 0x22CC, 0x22CD, 0x22D0, 0x22D1, + 0x22D6, 0x22D7, 0x22D8, 0x22D9, 0x22DA, 0x22DB, 0x22DC, 0x22DD, + 0x22DE, 0x22DF, 0x22E0, 0x22E1, 0x22E2, 0x22E3, 0x22E4, 0x22E5, + 0x22E6, 0x22E7, 0x22E8, 0x22E9, 0x22EA, 0x22EB, 0x22EC, 0x22ED, + 0x22F0, 0x22F1, 0x22F2, 0x22F3, 0x22F4, 0x22F6, 0x22F7, 0x22FA, + 0x22FB, 0x22FC, 0x22FD, 0x22FE, 0x2308, 0x2309, 0x230A, 0x230B, + 0x2329, 0x232A, 0x2768, 0x2769, 0x276A, 0x276B, 0x276C, 0x276D, + 0x276E, 0x276F, 0x2770, 0x2771, 0x2772, 0x2773, 0x2774, 0x2775, + 0x27C3, 0x27C4, 0x27C5, 0x27C6, 0x27D5, 0x27D6, 0x27DD, 0x27DE, + 0x27E2, 0x27E3, 0x27E4, 0x27E5, 0x27E6, 0x27E7, 0x27E8, 0x27E9, + 0x27EA, 0x27EB, 0x2983, 0x2984, 0x2985, 0x2986, 0x2987, 0x2988, + 0x2989, 0x298A, 0x298B, 0x298C, 0x298D, 0x298E, 0x298F, 0x2990, + 0x2991, 0x2992, 0x2993, 0x2994, 0x2995, 0x2996, 0x2997, 0x2998, + 0x29B8, 0x29C0, 0x29C1, 0x29C4, 0x29C5, 0x29CF, 0x29D0, 0x29D1, + 0x29D2, 0x29D4, 0x29D5, 0x29D8, 0x29D9, 0x29DA, 0x29DB, 0x29F5, + 0x29F8, 0x29F9, 0x29FC, 0x29FD, 0x2A2B, 0x2A2C, 0x2A2D, 0x2A2E, + 0x2A34, 0x2A35, 0x2A3C, 0x2A3D, 0x2A64, 0x2A65, 0x2A79, 0x2A7A, + 0x2A7D, 0x2A7E, 0x2A7F, 0x2A80, 0x2A81, 0x2A82, 0x2A83, 0x2A84, + 0x2A8B, 0x2A8C, 0x2A91, 0x2A92, 0x2A93, 0x2A94, 0x2A95, 0x2A96, + 0x2A97, 0x2A98, 0x2A99, 0x2A9A, 0x2A9B, 0x2A9C, 0x2AA1, 0x2AA2, + 0x2AA6, 0x2AA7, 0x2AA8, 0x2AA9, 0x2AAA, 0x2AAB, 0x2AAC, 0x2AAD, + 0x2AAF, 0x2AB0, 0x2AB3, 0x2AB4, 0x2ABB, 0x2ABC, 0x2ABD, 0x2ABE, + 0x2ABF, 0x2AC0, 0x2AC1, 0x2AC2, 0x2AC3, 0x2AC4, 0x2AC5, 0x2AC6, + 0x2ACD, 0x2ACE, 0x2ACF, 0x2AD0, 0x2AD1, 0x2AD2, 0x2AD3, 0x2AD4, + 0x2AD5, 0x2AD6, 0x2ADE, 0x2AE3, 0x2AE4, 0x2AE5, 0x2AEC, 0x2AED, + 0x2AF7, 0x2AF8, 0x2AF9, 0x2AFA, 0x2E02, 0x2E03, 0x2E04, 0x2E05, + 0x2E09, 0x2E0A, 0x2E0C, 0x2E0D, 0x2E1C, 0x2E1D, 0x3008, 0x3009, + 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, 0x3010, 0x3011, + 0x3014, 0x3015, 0x3016, 0x3017, 0x3018, 0x3019, 0x301A, 0x301B, + 0xFF08, 0xFF09, 0xFF1C, 0xFF1E, 0xFF3B, 0xFF3D, 0xFF5B, 0xFF5D, + 0xFF5F, 0xFF60, 0xFF62, 0xFF63 +}; + +const LEUnicode32 DefaultCharMapper::srahCderorrim[] = { + 0x0029, 0x0028, 0x003E, 0x003C, 0x005D, 0x005B, 0x007D, 0x007B, + 0x00BB, 0x00AB, 0x203A, 0x2039, 0x2046, 0x2045, 0x207E, 0x207D, + 0x208E, 0x208D, 0x220B, 0x220C, 0x220D, 0x2208, 0x2209, 0x220A, + 0x29F5, 0x223D, 0x223C, 0x22CD, 0x2253, 0x2252, 0x2255, 0x2254, + 0x2265, 0x2264, 0x2267, 0x2266, 0x2269, 0x2268, 0x226B, 0x226A, + 0x226F, 0x226E, 0x2271, 0x2270, 0x2273, 0x2272, 0x2275, 0x2274, + 0x2277, 0x2276, 0x2279, 0x2278, 0x227B, 0x227A, 0x227D, 0x227C, + 0x227F, 0x227E, 0x2281, 0x2280, 0x2283, 0x2282, 0x2285, 0x2284, + 0x2287, 0x2286, 0x2289, 0x2288, 0x228B, 0x228A, 0x2290, 0x228F, + 0x2292, 0x2291, 0x29B8, 0x22A3, 0x22A2, 0x2ADE, 0x2AE4, 0x2AE3, + 0x2AE5, 0x22B1, 0x22B0, 0x22B3, 0x22B2, 0x22B5, 0x22B4, 0x22B7, + 0x22B6, 0x22CA, 0x22C9, 0x22CC, 0x22CB, 0x2243, 0x22D1, 0x22D0, + 0x22D7, 0x22D6, 0x22D9, 0x22D8, 0x22DB, 0x22DA, 0x22DD, 0x22DC, + 0x22DF, 0x22DE, 0x22E1, 0x22E0, 0x22E3, 0x22E2, 0x22E5, 0x22E4, + 0x22E7, 0x22E6, 0x22E9, 0x22E8, 0x22EB, 0x22EA, 0x22ED, 0x22EC, + 0x22F1, 0x22F0, 0x22FA, 0x22FB, 0x22FC, 0x22FD, 0x22FE, 0x22F2, + 0x22F3, 0x22F4, 0x22F6, 0x22F7, 0x2309, 0x2308, 0x230B, 0x230A, + 0x232A, 0x2329, 0x2769, 0x2768, 0x276B, 0x276A, 0x276D, 0x276C, + 0x276F, 0x276E, 0x2771, 0x2770, 0x2773, 0x2772, 0x2775, 0x2774, + 0x27C4, 0x27C3, 0x27C6, 0x27C5, 0x27D6, 0x27D5, 0x27DE, 0x27DD, + 0x27E3, 0x27E2, 0x27E5, 0x27E4, 0x27E7, 0x27E6, 0x27E9, 0x27E8, + 0x27EB, 0x27EA, 0x2984, 0x2983, 0x2986, 0x2985, 0x2988, 0x2987, + 0x298A, 0x2989, 0x298C, 0x298B, 0x2990, 0x298F, 0x298E, 0x298D, + 0x2992, 0x2991, 0x2994, 0x2993, 0x2996, 0x2995, 0x2998, 0x2997, + 0x2298, 0x29C1, 0x29C0, 0x29C5, 0x29C4, 0x29D0, 0x29CF, 0x29D2, + 0x29D1, 0x29D5, 0x29D4, 0x29D9, 0x29D8, 0x29DB, 0x29DA, 0x2215, + 0x29F9, 0x29F8, 0x29FD, 0x29FC, 0x2A2C, 0x2A2B, 0x2A2E, 0x2A2D, + 0x2A35, 0x2A34, 0x2A3D, 0x2A3C, 0x2A65, 0x2A64, 0x2A7A, 0x2A79, + 0x2A7E, 0x2A7D, 0x2A80, 0x2A7F, 0x2A82, 0x2A81, 0x2A84, 0x2A83, + 0x2A8C, 0x2A8B, 0x2A92, 0x2A91, 0x2A94, 0x2A93, 0x2A96, 0x2A95, + 0x2A98, 0x2A97, 0x2A9A, 0x2A99, 0x2A9C, 0x2A9B, 0x2AA2, 0x2AA1, + 0x2AA7, 0x2AA6, 0x2AA9, 0x2AA8, 0x2AAB, 0x2AAA, 0x2AAD, 0x2AAC, + 0x2AB0, 0x2AAF, 0x2AB4, 0x2AB3, 0x2ABC, 0x2ABB, 0x2ABE, 0x2ABD, + 0x2AC0, 0x2ABF, 0x2AC2, 0x2AC1, 0x2AC4, 0x2AC3, 0x2AC6, 0x2AC5, + 0x2ACE, 0x2ACD, 0x2AD0, 0x2ACF, 0x2AD2, 0x2AD1, 0x2AD4, 0x2AD3, + 0x2AD6, 0x2AD5, 0x22A6, 0x22A9, 0x22A8, 0x22AB, 0x2AED, 0x2AEC, + 0x2AF8, 0x2AF7, 0x2AFA, 0x2AF9, 0x2E03, 0x2E02, 0x2E05, 0x2E04, + 0x2E0A, 0x2E09, 0x2E0D, 0x2E0C, 0x2E1D, 0x2E1C, 0x3009, 0x3008, + 0x300B, 0x300A, 0x300D, 0x300C, 0x300F, 0x300E, 0x3011, 0x3010, + 0x3015, 0x3014, 0x3017, 0x3016, 0x3019, 0x3018, 0x301B, 0x301A, + 0xFF09, 0xFF08, 0xFF1E, 0xFF1C, 0xFF3D, 0xFF3B, 0xFF5D, 0xFF5B, + 0xFF60, 0xFF5F, 0xFF63, 0xFF62 +}; + +const le_int32 DefaultCharMapper::mirroredCharsCount = 332; + +U_NAMESPACE_END diff --git a/Build/source/libs/icu-xetex/layout/OpenTypeLayoutEngine.cpp b/Build/source/libs/icu-xetex/layout/OpenTypeLayoutEngine.cpp index 2d1e3dde84a..6ed165bf5c3 100644 --- a/Build/source/libs/icu-xetex/layout/OpenTypeLayoutEngine.cpp +++ b/Build/source/libs/icu-xetex/layout/OpenTypeLayoutEngine.cpp @@ -1,7 +1,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved * */ @@ -12,6 +12,7 @@ #include "LayoutEngine.h" #include "OpenTypeLayoutEngine.h" #include "ScriptAndLanguageTags.h" +#include "CharSubstitutionFilter.h" #include "GlyphSubstitutionTables.h" #include "GlyphDefinitionTables.h" @@ -26,54 +27,68 @@ U_NAMESPACE_BEGIN UOBJECT_DEFINE_RTTI_IMPLEMENTATION(OpenTypeLayoutEngine) -static const LETag emptyTag = 0x00000000; - -static const LETag ccmpFeatureTag = LE_CCMP_FEATURE_TAG; -static const LETag loclFeatureTag = LE_LOCL_FEATURE_TAG; -static const LETag ligaFeatureTag = LE_LIGA_FEATURE_TAG; -static const LETag cligFeatureTag = LE_CLIG_FEATURE_TAG; -static const LETag kernFeatureTag = LE_KERN_FEATURE_TAG; -static const LETag markFeatureTag = LE_MARK_FEATURE_TAG; -static const LETag mkmkFeatureTag = LE_MKMK_FEATURE_TAG; - -static const LETag dligFeatureTag = 0x646C6967; // 'dlig' not used at the moment -static const LETag paltFeatureTag = 0x70616C74; // 'palt' - -// default has no ligatures, that's what java does. this is the minimal set. -static const LETag minimalFeatures[] = {ccmpFeatureTag, loclFeatureTag, markFeatureTag, mkmkFeatureTag, emptyTag}; - -// kerning (kern, palt following adobe recommendation for cjk 'kerning') but no ligatures. -static const LETag kernFeatures[] = {ccmpFeatureTag, loclFeatureTag, kernFeatureTag, paltFeatureTag, - markFeatureTag, mkmkFeatureTag, emptyTag}; - -// ligatures (liga, clig) but no kerning. omit dlig for now. -static const LETag ligaFeatures[] = {ccmpFeatureTag, loclFeatureTag, ligaFeatureTag, cligFeatureTag, markFeatureTag, - mkmkFeatureTag, emptyTag}; - -// kerning and ligatures. -static const LETag kernAndLigaFeatures[] = {ccmpFeatureTag, loclFeatureTag, ligaFeatureTag, cligFeatureTag, - kernFeatureTag, paltFeatureTag, markFeatureTag, mkmkFeatureTag, emptyTag}; +#define ccmpFeatureTag LE_CCMP_FEATURE_TAG +#define ligaFeatureTag LE_LIGA_FEATURE_TAG +#define cligFeatureTag LE_CLIG_FEATURE_TAG +#define kernFeatureTag LE_KERN_FEATURE_TAG +#define markFeatureTag LE_MARK_FEATURE_TAG +#define mkmkFeatureTag LE_MKMK_FEATURE_TAG + +// 'dlig' not used at the moment +#define dligFeatureTag 0x646C6967 + +// 'palt' +#define paltFeatureTag 0x70616C74 + +#define ccmpFeatureMask 0x80000000UL +#define ligaFeatureMask 0x40000000UL +#define cligFeatureMask 0x20000000UL +#define kernFeatureMask 0x10000000UL +#define paltFeatureMask 0x08000000UL +#define markFeatureMask 0x04000000UL +#define mkmkFeatureMask 0x02000000UL + +#define minimalFeatures (ccmpFeatureMask | markFeatureMask | mkmkFeatureMask) +#define ligaFeatures (ligaFeatureMask | cligFeatureMask | minimalFeatures) +#define kernFeatures (kernFeatureMask | paltFeatureMask | minimalFeatures) +#define kernAndLigaFeatures (ligaFeatures | kernFeatures) + +static const FeatureMap featureMap[] = +{ + {ccmpFeatureTag, ccmpFeatureMask}, + {ligaFeatureTag, ligaFeatureMask}, + {cligFeatureTag, cligFeatureMask}, + {kernFeatureTag, kernFeatureMask}, + {paltFeatureTag, paltFeatureMask}, + {markFeatureTag, markFeatureMask}, + {mkmkFeatureTag, mkmkFeatureMask} +}; +static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap); OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) - : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), - fFeatureList(minimalFeatures), fFeatureParamList(NULL), fFeatureOrder(NULL), - fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL) + : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fFeatureMask(minimalFeatures), + fFeatureMap(featureMap), fFeatureParamList(NULL), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE), + fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL), fFilterZeroWidth(TRUE) { static const le_uint32 gdefTableTag = LE_GDEF_TABLE_TAG; static const le_uint32 gposTableTag = LE_GPOS_TABLE_TAG; const GlyphPositioningTableHeader *gposTable = (const GlyphPositioningTableHeader *) getFontTable(gposTableTag); // todo: switch to more flags and bitfield rather than list of feature tags? - switch (typoFlags) { + switch (typoFlags & ~0x80000000L) { case 0: break; // default - case 1: fFeatureList = kernFeatures; break; - case 2: fFeatureList = ligaFeatures; break; - case 3: fFeatureList = kernAndLigaFeatures; break; + case 1: fFeatureMask = kernFeatures; break; + case 2: fFeatureMask = ligaFeatures; break; + case 3: fFeatureMask = kernAndLigaFeatures; break; default: break; } + if (typoFlags & 0x80000000L) { + fSubstitutionFilter = new CharSubstitutionFilter(fontInstance); + } + setScriptAndLanguageTags(); fGDEFTable = (const GlyphDefinitionTableHeader *) getFontTable(gdefTableTag); @@ -94,14 +109,18 @@ void OpenTypeLayoutEngine::reset() OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags) - : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fFeatureOrder(NULL), - fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL) + : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fFeatureOrder(FALSE), + fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL), fFilterZeroWidth(TRUE) { setScriptAndLanguageTags(); } OpenTypeLayoutEngine::~OpenTypeLayoutEngine() { + if (fTypoFlags & 0x80000000L) { + delete fSubstitutionFilter; + } + reset(); } @@ -150,7 +169,7 @@ le_int32 OpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_i glyphStorage.allocateGlyphArray(outCharCount, rightToLeft, success); glyphStorage.allocateAuxData(success); for (le_int32 i = 0; i < outCharCount; i += 1) { - glyphStorage.setAuxData(i, (void *) fFeatureList, (void *) fFeatureParamList, success); + glyphStorage.setAuxData(i, fFeatureMask, (void *) fFeatureParamList, success); } return outCharCount; @@ -170,14 +189,15 @@ le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32 return 0; } - mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success); + mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, fFilterZeroWidth, glyphStorage, success); if (LE_FAILURE(success)) { return 0; } if (fGSUBTable != NULL) { - count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, fFeatureOrder); + count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, + fFeatureMap, fFeatureMapCount, fFeatureOrder); } return count; @@ -214,6 +234,10 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, fakeGlyphStorage, success); + if (LE_FAILURE(success)) { + return 0; + } + if (outChars != NULL) { fakeGlyphCount = glyphProcessing(outChars, 0, outCharCount, outCharCount, rightToLeft, fakeGlyphStorage, success); LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work... @@ -223,6 +247,10 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o //adjustGlyphs(chars, offset, count, rightToLeft, fakeGlyphs, fakeGlyphCount); } + if (LE_FAILURE(success)) { + return 0; + } + outGlyphCount = glyphPostProcessing(fakeGlyphStorage, glyphStorage, success); return outGlyphCount; @@ -268,7 +296,8 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 } #endif - fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, fFontInstance, fFeatureOrder); + fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, fFontInstance, + fFeatureMap, fFeatureMapCount, fFeatureOrder); float xAdjust = 0, yAdjust = 0; diff --git a/Build/source/libs/icu-xetex/layout/OpenTypeLayoutEngine.h b/Build/source/libs/icu-xetex/layout/OpenTypeLayoutEngine.h index 6f9d4839f5b..366f31257e5 100644 --- a/Build/source/libs/icu-xetex/layout/OpenTypeLayoutEngine.h +++ b/Build/source/libs/icu-xetex/layout/OpenTypeLayoutEngine.h @@ -1,8 +1,5 @@ - /* - * %W% %E% - * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved * */ @@ -45,7 +42,7 @@ U_NAMESPACE_BEGIN * * @internal */ -class OpenTypeLayoutEngine : public LayoutEngine +class U_LAYOUT_API OpenTypeLayoutEngine : public LayoutEngine { public: /** @@ -125,6 +122,13 @@ public: */ static UClassID getStaticClassID(); + /** + * The array of language tags, indexed by language code. + * + * @internal + */ + static const LETag languageTags[]; + private: /** @@ -138,29 +142,40 @@ private: */ static const LETag scriptTags[]; +protected: /** - * The array of language tags, indexed by language code. + * A set of "default" features. The default characterProcessing method + * will apply all of these features to every glyph. + * + * @internal */ - static const LETag languageTags[]; + FeatureMask fFeatureMask; -protected: /** - * A list of "default" features. The default characterProcessing method - * will apply all of these tags to every glyph. + * A set of mappings from feature tags to feature masks. These may + * be in the order in which the featues should be applied, but they + * don't need to be. * * @internal */ - const LETag *fFeatureList; + const FeatureMap *fFeatureMap; const le_int32 *fFeatureParamList; /** - * A list of tags in the order in which the features in - * the font should be applied, as opposed to using the - * order of the lookups in the font. + * The length of the feature map. + * + * @internal + */ + le_int32 fFeatureMapCount; + + /** + * <code>TRUE</code> if the features in the + * feature map are in the order in which they + * must be applied. * * @internal */ - const LETag *fFeatureOrder; + le_bool fFeatureOrder; /** * The address of the GSUB table. @@ -208,6 +223,14 @@ protected: LETag fLangSysTag; /** + * <code>TRUE</code> if <code>mapCharsToGlyphs</code> should replace ZWJ / ZWNJ with a glyph + * with no contours. + * + * @internal + */ + le_bool fFilterZeroWidth; + + /** * This method does the OpenType character processing. It assigns the OpenType feature * tags to the characters, and may generate output characters that differ from the input * charcters due to insertions, deletions, or reorderings. In such cases, it will also diff --git a/Build/source/libs/icu-xetex/layout/OpenTypeTables.h b/Build/source/libs/icu-xetex/layout/OpenTypeTables.h index c94a5cbdaa1..510dd019849 100644 --- a/Build/source/libs/icu-xetex/layout/OpenTypeTables.h +++ b/Build/source/libs/icu-xetex/layout/OpenTypeTables.h @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * */ @@ -21,13 +21,14 @@ U_NAMESPACE_BEGIN typedef le_uint16 Offset; typedef le_uint8 ATag[4]; typedef le_uint32 fixed32; +typedef le_uint32 FeatureMask; #define SWAPT(atag) ((LETag) ((atag[0] << 24) + (atag[1] << 16) + (atag[2] << 8) + atag[3])) struct TagAndOffsetRecord { - ATag tag; - Offset offset; + ATag tag; + Offset offset; }; struct GlyphRangeRecord @@ -37,5 +38,11 @@ struct GlyphRangeRecord le_int16 rangeValue; }; +struct FeatureMap +{ + LETag tag; + FeatureMask mask; +}; + U_NAMESPACE_END #endif diff --git a/Build/source/libs/icu-xetex/layout/ScriptAndLanguageTags.cpp b/Build/source/libs/icu-xetex/layout/ScriptAndLanguageTags.cpp index 944769917df..a9171336a68 100644 --- a/Build/source/libs/icu-xetex/layout/ScriptAndLanguageTags.cpp +++ b/Build/source/libs/icu-xetex/layout/ScriptAndLanguageTags.cpp @@ -1,9 +1,11 @@ /* * - * (C) Copyright IBM Corp. 1998-2004. All Rights Reserved. + * (C) Copyright IBM Corp. 1998-2006. All Rights Reserved. * * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * YOU REALLY KNOW WHAT YOU'RE DOING. + * + * Generated on: 08/21/2006 02:35:14 PM HST */ #include "LETypes.h" @@ -20,7 +22,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = { bengScriptTag, /* 'beng' (BENGALI) */ bopoScriptTag, /* 'bopo' (BOPOMOFO) */ cherScriptTag, /* 'cher' (CHEROKEE) */ - qaacScriptTag, /* 'qaac' (COPTIC) */ + coptScriptTag, /* 'copt' (COPTIC) */ cyrlScriptTag, /* 'cyrl' (CYRILLIC) */ dsrtScriptTag, /* 'dsrt' (DESERET) */ devaScriptTag, /* 'deva' (DEVANAGARI) */ @@ -37,7 +39,6 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = { kndaScriptTag, /* 'knda' (KANNADA) */ kanaScriptTag, /* 'kana' (KATAKANA) */ khmrScriptTag, /* 'khmr' (KHMER) */ -/* laooScriptTag,*/ /* 'laoo' (LAO) */ laooScriptTag, /* 'lao ' (LAO) */ latnScriptTag, /* 'latn' (LATIN) */ mlymScriptTag, /* 'mlym' (MALAYALAM) */ @@ -55,7 +56,7 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = { thaiScriptTag, /* 'thai' (THAI) */ tibtScriptTag, /* 'tibt' (TIBETAN) */ cansScriptTag, /* 'cans' (CANADIAN_ABORIGINAL) */ - yiiiScriptTag, /* 'yiii' (YI) */ + yiiiScriptTag, /* 'yi ' (YI) */ tglgScriptTag, /* 'tglg' (TAGALOG) */ hanoScriptTag, /* 'hano' (HANUNOO) */ buhdScriptTag, /* 'buhd' (BUHID) */ @@ -68,7 +69,56 @@ const LETag OpenTypeLayoutEngine::scriptTags[] = { shawScriptTag, /* 'shaw' (SHAVIAN) */ taleScriptTag, /* 'tale' (TAI_LE) */ ugarScriptTag, /* 'ugar' (UGARITIC) */ - hrktScriptTag /* 'hrkt' (KATAKANA_OR_HIRAGANA) */ + hrktScriptTag, /* 'hrkt' (KATAKANA_OR_HIRAGANA) */ + bugiScriptTag, /* 'bugi' (BUGINESE) */ + glagScriptTag, /* 'glag' (GLAGOLITIC) */ + kharScriptTag, /* 'khar' (KHAROSHTHI) */ + syloScriptTag, /* 'sylo' (SYLOTI_NAGRI) */ + taluScriptTag, /* 'talu' (NEW_TAI_LUE) */ + tfngScriptTag, /* 'tfng' (TIFINAGH) */ + xpeoScriptTag, /* 'xpeo' (OLD_PERSIAN) */ + baliScriptTag, /* 'bali' (BALINESE) */ + batkScriptTag, /* 'batk' (BATK) */ + blisScriptTag, /* 'blis' (BLIS) */ + brahScriptTag, /* 'brah' (BRAH) */ + chamScriptTag, /* 'cham' (CHAM) */ + cirtScriptTag, /* 'cirt' (CIRT) */ + cyrsScriptTag, /* 'cyrs' (CYRS) */ + egydScriptTag, /* 'egyd' (EGYD) */ + egyhScriptTag, /* 'egyh' (EGYH) */ + egypScriptTag, /* 'egyp' (EGYP) */ + geokScriptTag, /* 'geok' (GEOK) */ + hansScriptTag, /* 'hans' (HANS) */ + hantScriptTag, /* 'hant' (HANT) */ + hmngScriptTag, /* 'hmng' (HMNG) */ + hungScriptTag, /* 'hung' (HUNG) */ + indsScriptTag, /* 'inds' (INDS) */ + javaScriptTag, /* 'java' (JAVA) */ + kaliScriptTag, /* 'kali' (KALI) */ + latfScriptTag, /* 'latf' (LATF) */ + latgScriptTag, /* 'latg' (LATG) */ + lepcScriptTag, /* 'lepc' (LEPC) */ + linaScriptTag, /* 'lina' (LINA) */ + mandScriptTag, /* 'mand' (MAND) */ + mayaScriptTag, /* 'maya' (MAYA) */ + meroScriptTag, /* 'mero' (MERO) */ + nkooScriptTag, /* 'nko ' (NKO) */ + orkhScriptTag, /* 'orkh' (ORKH) */ + permScriptTag, /* 'perm' (PERM) */ + phagScriptTag, /* 'phag' (PHAGS_PA) */ + phnxScriptTag, /* 'phnx' (PHOENICIAN) */ + plrdScriptTag, /* 'plrd' (PLRD) */ + roroScriptTag, /* 'roro' (RORO) */ + saraScriptTag, /* 'sara' (SARA) */ + syreScriptTag, /* 'syre' (SYRE) */ + syrjScriptTag, /* 'syrj' (SYRJ) */ + syrnScriptTag, /* 'syrn' (SYRN) */ + tengScriptTag, /* 'teng' (TENG) */ + vaiiScriptTag, /* 'vai ' (VAII) */ + vispScriptTag, /* 'visp' (VISP) */ + xsuxScriptTag, /* 'xsux' (CUNEIFORM) */ + zxxxScriptTag, /* 'zxxx' (ZXXX) */ + zzzzScriptTag /* 'zzzz' (UNKNOWN) */ }; const LETag OpenTypeLayoutEngine::languageTags[] = { diff --git a/Build/source/libs/icu-xetex/layout/ScriptAndLanguageTags.h b/Build/source/libs/icu-xetex/layout/ScriptAndLanguageTags.h index 06fa905113d..7fb6f5e65b8 100644 --- a/Build/source/libs/icu-xetex/layout/ScriptAndLanguageTags.h +++ b/Build/source/libs/icu-xetex/layout/ScriptAndLanguageTags.h @@ -1,9 +1,11 @@ /* * - * (C) Copyright IBM Corp. 1998-2004. All Rights Reserved. + * (C) Copyright IBM Corp. 1998-2006. All Rights Reserved. * * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * YOU REALLY KNOW WHAT YOU'RE DOING. + * + * Generated on: 08/21/2006 02:35:14 PM HST */ #ifndef __SCRIPTANDLANGUAGES_H @@ -11,13 +13,13 @@ #include "LETypes.h" -U_NAMESPACE_BEGIN - /** * \file * \internal */ +U_NAMESPACE_BEGIN + const LETag zyyyScriptTag = 0x7A797979; /* 'zyyy' (COMMON) */ const LETag qaaiScriptTag = 0x71616169; /* 'qaai' (INHERITED) */ const LETag arabScriptTag = 0x61726162; /* 'arab' (ARABIC) */ @@ -25,7 +27,7 @@ const LETag armnScriptTag = 0x61726D6E; /* 'armn' (ARMENIAN) */ const LETag bengScriptTag = 0x62656E67; /* 'beng' (BENGALI) */ const LETag bopoScriptTag = 0x626F706F; /* 'bopo' (BOPOMOFO) */ const LETag cherScriptTag = 0x63686572; /* 'cher' (CHEROKEE) */ -const LETag qaacScriptTag = 0x71616163; /* 'qaac' (COPTIC) */ +const LETag coptScriptTag = 0x636F7074; /* 'copt' (COPTIC) */ const LETag cyrlScriptTag = 0x6379726C; /* 'cyrl' (CYRILLIC) */ const LETag dsrtScriptTag = 0x64737274; /* 'dsrt' (DESERET) */ const LETag devaScriptTag = 0x64657661; /* 'deva' (DEVANAGARI) */ @@ -42,7 +44,6 @@ const LETag hiraScriptTag = 0x68697261; /* 'hira' (HIRAGANA) */ const LETag kndaScriptTag = 0x6B6E6461; /* 'knda' (KANNADA) */ const LETag kanaScriptTag = 0x6B616E61; /* 'kana' (KATAKANA) */ const LETag khmrScriptTag = 0x6B686D72; /* 'khmr' (KHMER) */ -/*const LETag laooScriptTag = 0x6C616F6F;*/ /* 'laoo' (LAO) */ const LETag laooScriptTag = 0x6C616F20; /* 'lao ' (LAO) */ const LETag latnScriptTag = 0x6C61746E; /* 'latn' (LATIN) */ const LETag mlymScriptTag = 0x6D6C796D; /* 'mlym' (MALAYALAM) */ @@ -60,7 +61,7 @@ const LETag thaaScriptTag = 0x74686161; /* 'thaa' (THAANA) */ const LETag thaiScriptTag = 0x74686169; /* 'thai' (THAI) */ const LETag tibtScriptTag = 0x74696274; /* 'tibt' (TIBETAN) */ const LETag cansScriptTag = 0x63616E73; /* 'cans' (CANADIAN_ABORIGINAL) */ -const LETag yiiiScriptTag = 0x79696969; /* 'yiii' (YI) */ +const LETag yiiiScriptTag = 0x79692020; /* 'yi ' (YI) */ const LETag tglgScriptTag = 0x74676C67; /* 'tglg' (TAGALOG) */ const LETag hanoScriptTag = 0x68616E6F; /* 'hano' (HANUNOO) */ const LETag buhdScriptTag = 0x62756864; /* 'buhd' (BUHID) */ @@ -74,6 +75,55 @@ const LETag shawScriptTag = 0x73686177; /* 'shaw' (SHAVIAN) */ const LETag taleScriptTag = 0x74616C65; /* 'tale' (TAI_LE) */ const LETag ugarScriptTag = 0x75676172; /* 'ugar' (UGARITIC) */ const LETag hrktScriptTag = 0x68726B74; /* 'hrkt' (KATAKANA_OR_HIRAGANA) */ +const LETag bugiScriptTag = 0x62756769; /* 'bugi' (BUGINESE) */ +const LETag glagScriptTag = 0x676C6167; /* 'glag' (GLAGOLITIC) */ +const LETag kharScriptTag = 0x6B686172; /* 'khar' (KHAROSHTHI) */ +const LETag syloScriptTag = 0x73796C6F; /* 'sylo' (SYLOTI_NAGRI) */ +const LETag taluScriptTag = 0x74616C75; /* 'talu' (NEW_TAI_LUE) */ +const LETag tfngScriptTag = 0x74666E67; /* 'tfng' (TIFINAGH) */ +const LETag xpeoScriptTag = 0x7870656F; /* 'xpeo' (OLD_PERSIAN) */ +const LETag baliScriptTag = 0x62616C69; /* 'bali' (BALINESE) */ +const LETag batkScriptTag = 0x6261746B; /* 'batk' (BATK) */ +const LETag blisScriptTag = 0x626C6973; /* 'blis' (BLIS) */ +const LETag brahScriptTag = 0x62726168; /* 'brah' (BRAH) */ +const LETag chamScriptTag = 0x6368616D; /* 'cham' (CHAM) */ +const LETag cirtScriptTag = 0x63697274; /* 'cirt' (CIRT) */ +const LETag cyrsScriptTag = 0x63797273; /* 'cyrs' (CYRS) */ +const LETag egydScriptTag = 0x65677964; /* 'egyd' (EGYD) */ +const LETag egyhScriptTag = 0x65677968; /* 'egyh' (EGYH) */ +const LETag egypScriptTag = 0x65677970; /* 'egyp' (EGYP) */ +const LETag geokScriptTag = 0x67656F6B; /* 'geok' (GEOK) */ +const LETag hansScriptTag = 0x68616E73; /* 'hans' (HANS) */ +const LETag hantScriptTag = 0x68616E74; /* 'hant' (HANT) */ +const LETag hmngScriptTag = 0x686D6E67; /* 'hmng' (HMNG) */ +const LETag hungScriptTag = 0x68756E67; /* 'hung' (HUNG) */ +const LETag indsScriptTag = 0x696E6473; /* 'inds' (INDS) */ +const LETag javaScriptTag = 0x6A617661; /* 'java' (JAVA) */ +const LETag kaliScriptTag = 0x6B616C69; /* 'kali' (KALI) */ +const LETag latfScriptTag = 0x6C617466; /* 'latf' (LATF) */ +const LETag latgScriptTag = 0x6C617467; /* 'latg' (LATG) */ +const LETag lepcScriptTag = 0x6C657063; /* 'lepc' (LEPC) */ +const LETag linaScriptTag = 0x6C696E61; /* 'lina' (LINA) */ +const LETag mandScriptTag = 0x6D616E64; /* 'mand' (MAND) */ +const LETag mayaScriptTag = 0x6D617961; /* 'maya' (MAYA) */ +const LETag meroScriptTag = 0x6D65726F; /* 'mero' (MERO) */ +const LETag nkooScriptTag = 0x6E6B6F20; /* 'nko ' (NKO) */ +const LETag orkhScriptTag = 0x6F726B68; /* 'orkh' (ORKH) */ +const LETag permScriptTag = 0x7065726D; /* 'perm' (PERM) */ +const LETag phagScriptTag = 0x70686167; /* 'phag' (PHAGS_PA) */ +const LETag phnxScriptTag = 0x70686E78; /* 'phnx' (PHOENICIAN) */ +const LETag plrdScriptTag = 0x706C7264; /* 'plrd' (PLRD) */ +const LETag roroScriptTag = 0x726F726F; /* 'roro' (RORO) */ +const LETag saraScriptTag = 0x73617261; /* 'sara' (SARA) */ +const LETag syreScriptTag = 0x73797265; /* 'syre' (SYRE) */ +const LETag syrjScriptTag = 0x7379726A; /* 'syrj' (SYRJ) */ +const LETag syrnScriptTag = 0x7379726E; /* 'syrn' (SYRN) */ +const LETag tengScriptTag = 0x74656E67; /* 'teng' (TENG) */ +const LETag vaiiScriptTag = 0x76616920; /* 'vai ' (VAII) */ +const LETag vispScriptTag = 0x76697370; /* 'visp' (VISP) */ +const LETag xsuxScriptTag = 0x78737578; /* 'xsux' (CUNEIFORM) */ +const LETag zxxxScriptTag = 0x7A787878; /* 'zxxx' (ZXXX) */ +const LETag zzzzScriptTag = 0x7A7A7A7A; /* 'zzzz' (UNKNOWN) */ const LETag nullScriptTag = 0x00000000; /* '' (NULL) */ diff --git a/Build/source/libs/icu-xetex/layout/ShapingTypeData.cpp b/Build/source/libs/icu-xetex/layout/ShapingTypeData.cpp new file mode 100644 index 00000000000..36d5d4b53e5 --- /dev/null +++ b/Build/source/libs/icu-xetex/layout/ShapingTypeData.cpp @@ -0,0 +1,208 @@ +/* + * + * (C) Copyright SIL International. 2007. + * (C) Copyright IBM Corp. 1998-2005. + * Based on code distributed with ICU 3.6 + * and the Unicode Character Database, version 5.0.0 + * + * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS + * YOU REALLY KNOW WHAT YOU'RE DOING. + * + * Generated on: 2007-01-16 12:28:32 GMT + + */ + +#include "LETypes.h" +#include "ArabicShaping.h" + +U_NAMESPACE_BEGIN + +const le_uint8 ArabicShaping::shapingTypeTable[] = { + 0x00, 0x02, /* classFormat */ + 0x00, 0xB7, /* classRangeCount */ + 0x00, 0xAD, 0x00, 0xAD, 0x00, 0x05, + 0x03, 0x00, 0x03, 0x6F, 0x00, 0x05, + 0x04, 0x83, 0x04, 0x86, 0x00, 0x05, + 0x04, 0x88, 0x04, 0x89, 0x00, 0x05, + 0x05, 0x91, 0x05, 0xBD, 0x00, 0x05, + 0x05, 0xBF, 0x05, 0xBF, 0x00, 0x05, + 0x05, 0xC1, 0x05, 0xC2, 0x00, 0x05, + 0x05, 0xC4, 0x05, 0xC5, 0x00, 0x05, + 0x05, 0xC7, 0x05, 0xC7, 0x00, 0x05, + 0x06, 0x10, 0x06, 0x15, 0x00, 0x05, + 0x06, 0x22, 0x06, 0x25, 0x00, 0x04, + 0x06, 0x26, 0x06, 0x26, 0x00, 0x02, + 0x06, 0x27, 0x06, 0x27, 0x00, 0x04, + 0x06, 0x28, 0x06, 0x28, 0x00, 0x02, + 0x06, 0x29, 0x06, 0x29, 0x00, 0x04, + 0x06, 0x2A, 0x06, 0x2E, 0x00, 0x02, + 0x06, 0x2F, 0x06, 0x32, 0x00, 0x04, + 0x06, 0x33, 0x06, 0x3A, 0x00, 0x02, + 0x06, 0x40, 0x06, 0x40, 0x00, 0x01, + 0x06, 0x41, 0x06, 0x47, 0x00, 0x02, + 0x06, 0x48, 0x06, 0x48, 0x00, 0x04, + 0x06, 0x49, 0x06, 0x4A, 0x00, 0x02, + 0x06, 0x4B, 0x06, 0x5E, 0x00, 0x05, + 0x06, 0x6E, 0x06, 0x6F, 0x00, 0x02, + 0x06, 0x70, 0x06, 0x70, 0x00, 0x05, + 0x06, 0x71, 0x06, 0x73, 0x00, 0x04, + 0x06, 0x75, 0x06, 0x77, 0x00, 0x04, + 0x06, 0x78, 0x06, 0x87, 0x00, 0x02, + 0x06, 0x88, 0x06, 0x99, 0x00, 0x04, + 0x06, 0x9A, 0x06, 0xBF, 0x00, 0x02, + 0x06, 0xC0, 0x06, 0xC0, 0x00, 0x04, + 0x06, 0xC1, 0x06, 0xC2, 0x00, 0x02, + 0x06, 0xC3, 0x06, 0xCB, 0x00, 0x04, + 0x06, 0xCC, 0x06, 0xCC, 0x00, 0x02, + 0x06, 0xCD, 0x06, 0xCD, 0x00, 0x04, + 0x06, 0xCE, 0x06, 0xCE, 0x00, 0x02, + 0x06, 0xCF, 0x06, 0xCF, 0x00, 0x04, + 0x06, 0xD0, 0x06, 0xD1, 0x00, 0x02, + 0x06, 0xD2, 0x06, 0xD3, 0x00, 0x04, + 0x06, 0xD5, 0x06, 0xD5, 0x00, 0x04, + 0x06, 0xD6, 0x06, 0xDC, 0x00, 0x05, + 0x06, 0xDE, 0x06, 0xE4, 0x00, 0x05, + 0x06, 0xE7, 0x06, 0xE8, 0x00, 0x05, + 0x06, 0xEA, 0x06, 0xED, 0x00, 0x05, + 0x06, 0xEE, 0x06, 0xEF, 0x00, 0x04, + 0x06, 0xFA, 0x06, 0xFC, 0x00, 0x02, + 0x06, 0xFF, 0x06, 0xFF, 0x00, 0x02, + 0x07, 0x0F, 0x07, 0x0F, 0x00, 0x05, + 0x07, 0x10, 0x07, 0x10, 0x00, 0x04, + 0x07, 0x11, 0x07, 0x11, 0x00, 0x05, + 0x07, 0x12, 0x07, 0x14, 0x00, 0x02, + 0x07, 0x15, 0x07, 0x19, 0x00, 0x04, + 0x07, 0x1A, 0x07, 0x1D, 0x00, 0x02, + 0x07, 0x1E, 0x07, 0x1E, 0x00, 0x04, + 0x07, 0x1F, 0x07, 0x27, 0x00, 0x02, + 0x07, 0x28, 0x07, 0x28, 0x00, 0x04, + 0x07, 0x29, 0x07, 0x29, 0x00, 0x02, + 0x07, 0x2A, 0x07, 0x2A, 0x00, 0x04, + 0x07, 0x2B, 0x07, 0x2B, 0x00, 0x02, + 0x07, 0x2C, 0x07, 0x2C, 0x00, 0x04, + 0x07, 0x2D, 0x07, 0x2E, 0x00, 0x02, + 0x07, 0x2F, 0x07, 0x2F, 0x00, 0x04, + 0x07, 0x30, 0x07, 0x4A, 0x00, 0x05, + 0x07, 0x4D, 0x07, 0x4D, 0x00, 0x04, + 0x07, 0x4E, 0x07, 0x58, 0x00, 0x02, + 0x07, 0x59, 0x07, 0x5B, 0x00, 0x04, + 0x07, 0x5C, 0x07, 0x6A, 0x00, 0x02, + 0x07, 0x6B, 0x07, 0x6C, 0x00, 0x04, + 0x07, 0x6D, 0x07, 0x6D, 0x00, 0x02, + 0x07, 0xA6, 0x07, 0xB0, 0x00, 0x05, + 0x07, 0xCA, 0x07, 0xEA, 0x00, 0x02, + 0x07, 0xEB, 0x07, 0xF3, 0x00, 0x05, + 0x07, 0xFA, 0x07, 0xFA, 0x00, 0x01, + 0x09, 0x01, 0x09, 0x02, 0x00, 0x05, + 0x09, 0x3C, 0x09, 0x3C, 0x00, 0x05, + 0x09, 0x41, 0x09, 0x48, 0x00, 0x05, + 0x09, 0x4D, 0x09, 0x4D, 0x00, 0x05, + 0x09, 0x51, 0x09, 0x54, 0x00, 0x05, + 0x09, 0x62, 0x09, 0x63, 0x00, 0x05, + 0x09, 0x81, 0x09, 0x81, 0x00, 0x05, + 0x09, 0xBC, 0x09, 0xBC, 0x00, 0x05, + 0x09, 0xC1, 0x09, 0xC4, 0x00, 0x05, + 0x09, 0xCD, 0x09, 0xCD, 0x00, 0x05, + 0x09, 0xE2, 0x09, 0xE3, 0x00, 0x05, + 0x0A, 0x01, 0x0A, 0x02, 0x00, 0x05, + 0x0A, 0x3C, 0x0A, 0x3C, 0x00, 0x05, + 0x0A, 0x41, 0x0A, 0x42, 0x00, 0x05, + 0x0A, 0x47, 0x0A, 0x48, 0x00, 0x05, + 0x0A, 0x4B, 0x0A, 0x4D, 0x00, 0x05, + 0x0A, 0x70, 0x0A, 0x71, 0x00, 0x05, + 0x0A, 0x81, 0x0A, 0x82, 0x00, 0x05, + 0x0A, 0xBC, 0x0A, 0xBC, 0x00, 0x05, + 0x0A, 0xC1, 0x0A, 0xC5, 0x00, 0x05, + 0x0A, 0xC7, 0x0A, 0xC8, 0x00, 0x05, + 0x0A, 0xCD, 0x0A, 0xCD, 0x00, 0x05, + 0x0A, 0xE2, 0x0A, 0xE3, 0x00, 0x05, + 0x0B, 0x01, 0x0B, 0x01, 0x00, 0x05, + 0x0B, 0x3C, 0x0B, 0x3C, 0x00, 0x05, + 0x0B, 0x3F, 0x0B, 0x3F, 0x00, 0x05, + 0x0B, 0x41, 0x0B, 0x43, 0x00, 0x05, + 0x0B, 0x4D, 0x0B, 0x4D, 0x00, 0x05, + 0x0B, 0x56, 0x0B, 0x56, 0x00, 0x05, + 0x0B, 0x82, 0x0B, 0x82, 0x00, 0x05, + 0x0B, 0xC0, 0x0B, 0xC0, 0x00, 0x05, + 0x0B, 0xCD, 0x0B, 0xCD, 0x00, 0x05, + 0x0C, 0x3E, 0x0C, 0x40, 0x00, 0x05, + 0x0C, 0x46, 0x0C, 0x48, 0x00, 0x05, + 0x0C, 0x4A, 0x0C, 0x4D, 0x00, 0x05, + 0x0C, 0x55, 0x0C, 0x56, 0x00, 0x05, + 0x0C, 0xBC, 0x0C, 0xBC, 0x00, 0x05, + 0x0C, 0xBF, 0x0C, 0xBF, 0x00, 0x05, + 0x0C, 0xC6, 0x0C, 0xC6, 0x00, 0x05, + 0x0C, 0xCC, 0x0C, 0xCD, 0x00, 0x05, + 0x0C, 0xE2, 0x0C, 0xE3, 0x00, 0x05, + 0x0D, 0x41, 0x0D, 0x43, 0x00, 0x05, + 0x0D, 0x4D, 0x0D, 0x4D, 0x00, 0x05, + 0x0D, 0xCA, 0x0D, 0xCA, 0x00, 0x05, + 0x0D, 0xD2, 0x0D, 0xD4, 0x00, 0x05, + 0x0D, 0xD6, 0x0D, 0xD6, 0x00, 0x05, + 0x0E, 0x31, 0x0E, 0x31, 0x00, 0x05, + 0x0E, 0x34, 0x0E, 0x3A, 0x00, 0x05, + 0x0E, 0x47, 0x0E, 0x4E, 0x00, 0x05, + 0x0E, 0xB1, 0x0E, 0xB1, 0x00, 0x05, + 0x0E, 0xB4, 0x0E, 0xB9, 0x00, 0x05, + 0x0E, 0xBB, 0x0E, 0xBC, 0x00, 0x05, + 0x0E, 0xC8, 0x0E, 0xCD, 0x00, 0x05, + 0x0F, 0x18, 0x0F, 0x19, 0x00, 0x05, + 0x0F, 0x35, 0x0F, 0x35, 0x00, 0x05, + 0x0F, 0x37, 0x0F, 0x37, 0x00, 0x05, + 0x0F, 0x39, 0x0F, 0x39, 0x00, 0x05, + 0x0F, 0x71, 0x0F, 0x7E, 0x00, 0x05, + 0x0F, 0x80, 0x0F, 0x84, 0x00, 0x05, + 0x0F, 0x86, 0x0F, 0x87, 0x00, 0x05, + 0x0F, 0x90, 0x0F, 0x97, 0x00, 0x05, + 0x0F, 0x99, 0x0F, 0xBC, 0x00, 0x05, + 0x0F, 0xC6, 0x0F, 0xC6, 0x00, 0x05, + 0x10, 0x2D, 0x10, 0x30, 0x00, 0x05, + 0x10, 0x32, 0x10, 0x32, 0x00, 0x05, + 0x10, 0x36, 0x10, 0x37, 0x00, 0x05, + 0x10, 0x39, 0x10, 0x39, 0x00, 0x05, + 0x10, 0x58, 0x10, 0x59, 0x00, 0x05, + 0x13, 0x5F, 0x13, 0x5F, 0x00, 0x05, + 0x17, 0x12, 0x17, 0x14, 0x00, 0x05, + 0x17, 0x32, 0x17, 0x34, 0x00, 0x05, + 0x17, 0x52, 0x17, 0x53, 0x00, 0x05, + 0x17, 0x72, 0x17, 0x73, 0x00, 0x05, + 0x17, 0xB4, 0x17, 0xB5, 0x00, 0x05, + 0x17, 0xB7, 0x17, 0xBD, 0x00, 0x05, + 0x17, 0xC6, 0x17, 0xC6, 0x00, 0x05, + 0x17, 0xC9, 0x17, 0xD3, 0x00, 0x05, + 0x17, 0xDD, 0x17, 0xDD, 0x00, 0x05, + 0x18, 0x0B, 0x18, 0x0D, 0x00, 0x05, + 0x18, 0xA9, 0x18, 0xA9, 0x00, 0x05, + 0x19, 0x20, 0x19, 0x22, 0x00, 0x05, + 0x19, 0x27, 0x19, 0x28, 0x00, 0x05, + 0x19, 0x32, 0x19, 0x32, 0x00, 0x05, + 0x19, 0x39, 0x19, 0x3B, 0x00, 0x05, + 0x1A, 0x17, 0x1A, 0x18, 0x00, 0x05, + 0x1B, 0x00, 0x1B, 0x03, 0x00, 0x05, + 0x1B, 0x34, 0x1B, 0x34, 0x00, 0x05, + 0x1B, 0x36, 0x1B, 0x3A, 0x00, 0x05, + 0x1B, 0x3C, 0x1B, 0x3C, 0x00, 0x05, + 0x1B, 0x42, 0x1B, 0x42, 0x00, 0x05, + 0x1B, 0x6B, 0x1B, 0x73, 0x00, 0x05, + 0x1D, 0xC0, 0x1D, 0xCA, 0x00, 0x05, + 0x1D, 0xFE, 0x1D, 0xFF, 0x00, 0x05, + 0x20, 0x0B, 0x20, 0x0B, 0x00, 0x05, + 0x20, 0x0D, 0x20, 0x0D, 0x00, 0x01, + 0x20, 0x0E, 0x20, 0x0F, 0x00, 0x05, + 0x20, 0x2A, 0x20, 0x2E, 0x00, 0x05, + 0x20, 0x60, 0x20, 0x63, 0x00, 0x05, + 0x20, 0x6A, 0x20, 0x6F, 0x00, 0x05, + 0x20, 0xD0, 0x20, 0xEF, 0x00, 0x05, + 0x30, 0x2A, 0x30, 0x2F, 0x00, 0x05, + 0x30, 0x99, 0x30, 0x9A, 0x00, 0x05, + 0xA8, 0x06, 0xA8, 0x06, 0x00, 0x05, + 0xA8, 0x0B, 0xA8, 0x0B, 0x00, 0x05, + 0xA8, 0x25, 0xA8, 0x26, 0x00, 0x05, + 0xFB, 0x1E, 0xFB, 0x1E, 0x00, 0x05, + 0xFE, 0x00, 0xFE, 0x0F, 0x00, 0x05, + 0xFE, 0x20, 0xFE, 0x23, 0x00, 0x05, + 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x05, + 0xFF, 0xF9, 0xFF, 0xFB, 0x00, 0x05 +}; + +U_NAMESPACE_END diff --git a/Build/source/libs/icu-xetex/layout/ThaiLayoutEngine.cpp b/Build/source/libs/icu-xetex/layout/ThaiLayoutEngine.cpp index 824c95d1c35..38f8a3275ce 100644 --- a/Build/source/libs/icu-xetex/layout/ThaiLayoutEngine.cpp +++ b/Build/source/libs/icu-xetex/layout/ThaiLayoutEngine.cpp @@ -83,7 +83,7 @@ le_int32 ThaiLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offse } glyphCount = ThaiShaping::compose(chars, offset, count, fGlyphSet, fErrorChar, outChars, glyphStorage); - mapCharsToGlyphs(outChars, 0, glyphCount, FALSE, FALSE, glyphStorage, success); + mapCharsToGlyphs(outChars, 0, glyphCount, FALSE, FALSE, TRUE, glyphStorage, success); LE_DELETE_ARRAY(outChars); diff --git a/Build/source/libs/icu-xetex/layout/TibetanLayoutEngine.cpp b/Build/source/libs/icu-xetex/layout/TibetanLayoutEngine.cpp new file mode 100644 index 00000000000..be97ab5baf4 --- /dev/null +++ b/Build/source/libs/icu-xetex/layout/TibetanLayoutEngine.cpp @@ -0,0 +1,87 @@ +/* + * + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * + * Developed at DIT - Government of Bhutan + * + * Contact person: Pema Geyleg - <pema_geyleg@druknet.bt> + * + * This file is a modification of the ICU file KhmerReordering.cpp + * by Jens Herden and Javier Sola who have given all their possible rights to IBM and the Governement of Bhutan + * A first module for Dzongkha was developed by Karunakar under Panlocalisation funding. + * Assistance for this module has been received from Namgay Thinley, Christopher Fynn and Javier Sola + * + */ + + +#include "OpenTypeLayoutEngine.h" +#include "TibetanLayoutEngine.h" +#include "LEGlyphStorage.h" +#include "TibetanReordering.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TibetanOpenTypeLayoutEngine) + +TibetanOpenTypeLayoutEngine::TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, + le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) + : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable) +{ + fFeatureMap = TibetanReordering::getFeatureMap(fFeatureMapCount); + fFeatureOrder = TRUE; +} + +TibetanOpenTypeLayoutEngine::TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, + le_int32 typoFlags) + : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags) +{ + fFeatureMap = TibetanReordering::getFeatureMap(fFeatureMapCount); + fFeatureOrder = TRUE; +} + +TibetanOpenTypeLayoutEngine::~TibetanOpenTypeLayoutEngine() +{ + // nothing to do +} + +// Input: characters +// Output: characters, char indices, tags +// Returns: output character count +le_int32 TibetanOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, + LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success) +{ + if (LE_FAILURE(success)) { + return 0; + } + + if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { + success = LE_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + le_int32 worstCase = count * 3; // worst case is 3 for Khmer TODO check if 2 is enough + + outChars = LE_NEW_ARRAY(LEUnicode, worstCase); + + if (outChars == NULL) { + success = LE_MEMORY_ALLOCATION_ERROR; + return 0; + } + + glyphStorage.allocateGlyphArray(worstCase, rightToLeft, success); + glyphStorage.allocateAuxData(success); + + if (LE_FAILURE(success)) { + LE_DELETE_ARRAY(outChars); + return 0; + } + + // NOTE: assumes this allocates featureTags... + // (probably better than doing the worst case stuff here...) + le_int32 outCharCount = TibetanReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage); + + glyphStorage.adoptGlyphCount(outCharCount); + return outCharCount; +} + +U_NAMESPACE_END diff --git a/Build/source/libs/icu-xetex/layout/TibetanLayoutEngine.h b/Build/source/libs/icu-xetex/layout/TibetanLayoutEngine.h new file mode 100644 index 00000000000..9deb4f0241a --- /dev/null +++ b/Build/source/libs/icu-xetex/layout/TibetanLayoutEngine.h @@ -0,0 +1,129 @@ +/* + * + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * + * Developed at DIT - Government of Bhutan + * + * Contact person: Pema Geyleg - <pema_geyleg@druknet.bt> + * + * This file is a modification of the ICU file KhmerReordering.cpp + * by Jens Herden and Javier Sola who have given all their possible rights to IBM and the Governement of Bhutan + * A first module for Dzongkha was developed by Karunakar under Panlocalisation funding. + * Assistance for this module has been received from Namgay Thinley, Christopher Fynn and Javier Sola + * + */ + +#ifndef __TIBETANLAYOUTENGINE_H +#define __TIBETANLAYOUTENGINE_H + +// #include "LETypes.h" +// #include "LEFontInstance.h" +// #include "LEGlyphFilter.h" +// #include "LayoutEngine.h" +// #include "OpenTypeLayoutEngine.h" + +// #include "GlyphSubstitutionTables.h" +// #include "GlyphDefinitionTables.h" +// #include "GlyphPositioningTables.h" + +U_NAMESPACE_BEGIN + +// class MPreFixups; +// class LEGlyphStorage; + +/** + * This class implements OpenType layout for Dzongkha and Tibetan OpenType fonts + * + * @internal + */ +class TibetanOpenTypeLayoutEngine : public OpenTypeLayoutEngine +{ +public: + /** + * This is the main constructor. It constructs an instance of TibetanOpenTypeLayoutEngine for + * a particular font, script and language. It takes the GSUB table as a parameter since + * LayoutEngine::layoutEngineFactory has to read the GSUB table to know that it has an + * Tibetan OpenType font. + * + * @param fontInstance - the font + * @param scriptCode - the script + * @param langaugeCode - the language + * @param gsubTable - the GSUB table + * + * @see LayoutEngine::layoutEngineFactory + * @see OpenTypeLayoutEngine + * @see ScriptAndLangaugeTags.h for script and language codes + * + * @internal + */ + TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, + le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable); + + /** + * This constructor is used when the font requires a "canned" GSUB table which can't be known + * until after this constructor has been invoked. + * + * @param fontInstance - the font + * @param scriptCode - the script + * @param langaugeCode - the language + * + * @see OpenTypeLayoutEngine + * @see ScriptAndLangaugeTags.h for script and language codes + * + * @internal + */ + TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, + le_int32 typoFlags); + + /** + * The destructor, virtual for correct polymorphic invocation. + * + * @internal + */ + virtual ~TibetanOpenTypeLayoutEngine(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @draft ICU 3.6 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @draft ICU 3.6 + */ + static UClassID getStaticClassID(); + +protected: + + /** + * This method does Tibetan OpenType character processing. It assigns the OpenType feature + * tags to the characters, and may generate output characters which have been reordered. + * It may also split some vowels, resulting in more output characters than input characters. + * + * Input parameters: + * @param chars - the input character context + * @param offset - the index of the first character to process + * @param count - the number of characters to process + * @param max - the number of characters in the input context + * @param rightToLeft - <code>TRUE</code> if the characters are in a right to left directional run + * @param glyphStorage - the glyph storage object. The glyph and character index arrays will be set. + * the auxillary data array will be set to the feature tags. + * + * Output parameters: + * @param success - set to an error code if the operation fails + * + * @return the output character count + * + * @internal + */ + virtual le_int32 characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, + LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success); + +}; + +U_NAMESPACE_END +#endif + diff --git a/Build/source/libs/icu-xetex/layout/TibetanReordering.cpp b/Build/source/libs/icu-xetex/layout/TibetanReordering.cpp new file mode 100644 index 00000000000..e7035126b68 --- /dev/null +++ b/Build/source/libs/icu-xetex/layout/TibetanReordering.cpp @@ -0,0 +1,381 @@ +/* + * + * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved + * + * Developed at DIT - Government of Bhutan + * + * Contact person: Pema Geyleg - <pema_geyleg@druknet.bt> + * + * This file is a modification of the ICU file KhmerReordering.cpp + * by Jens Herden and Javier Sola who have given all their possible rights to IBM and the Governement of Bhutan + * A first module for Dzongkha was developed by Karunakar under Panlocalisation funding. + * Assistance for this module has been received from Namgay Thinley, Christopher Fynn and Javier Sola + * + */ + +//#include <stdio.h> +#include "LETypes.h" +#include "OpenTypeTables.h" +#include "TibetanReordering.h" +#include "LEGlyphStorage.h" + + +U_NAMESPACE_BEGIN + +// Characters that get refered to by name... +enum +{ + C_DOTTED_CIRCLE = 0x25CC, + C_PRE_NUMBER_MARK = 0x0F3F + }; + + +enum +{ + // simple classes, they are used in the statetable (in this file) to control the length of a syllable + // they are also used to know where a character should be placed (location in reference to the base character) + // and also to know if a character, when independtly displayed, should be displayed with a dotted-circle to + // indicate error in syllable construction + _xx = TibetanClassTable::CC_RESERVED, + _ba = TibetanClassTable::CC_BASE, + _sj = TibetanClassTable::CC_SUBJOINED | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW, + _tp = TibetanClassTable::CC_TSA_PHRU | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_ABOVE, + _ac = TibetanClassTable::CC_A_CHUNG | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW, + _cs = TibetanClassTable::CC_COMP_SANSKRIT | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW, + _ha = TibetanClassTable::CC_HALANTA | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW, + _bv = TibetanClassTable::CC_BELOW_VOWEL | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW, + _av = TibetanClassTable::CC_ABOVE_VOWEL | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_ABOVE, + _an = TibetanClassTable::CC_ANUSVARA | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_ABOVE, + _cb = TibetanClassTable::CC_CANDRABINDU | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_ABOVE, + _vs = TibetanClassTable::CC_VISARGA | TibetanClassTable::CF_DOTTED_CIRCLE| TibetanClassTable::CF_POS_AFTER, + _as = TibetanClassTable::CC_ABOVE_S_MARK | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_ABOVE, + _bs = TibetanClassTable::CC_BELOW_S_MARK | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_BELOW, + _di = TibetanClassTable::CC_DIGIT | TibetanClassTable::CF_DIGIT, + _pd = TibetanClassTable::CC_PRE_DIGIT_MARK | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_PREDIGIT | TibetanClassTable::CF_POS_BEFORE , + _bd = TibetanClassTable::CC_POST_BELOW_DIGIT_M | TibetanClassTable::CF_DOTTED_CIRCLE | TibetanClassTable::CF_POS_AFTER +}; + + +// Character class tables +//_xx Non Combining characters +//_ba Base Consonants +//_sj Subjoined consonants +//_tp Tsa - phru +//_ac A-chung, Vowel Lengthening mark +//_cs Precomposed Sanskrit vowel + subjoined consonants +//_ha Halanta/Virama +//_bv Below vowel +//_av above vowel +//_an Anusvara +//_cb Candrabindu +//_vs Visaraga/Post mark +//_as Upper Stress marks +//_bs Lower Stress marks +//_di Digit +//_pd Number pre combining, Needs reordering +//_bd Other number combining marks + +static const TibetanClassTable::CharClass tibetanCharClasses[] = +{ + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + _xx, _ba, _xx, _xx, _ba, _ba, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0F00 - 0F0F 0 + _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _bd, _bd, _xx, _xx, _xx, _xx, _xx, _xx, // 0F10 - 0F1F 1 + _di, _di, _di, _di, _di, _di, _di, _di, _di, _di, _xx, _xx, _xx, _xx, _xx, _xx, // 0F20 - 0F2F 2 + _xx, _xx, _xx, _xx, _xx, _bs, _xx, _bs, _xx, _tp, _xx, _xx, _xx, _xx, _bd, _pd, // 0F30 - 0F3F 3 + _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _xx, _ba, _ba, _ba, _ba, _ba, _ba, _ba, // 0F40 - 0F4F 4 + _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, // 0F50 - 0F5F 5 + _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _ba, _xx, _xx, _xx, _xx, _xx, // 0F60 - 0F6F 6 + _xx, _ac, _av, _cs, _bv, _bv, _cs, _cs, _cs, _cs, _av, _av, _av, _av, _an, _vs, // 0F70 - 0F7F 7 + _av, _cs, _cb, _cb, _ha, _xx, _as, _as, _ba, _ba, _ba, _ba, _xx, _xx, _xx, _xx, // 0F80 - 0F8F 8 + _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _xx, _sj, _sj, _sj, _sj, _sj, _sj, _sj, // 0F90 - 0F9F 9 + _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, // 0FA0 - 0FAF a + _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _sj, _xx, _sj, _sj, // 0FB0 - 0FBF b + _xx, _xx, _xx, _xx, _xx, _xx, _bs, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0FC0 - 0FCF c + _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx,// 0FD0 - 0FDF d + _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0FE0 - 0FEF e + _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0FF0 - 0FFF f +}; + + +// +// Tibetan Class Tables +// + +// +// The range of characters defined in the above table is defined here. For Tibetan 0F00 to 0FFF +// Even if the Tibetan range is bigger, most of the characters are not combinable, and therefore treated +// as _xx +static const TibetanClassTable tibetanClassTable = {0x0F00, 0x0FFF, tibetanCharClasses}; + + +// Below we define how a character in the input string is either in the tibetanCharClasses table +// (in which case we get its type back), or an unknown object in which case we get _xx (CC_RESERVED) back +TibetanClassTable::CharClass TibetanClassTable::getCharClass(LEUnicode ch) const +{ + if (ch < firstChar || ch > lastChar) { + return CC_RESERVED; + } + + return classTable[ch - firstChar]; +} + +const TibetanClassTable *TibetanClassTable::getTibetanClassTable() +{ + return &tibetanClassTable; +} + + + +class TibetanReorderingOutput : public UMemory { +private: + le_int32 fOutIndex; + LEUnicode *fOutChars; + + LEGlyphStorage &fGlyphStorage; + + +public: + TibetanReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage) + : fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage) + { + // nothing else to do... + } + + ~TibetanReorderingOutput() + { + // nothing to do here... + } + + void writeChar(LEUnicode ch, le_uint32 charIndex, FeatureMask featureMask) + { + LEErrorCode success = LE_NO_ERROR; + + fOutChars[fOutIndex] = ch; + + fGlyphStorage.setCharIndex(fOutIndex, charIndex, success); + fGlyphStorage.setAuxData(fOutIndex, featureMask, NULL, success); + + fOutIndex += 1; + } + + le_int32 getOutputIndex() + { + return fOutIndex; + } +}; + + +//TODO remove unused flags +#define ccmpFeatureTag LE_CCMP_FEATURE_TAG +#define blwfFeatureTag LE_BLWF_FEATURE_TAG +#define pstfFeatureTag LE_PSTF_FEATURE_TAG +#define presFeatureTag LE_PRES_FEATURE_TAG +#define blwsFeatureTag LE_BLWS_FEATURE_TAG +#define abvsFeatureTag LE_ABVS_FEATURE_TAG +#define pstsFeatureTag LE_PSTS_FEATURE_TAG + +#define blwmFeatureTag LE_BLWM_FEATURE_TAG +#define abvmFeatureTag LE_ABVM_FEATURE_TAG +#define distFeatureTag LE_DIST_FEATURE_TAG + +#define prefFeatureTag LE_PREF_FEATURE_TAG +#define abvfFeatureTag LE_ABVF_FEATURE_TAG +#define cligFeatureTag LE_CLIG_FEATURE_TAG +#define mkmkFeatureTag LE_MKMK_FEATURE_TAG + +// Shaping features +#define prefFeatureMask 0x80000000UL +#define blwfFeatureMask 0x40000000UL +#define abvfFeatureMask 0x20000000UL +#define pstfFeatureMask 0x10000000UL +#define presFeatureMask 0x08000000UL +#define blwsFeatureMask 0x04000000UL +#define abvsFeatureMask 0x02000000UL +#define pstsFeatureMask 0x01000000UL +#define cligFeatureMask 0x00800000UL +#define ccmpFeatureMask 0x00040000UL + +// Positioning features +#define distFeatureMask 0x00400000UL +#define blwmFeatureMask 0x00200000UL +#define abvmFeatureMask 0x00100000UL +#define mkmkFeatureMask 0x00080000UL + +#define tagPref (ccmpFeatureMask | prefFeatureMask | presFeatureMask | cligFeatureMask | distFeatureMask) +#define tagAbvf (ccmpFeatureMask | abvfFeatureMask | abvsFeatureMask | cligFeatureMask | distFeatureMask | abvmFeatureMask | mkmkFeatureMask) +#define tagPstf (ccmpFeatureMask | blwfFeatureMask | blwsFeatureMask | prefFeatureMask | presFeatureMask | pstfFeatureMask | pstsFeatureMask | cligFeatureMask | distFeatureMask | blwmFeatureMask) +#define tagBlwf (ccmpFeatureMask | blwfFeatureMask | blwsFeatureMask | cligFeatureMask | distFeatureMask | blwmFeatureMask | mkmkFeatureMask) +#define tagDefault (ccmpFeatureMask | prefFeatureMask | blwfFeatureMask | presFeatureMask | blwsFeatureMask | cligFeatureMask | distFeatureMask | abvmFeatureMask | blwmFeatureMask | mkmkFeatureMask) + + + +// These are in the order in which the features need to be applied +// for correct processing +static const FeatureMap featureMap[] = +{ + // Shaping features + {ccmpFeatureTag, ccmpFeatureMask}, + {prefFeatureTag, prefFeatureMask}, + {blwfFeatureTag, blwfFeatureMask}, + {abvfFeatureTag, abvfFeatureMask}, + {pstfFeatureTag, pstfFeatureMask}, + {presFeatureTag, presFeatureMask}, + {blwsFeatureTag, blwsFeatureMask}, + {abvsFeatureTag, abvsFeatureMask}, + {pstsFeatureTag, pstsFeatureMask}, + {cligFeatureTag, cligFeatureMask}, + + // Positioning features + {distFeatureTag, distFeatureMask}, + {blwmFeatureTag, blwmFeatureMask}, + {abvmFeatureTag, abvmFeatureMask}, + {mkmkFeatureTag, mkmkFeatureMask}, +}; + +static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap); + +// The stateTable is used to calculate the end (the length) of a well +// formed Tibetan Syllable. +// +// Each horizontal line is ordered exactly the same way as the values in TibetanClassTable +// CharClassValues in TibetanReordering.h This coincidence of values allows the +// follow up of the table. +// +// Each line corresponds to a state, which does not necessarily need to be a type +// of component... for example, state 2 is a base, with is always a first character +// in the syllable, but the state could be produced a consonant of any type when +// it is the first character that is analysed (in ground state). +// +static const le_int8 tibetanStateTable[][TibetanClassTable::CC_COUNT] = +{ + + + //Dzongkha state table + //xx ba sj tp ac cs ha bv av an cb vs as bs di pd bd + { 1, 2, 4, 3, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, 20, 21, 21,}, // 0 - ground state + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, // 1 - exit state (or sign to the right of the syllable) + {-1, -1, 4, 3, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 2 - Base consonant + {-1, -1, 5, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 3 - Tsa phru after base + {-1, -1, 4, 6, 8, 7, 9, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 4 - Subjoined consonant after base + {-1, -1, 5, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 5 - Subjoined consonant after tsa phru + {-1, -1, -1, -1, 8, 7, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 6 - Tsa phru after subjoined consonant + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 19, -1, -1, -1,}, // 7 - Pre Composed Sanskrit + {-1, -1, -1, -1, -1, -1, -1, 10, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 8 - A-chung + {-1, -1, -1, -1, -1, -1, -1, -1, 14, 13, 17, -1, 19, 19, -1, -1, -1,}, // 9 - Halanta + {-1, -1, -1, -1, -1, -1, -1, 11, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 10 - below vowel 1 + {-1, -1, -1, -1, -1, -1, -1, 12, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 11 - below vowel 2 + {-1, -1, -1, -1, -1, -1, -1, -1, 14, 13, 17, 18, 19, 19, -1, -1, -1,}, // 12 - below vowel 3 + {-1, -1, -1, -1, -1, -1, -1, -1, 14, 17, 17, 18, 19, 19, -1, -1, -1,}, // 13 - Anusvara before vowel + {-1, -1, -1, -1, -1, -1, -1, -1, 15, 17, 17, 18, 19, 19, -1, -1, -1,}, // 14 - above vowel 1 + {-1, -1, -1, -1, -1, -1, -1, -1, 16, 17, 17, 18, 19, 19, -1, -1, -1,}, // 15 - above vowel 2 + {-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 17, 18, 19, 19, -1, -1, -1,}, // 16 - above vowel 3 + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, 19, -1, -1, -1,}, // 17 - Anusvara or Candrabindu after vowel + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 19, -1, -1, -1,}, // 18 - Visarga + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, // 19 - strss mark + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 21,}, // 20 - digit + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,}, // 21 - digit mark + + +}; + + +const FeatureMap *TibetanReordering::getFeatureMap(le_int32 &count) +{ + count = featureMapCount; + + return featureMap; +} + + +// Given an input string of characters and a location in which to start looking +// calculate, using the state table, which one is the last character of the syllable +// that starts in the starting position. +le_int32 TibetanReordering::findSyllable(const TibetanClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount) +{ + le_int32 cursor = prev; + le_int8 state = 0; + + while (cursor < charCount) { + TibetanClassTable::CharClass charClass = (classTable->getCharClass(chars[cursor]) & TibetanClassTable::CF_CLASS_MASK); + + state = tibetanStateTable[state][charClass]; + + if (state < 0) { + break; + } + + cursor += 1; + } + + return cursor; +} + + +// This is the real reordering function as applied to the Tibetan language + +le_int32 TibetanReordering::reorder(const LEUnicode *chars, le_int32 charCount, le_int32, + LEUnicode *outChars, LEGlyphStorage &glyphStorage) +{ + const TibetanClassTable *classTable = TibetanClassTable::getTibetanClassTable(); + + TibetanReorderingOutput output(outChars, glyphStorage); + TibetanClassTable::CharClass charClass; + le_int32 i, prev = 0; + + // This loop only exits when we reach the end of a run, which may contain + // several syllables. + while (prev < charCount) { + le_int32 syllable = findSyllable(classTable, chars, prev, charCount); + + // shall we add a dotted circle? + // If in the position in which the base should be (first char in the string) there is + // a character that has the Dotted circle flag (a character that cannot be a base) + // then write a dotted circle + if (classTable->getCharClass(chars[prev]) & TibetanClassTable::CF_DOTTED_CIRCLE) { + output.writeChar(C_DOTTED_CIRCLE, prev, tagDefault); + } + + // copy the rest to output, inverting the pre-number mark if present after a digit. + for (i = prev; i < syllable; i += 1) { + charClass = classTable->getCharClass(chars[i]); + + if ((TibetanClassTable::CF_DIGIT & charClass) + && ( classTable->getCharClass(chars[i+1]) & TibetanClassTable::CF_PREDIGIT)) + { + output.writeChar(C_PRE_NUMBER_MARK, i, tagPref); + output.writeChar(chars[i], i+1 , tagPref); + i += 1; + } else { + switch (charClass & TibetanClassTable::CF_POS_MASK) { + + // If the present character is a number, and the next character is a pre-number combining mark + // then the two characters are reordered + + case TibetanClassTable::CF_POS_ABOVE : + output.writeChar(chars[i], i, tagAbvf); + break; + + case TibetanClassTable::CF_POS_AFTER : + output.writeChar(chars[i], i, tagPstf); + break; + + case TibetanClassTable::CF_POS_BELOW : + output.writeChar(chars[i], i, tagBlwf); + break; + + default: + // default - any other characters + output.writeChar(chars[i], i, tagDefault); + break; + } // switch + } // if + } // for + + prev = syllable; // move the pointer to the start of next syllable + } + + return output.getOutputIndex(); +} + + +U_NAMESPACE_END diff --git a/Build/source/libs/icu-xetex/layout/TibetanReordering.h b/Build/source/libs/icu-xetex/layout/TibetanReordering.h new file mode 100644 index 00000000000..cafcf5646c8 --- /dev/null +++ b/Build/source/libs/icu-xetex/layout/TibetanReordering.h @@ -0,0 +1,151 @@ +/* + * + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * + * Developed at DIT - Government of Bhutan + * + * Contact person: Pema Geyleg - <pema_geyleg@druknet.bt> + * + * This file is a modification of the ICU file KhmerReordering.h + * by Jens Herden and Javier Sola who have given all their possible rights to IBM and the Governement of Bhutan + * A first module for Dzongkha was developed by Karunakar under Panlocalisation funding. + * Assistance for this module has been received from Namgay Thinley, Christopher Fynn and Javier Sola + * + */ + +#ifndef __TIBETANREORDERING_H +#define __TIBETANORDERING_H + +/** + * \file + * \internal + */ + +// #include "LETypes.h" +// #include "OpenTypeTables.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +// Vocabulary +// Base -> A consonant in its full (not subscript) form. It is the +// center of the syllable, it can be souranded by subjoined consonants, vowels, +// signs... but there is only one base in a stack, it has to be coded as +// the first character of the syllable.Included here are also groups of base + subjoined +// which are represented by one single code point in unicode (e.g. 0F43) Also other characters that might take +// subjoined consonants or other combining characters. +// Subjoined -> Subjoined consonants and groups of subjoined consonants which have a single code-point +// to repersent the group (even if each subjoined consonant is represented independently +// by anothe code-point +// Tsa Phru --> Tsa Phru character, Bhutanese people will always place it right after the base, but sometimes, due to +// "normalization" +// is placed after all the subjoined consonants, and it is also permitted there. +// A Chung Vowel lengthening mark --> . 0F71 It is placed after the base and any subjoined consonants but before any vowels +// Precomposed Sanskrit vowels --> The are combinations of subjoined consonants + vowels that have been assigned +// a given code-point (in spite of each single part of them having also a code-point +// They are avoided, and users are encouraged to use the combination of code-points that +// represents the same sound instead of using this combined characters. This is included here +// for compatibility with possible texts that use them (they are not in the Dzongkha keyboard). +// Halanta -> The Halanta or Virama character 0F84 indicates that a consonant should not use its inheernt vowel, +// in spite of not having other vowels present. It is usually placed immediatly after a base consonant, +// but in some special cases it can also be placed after a subjoined consonant, so this is also +// permitted in this algorithm. (Halanta is always displayed in Tibetan not used as a connecting char) +// +// Subjoined vowels -> Dependent vowels (matras) placed below the base and below all subjoined consonants. There +// might be as much as three subjoined vowels in a given stack (only one in general text, but up +// to three for abreviations, they have to be permitted). +// Superscript vowels -> There are three superscript vowels, and they can be repeated or combined (up to three +// times. They can combine with subjoined vowels, and are always coded after these. +// Anusvara --> Nasalisation sign. Traditioinally placed in absence of vowels, but also after vowels. In some +// special cases it can be placed before a vowel, so this is also permitted +// Candrabindu -> Forms of the Anusvara with different glyphs (and different in identity) which can be placed +// without vowel or after the vowel, but never before. Cannot combine with Anusvara. +// Stress marks -> Marks placed above or below a syllable, affecting the whole syllable. They are combining +// marks, so they have to be attached to a specific stack. The are using to emphasise a syllable. +// +// Digits -> Digits are not considered as non-combining characters because there are a few characters which +// combine with them, so they have to be considered independently. +// Digit combining marks -> dependent marks that combine with digits. +// +// TODO +// There are a number of characters in the CJK block that are used in Tibetan script, two of these are symbols +// are used as bases for combining glyphs, and have not been encoded in Tibetan. As these characters are outside +// of the tibetan block, they have not been treated in this program. + + +struct TibetanClassTable // This list must include all types of components that can be used inside a syllable +{ + enum CharClassValues // order is important here! This order must be the same that is found in each horizontal + // line in the statetable for Tibetan (file TibetanReordering.cpp). It assigns one number + // to each type of character that has to be considered when analysing the order in which + // characters can be placed + { + CC_RESERVED = 0, //Non Combining Characters + CC_BASE = 1, // Base Consonants, Base Consonants with Subjoined attached in code point, Sanskrit base marks + CC_SUBJOINED = 2, // Subjoined Consonats, combination of more than Subjoined Consonants in the code point + CC_TSA_PHRU = 3, // Tsa-Phru character 0F39 + CC_A_CHUNG = 4, // Vowel Lenthening a-chung mark 0F71 + CC_COMP_SANSKRIT = 5, // Precomposed Sanskrit vowels including Subjoined characters and vowels + CC_HALANTA = 6, // Halanta Character 0F84 + CC_BELOW_VOWEL = 7, // Subjoined vowels + CC_ABOVE_VOWEL = 8, // Superscript vowels + CC_ANUSVARA = 9, // Tibetan sign Rjes Su Nga Ro 0F7E + CC_CANDRABINDU = 10, // Tibetan sign Sna Ldan and Nyi Zla Naa Da 0F82, 0F83 + CC_VISARGA = 11, // Tibetan sign Rnam Bcad (0F7F) + CC_ABOVE_S_MARK = 12, // Stress Marks placed above the text + CC_BELOW_S_MARK = 13, // Stress Marks placed below the text + CC_DIGIT = 14, // Dzongkha Digits + CC_PRE_DIGIT_MARK = 15, // Mark placed before the digit + CC_POST_BELOW_DIGIT_M = 16, // Mark placed below or after the digit + CC_COUNT = 17 // This is the number of character classes + }; + + enum CharClassFlags + { + CF_CLASS_MASK = 0x0000FFFF, + + CF_DOTTED_CIRCLE = 0x04000000, // add a dotted circle if a character with this flag is the first in a syllable + CF_DIGIT = 0x01000000, // flag to speed up comparaisson + CF_PREDIGIT = 0x02000000, // flag to detect pre-digit marks for reordering + + // position flags + CF_POS_BEFORE = 0x00080000, + CF_POS_BELOW = 0x00040000, + CF_POS_ABOVE = 0x00020000, + CF_POS_AFTER = 0x00010000, + CF_POS_MASK = 0x000f0000 + }; + + typedef le_uint32 CharClass; + + typedef le_int32 ScriptFlags; + + LEUnicode firstChar; // for Tibetan this will become xOF00 + LEUnicode lastChar; // and this x0FFF + const CharClass *classTable; + + CharClass getCharClass(LEUnicode ch) const; + + static const TibetanClassTable *getTibetanClassTable(); +}; + + +class TibetanReordering /* not : public UObject because all methods are static */ { +public: + static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode, + LEUnicode *outChars, LEGlyphStorage &glyphStorage); + + static const FeatureMap *getFeatureMap(le_int32 &count); + +private: + // do not instantiate + TibetanReordering(); + + static le_int32 findSyllable(const TibetanClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount); + +}; + + +U_NAMESPACE_END +#endif diff --git a/Build/source/libs/icu-xetex/layout/layout.vcproj b/Build/source/libs/icu-xetex/layout/layout.vcproj index 9855632c81d..12ab9c54c10 100644 --- a/Build/source/libs/icu-xetex/layout/layout.vcproj +++ b/Build/source/libs/icu-xetex/layout/layout.vcproj @@ -28,6 +28,7 @@ RuntimeLibrary="3" BufferSecurityCheck="TRUE" DisableLanguageExtensions="TRUE" + TreatWChar_tAsBuiltInType="TRUE" PrecompiledHeaderFile=".\Debug/layout.pch" AssemblerListingLocation=".\Debug/" ObjectFile=".\Debug/" @@ -41,11 +42,11 @@ Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" - OutputFile="..\..\bin\icule34d.dll" + OutputFile="..\..\bin\icule36d.dll" LinkIncremental="2" SuppressStartupBanner="TRUE" GenerateDebugInformation="TRUE" - ProgramDatabaseFile=".\..\..\lib\icule34d.pdb" + ProgramDatabaseFile=".\..\..\lib\icule36d.pdb" BaseAddress="0x4ac00000" ImportLibrary="..\..\lib\iculed.lib"/> <Tool @@ -94,6 +95,7 @@ RuntimeLibrary="2" EnableFunctionLevelLinking="TRUE" DisableLanguageExtensions="TRUE" + TreatWChar_tAsBuiltInType="TRUE" PrecompiledHeaderFile=".\Release/layout.pch" AssemblerListingLocation=".\Release/" ObjectFile=".\Release/" @@ -105,10 +107,10 @@ Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" - OutputFile="..\..\bin\icule34.dll" + OutputFile="..\..\bin\icule36.dll" LinkIncremental="1" SuppressStartupBanner="TRUE" - ProgramDatabaseFile=".\..\..\lib\icule34.pdb" + ProgramDatabaseFile=".\..\..\lib\icule36.pdb" EnableCOMDATFolding="2" BaseAddress="0x4ac00000" ImportLibrary="..\..\lib\icule.lib"/> @@ -221,6 +223,9 @@ RelativePath=".\GXLayoutEngine.cpp"> </File> <File + RelativePath=".\HangulLayoutEngine.cpp"> + </File> + <File RelativePath=".\HanLayoutEngine.cpp"> </File> <File @@ -284,6 +289,9 @@ RelativePath=".\MarkToMarkPosnSubtables.cpp"> </File> <File + RelativePath=".\MirroredCharData.cpp"> + </File> + <File RelativePath=".\MorphTables.cpp"> </File> <File @@ -317,6 +325,9 @@ RelativePath=".\SegmentSingleProcessor.cpp"> </File> <File + RelativePath=".\ShapingTypeData.cpp"> + </File> + <File RelativePath=".\SimpleArrayProcessor.cpp"> </File> <File @@ -347,6 +358,12 @@ RelativePath=".\ThaiStateTables.cpp"> </File> <File + RelativePath=".\TibetanLayoutEngine.cpp"> + </File> + <File + RelativePath=".\TibetanReordering.cpp"> + </File> + <File RelativePath=".\TrimmedArrayProcessor.cpp"> </File> <File @@ -441,10 +458,10 @@ RelativePath=".\GXLayoutEngine.h"> </File> <File - RelativePath=".\HanLayoutEngine.h"> + RelativePath=".\HangulLayoutEngine.h"> </File> <File - RelativePath=".\HindiFeatureTags.h"> + RelativePath=".\HanLayoutEngine.h"> </File> <File RelativePath=".\IndicLayoutEngine.h"> @@ -744,6 +761,12 @@ RelativePath=".\ThaiShaping.h"> </File> <File + RelativePath=".\TibetanLayoutEngine.h"> + </File> + <File + RelativePath=".\TibetanReordering.h"> + </File> + <File RelativePath=".\TrimmedArrayProcessor.h"> </File> <File |