提交 0fd0c1f7 编写于 作者: S srl

6886358: layout code update

Reviewed-by: igor, prr
上级 321e8299
...@@ -68,8 +68,7 @@ FILES_cpp_shared = \ ...@@ -68,8 +68,7 @@ FILES_cpp_shared = \
GlyphPositioningTables.cpp \ GlyphPositioningTables.cpp \
GlyphSubstLookupProc.cpp \ GlyphSubstLookupProc.cpp \
GlyphSubstitutionTables.cpp \ GlyphSubstitutionTables.cpp \
HebrewLigatureData.cpp \ HangulLayoutEngine.cpp \
HebrewShaping.cpp \
IndicClassTables.cpp \ IndicClassTables.cpp \
IndicReordering.cpp \ IndicReordering.cpp \
KernTable.cpp \ KernTable.cpp \
...@@ -95,6 +94,8 @@ FILES_cpp_shared = \ ...@@ -95,6 +94,8 @@ FILES_cpp_shared = \
SubstitutionLookups.cpp \ SubstitutionLookups.cpp \
ThaiShaping.cpp \ ThaiShaping.cpp \
ThaiStateTables.cpp \ ThaiStateTables.cpp \
TibetanLayoutEngine.cpp \
TibetanReordering.cpp \
ValueRecords.cpp \ ValueRecords.cpp \
ArabicLayoutEngine.cpp \ ArabicLayoutEngine.cpp \
ArabicShaping.cpp \ ArabicShaping.cpp \
......
...@@ -276,6 +276,18 @@ public final class FontUtilities { ...@@ -276,6 +276,18 @@ public final class FontUtilities {
// 0E00 - 0E7F if Thai, assume shaping for vowel, tone marks // 0E00 - 0E7F if Thai, assume shaping for vowel, tone marks
return true; return true;
} }
else if (code < 0x0f00) {
return false;
}
else if (code <= 0x0fff) { // U+0F00 - U+0FFF Tibetan
return true;
}
else if (code < 0x1100) {
return false;
}
else if (code < 0x11ff) { // U+1100 - U+11FF Old Hangul
return true;
}
else if (code < 0x1780) { else if (code < 0x1780) {
return false; return false;
} }
......
...@@ -59,16 +59,16 @@ le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const ...@@ -59,16 +59,16 @@ le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{ {
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount); fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE; fFeatureOrder = TRUE;
} }
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags) le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{ {
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount); fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
...@@ -151,8 +151,8 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l ...@@ -151,8 +151,8 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
} }
} }
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags) UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags) : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{ {
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
......
...@@ -66,6 +66,7 @@ public: ...@@ -66,6 +66,7 @@ public:
* @param scriptCode - the script * @param scriptCode - the script
* @param langaugeCode - the language * @param langaugeCode - the language
* @param gsubTable - the GSUB table * @param gsubTable - the GSUB table
* @param success - set to an error code if the operation fails
* *
* @see LayoutEngine::layoutEngineFactory * @see LayoutEngine::layoutEngineFactory
* @see OpenTypeLayoutEngine * @see OpenTypeLayoutEngine
...@@ -74,7 +75,7 @@ public: ...@@ -74,7 +75,7 @@ public:
* @internal * @internal
*/ */
ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable); le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
/** /**
* This constructor is used when the font requires a "canned" GSUB table which can't be known * This constructor is used when the font requires a "canned" GSUB table which can't be known
...@@ -83,6 +84,7 @@ public: ...@@ -83,6 +84,7 @@ public:
* @param fontInstance - the font * @param fontInstance - the font
* @param scriptCode - the script * @param scriptCode - the script
* @param langaugeCode - the language * @param langaugeCode - the language
* @param success - set to an error code if the operation fails
* *
* @see OpenTypeLayoutEngine * @see OpenTypeLayoutEngine
* @see ScriptAndLanguageTags.h for script and language codes * @see ScriptAndLanguageTags.h for script and language codes
...@@ -90,7 +92,7 @@ public: ...@@ -90,7 +92,7 @@ public:
* @internal * @internal
*/ */
ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags); le_int32 typoFlags, LEErrorCode &success);
/** /**
* The destructor, virtual for correct polymorphic invocation. * The destructor, virtual for correct polymorphic invocation.
...@@ -184,6 +186,7 @@ public: ...@@ -184,6 +186,7 @@ public:
* @param fontInstance - the font * @param fontInstance - the font
* @param scriptCode - the script * @param scriptCode - the script
* @param languageCode - the language * @param languageCode - the language
* @param success - set to an error code if the operation fails
* *
* @see LEFontInstance * @see LEFontInstance
* @see ScriptAndLanguageTags.h for script and language codes * @see ScriptAndLanguageTags.h for script and language codes
...@@ -191,7 +194,7 @@ public: ...@@ -191,7 +194,7 @@ public:
* @internal * @internal
*/ */
UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags); le_int32 typoFlags, LEErrorCode &success);
/** /**
* The destructor, virtual for correct polymorphic invocation. * The destructor, virtual for correct polymorphic invocation.
......
...@@ -104,6 +104,7 @@ ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c) ...@@ -104,6 +104,7 @@ ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
#define markFeatureMask 0x00040000UL #define markFeatureMask 0x00040000UL
#define mkmkFeatureMask 0x00020000UL #define mkmkFeatureMask 0x00020000UL
#define NO_FEATURES 0
#define ISOL_FEATURES (isolFeatureMask | ligaFeatureMask | msetFeatureMask | markFeatureMask | ccmpFeatureMask | rligFeatureMask | caltFeatureMask | dligFeatureMask | cswhFeatureMask | cursFeatureMask | kernFeatureMask | mkmkFeatureMask) #define ISOL_FEATURES (isolFeatureMask | ligaFeatureMask | msetFeatureMask | markFeatureMask | ccmpFeatureMask | rligFeatureMask | caltFeatureMask | dligFeatureMask | cswhFeatureMask | cursFeatureMask | kernFeatureMask | mkmkFeatureMask)
#define SHAPE_MASK 0xF0000000UL #define SHAPE_MASK 0xF0000000UL
...@@ -198,7 +199,11 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char ...@@ -198,7 +199,11 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char
LEUnicode c = chars[in]; LEUnicode c = chars[in];
ShapeType t = getShapeType(c); ShapeType t = getShapeType(c);
if (t == ST_NOSHAPE_NONE) {
glyphStorage.setAuxData(out, NO_FEATURES, success);
} else {
glyphStorage.setAuxData(out, ISOL_FEATURES, success); glyphStorage.setAuxData(out, ISOL_FEATURES, success);
}
if ((t & MASK_TRANSPARENT) != 0) { if ((t & MASK_TRANSPARENT) != 0) {
continue; continue;
......
...@@ -38,7 +38,7 @@ U_NAMESPACE_BEGIN ...@@ -38,7 +38,7 @@ U_NAMESPACE_BEGIN
class LEGlyphStorage; 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: public:
static const le_uint8 glyphSubstitutionTable[]; static const le_uint8 glyphSubstitutionTable[];
......
...@@ -93,7 +93,7 @@ le_int32 ClassDefFormat1Table::getGlyphClass(LEGlyphID glyphID) const ...@@ -93,7 +93,7 @@ le_int32 ClassDefFormat1Table::getGlyphClass(LEGlyphID glyphID) const
TTGlyphID firstGlyph = SWAPW(startGlyph); TTGlyphID firstGlyph = SWAPW(startGlyph);
TTGlyphID lastGlyph = firstGlyph + SWAPW(glyphCount); TTGlyphID lastGlyph = firstGlyph + SWAPW(glyphCount);
if (ttGlyphID > firstGlyph && ttGlyphID < lastGlyph) { if (ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
return SWAPW(classValueArray[ttGlyphID - firstGlyph]); return SWAPW(classValueArray[ttGlyphID - firstGlyph]);
} }
......
...@@ -52,18 +52,23 @@ void ContextualSubstitutionBase::applySubstitutionLookups( ...@@ -52,18 +52,23 @@ void ContextualSubstitutionBase::applySubstitutionLookups(
le_uint16 substCount, le_uint16 substCount,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
le_int32 position) le_int32 position,
LEErrorCode& success)
{ {
if (LE_FAILURE(success)) {
return;
}
GlyphIterator tempIterator(*glyphIterator); GlyphIterator tempIterator(*glyphIterator);
for (le_int16 subst = 0; subst < substCount; subst += 1) { for (le_int16 subst = 0; subst < substCount && LE_SUCCESS(success); subst += 1) {
le_uint16 sequenceIndex = SWAPW(substLookupRecordArray[subst].sequenceIndex); le_uint16 sequenceIndex = SWAPW(substLookupRecordArray[subst].sequenceIndex);
le_uint16 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex); le_uint16 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex);
tempIterator.setCurrStreamPosition(position); tempIterator.setCurrStreamPosition(position);
tempIterator.next(sequenceIndex); tempIterator.next(sequenceIndex);
lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance); lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance, success);
} }
} }
...@@ -165,9 +170,15 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa ...@@ -165,9 +170,15 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa
return TRUE; return TRUE;
} }
le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
const LEFontInstance *fontInstance) const GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) {
return 0;
}
switch(SWAPW(subtableFormat)) switch(SWAPW(subtableFormat))
{ {
case 0: case 0:
...@@ -176,22 +187,19 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP ...@@ -176,22 +187,19 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP
case 1: case 1:
{ {
const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this; const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
return subtable->process(lookupProcessor, glyphIterator, fontInstance);
} }
case 2: case 2:
{ {
const ContextualSubstitutionFormat2Subtable *subtable = (const ContextualSubstitutionFormat2Subtable *) this; const ContextualSubstitutionFormat2Subtable *subtable = (const ContextualSubstitutionFormat2Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
return subtable->process(lookupProcessor, glyphIterator, fontInstance);
} }
case 3: case 3:
{ {
const ContextualSubstitutionFormat3Subtable *subtable = (const ContextualSubstitutionFormat3Subtable *) this; const ContextualSubstitutionFormat3Subtable *subtable = (const ContextualSubstitutionFormat3Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
return subtable->process(lookupProcessor, glyphIterator, fontInstance);
} }
default: default:
...@@ -199,9 +207,15 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP ...@@ -199,9 +207,15 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP
} }
} }
le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
const LEFontInstance *fontInstance) const GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) {
return 0;
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(glyph);
...@@ -227,7 +241,7 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor * ...@@ -227,7 +241,7 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
const SubstitutionLookupRecord *substLookupRecordArray = const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount]; (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount];
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return matchCount + 1; return matchCount + 1;
} }
...@@ -242,9 +256,15 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor * ...@@ -242,9 +256,15 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
return 0; return 0;
} }
le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
const LEFontInstance *fontInstance) const GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) {
return 0;
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(glyph);
...@@ -273,7 +293,7 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor * ...@@ -273,7 +293,7 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
const SubstitutionLookupRecord *substLookupRecordArray = const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount]; (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount];
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return matchCount + 1; return matchCount + 1;
} }
...@@ -288,9 +308,15 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor * ...@@ -288,9 +308,15 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
return 0; return 0;
} }
le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
const LEFontInstance *fontInstance)const GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success)const
{ {
if (LE_FAILURE(success)) {
return 0;
}
le_uint16 gCount = SWAPW(glyphCount); le_uint16 gCount = SWAPW(glyphCount);
le_uint16 subCount = SWAPW(substCount); le_uint16 subCount = SWAPW(substCount);
le_int32 position = glyphIterator->getCurrStreamPosition(); le_int32 position = glyphIterator->getCurrStreamPosition();
...@@ -305,7 +331,7 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor * ...@@ -305,7 +331,7 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
const SubstitutionLookupRecord *substLookupRecordArray = const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount]; (const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount];
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position); ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position, success);
return gCount + 1; return gCount + 1;
} }
...@@ -315,9 +341,15 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor * ...@@ -315,9 +341,15 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
return 0; return 0;
} }
le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
const LEFontInstance *fontInstance) const GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) {
return 0;
}
switch(SWAPW(subtableFormat)) switch(SWAPW(subtableFormat))
{ {
case 0: case 0:
...@@ -326,22 +358,19 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor ...@@ -326,22 +358,19 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
case 1: case 1:
{ {
const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this; const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
return subtable->process(lookupProcessor, glyphIterator, fontInstance);
} }
case 2: case 2:
{ {
const ChainingContextualSubstitutionFormat2Subtable *subtable = (const ChainingContextualSubstitutionFormat2Subtable *) this; const ChainingContextualSubstitutionFormat2Subtable *subtable = (const ChainingContextualSubstitutionFormat2Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
return subtable->process(lookupProcessor, glyphIterator, fontInstance);
} }
case 3: case 3:
{ {
const ChainingContextualSubstitutionFormat3Subtable *subtable = (const ChainingContextualSubstitutionFormat3Subtable *) this; const ChainingContextualSubstitutionFormat3Subtable *subtable = (const ChainingContextualSubstitutionFormat3Subtable *) this;
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
return subtable->process(lookupProcessor, glyphIterator, fontInstance);
} }
default: default:
...@@ -355,9 +384,15 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor ...@@ -355,9 +384,15 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
// emptyFeatureList matches an le_uint32 or an le_uint16... // emptyFeatureList matches an le_uint32 or an le_uint16...
static const FeatureMask emptyFeatureList = 0x00000000UL; static const FeatureMask emptyFeatureList = 0x00000000UL;
le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
const LEFontInstance *fontInstance) const GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) {
return 0;
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(glyph);
...@@ -405,7 +440,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro ...@@ -405,7 +440,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
const SubstitutionLookupRecord *substLookupRecordArray = const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1]; (const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1];
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return inputGlyphCount + 1; return inputGlyphCount + 1;
} }
...@@ -420,9 +455,15 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro ...@@ -420,9 +455,15 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
return 0; return 0;
} }
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
const LEFontInstance *fontInstance) const GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) {
return 0;
}
LEGlyphID glyph = glyphIterator->getCurrGlyphID(); LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph); le_int32 coverageIndex = getGlyphCoverage(glyph);
...@@ -479,7 +520,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro ...@@ -479,7 +520,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
const SubstitutionLookupRecord *substLookupRecordArray = const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1]; (const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1];
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return inputGlyphCount + 1; return inputGlyphCount + 1;
} }
...@@ -494,9 +535,15 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro ...@@ -494,9 +535,15 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
return 0; return 0;
} }
le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
const LEFontInstance *fontInstance) const GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance,
LEErrorCode & success) const
{ {
if (LE_FAILURE(success)) {
return 0;
}
le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount); le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount);
le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]); le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]);
const Offset *inputCoverageTableOffsetArray = &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1]; const Offset *inputCoverageTableOffsetArray = &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1];
...@@ -534,7 +581,7 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro ...@@ -534,7 +581,7 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
const SubstitutionLookupRecord *substLookupRecordArray = const SubstitutionLookupRecord *substLookupRecordArray =
(const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1]; (const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1];
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
return inputGlyphCount; return inputGlyphCount;
} }
......
...@@ -72,12 +72,13 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable ...@@ -72,12 +72,13 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
le_uint16 substCount, le_uint16 substCount,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance, const LEFontInstance *fontInstance,
le_int32 position); le_int32 position,
LEErrorCode& success);
}; };
struct ContextualSubstitutionSubtable : ContextualSubstitutionBase struct ContextualSubstitutionSubtable : ContextualSubstitutionBase
{ {
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
...@@ -85,7 +86,7 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable ...@@ -85,7 +86,7 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
le_uint16 subRuleSetCount; le_uint16 subRuleSetCount;
Offset subRuleSetTableOffsetArray[ANY_NUMBER]; Offset subRuleSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
struct SubRuleSetTable struct SubRuleSetTable
...@@ -110,7 +111,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable ...@@ -110,7 +111,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
le_uint16 subClassSetCount; le_uint16 subClassSetCount;
Offset subClassSetTableOffsetArray[ANY_NUMBER]; Offset subClassSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
struct SubClassSetTable struct SubClassSetTable
...@@ -140,12 +141,12 @@ struct ContextualSubstitutionFormat3Subtable ...@@ -140,12 +141,12 @@ struct ContextualSubstitutionFormat3Subtable
Offset coverageTableOffsetArray[ANY_NUMBER]; Offset coverageTableOffsetArray[ANY_NUMBER];
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
{ {
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable
...@@ -153,7 +154,7 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit ...@@ -153,7 +154,7 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit
le_uint16 chainSubRuleSetCount; le_uint16 chainSubRuleSetCount;
Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER]; Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
struct ChainSubRuleSetTable struct ChainSubRuleSetTable
...@@ -184,7 +185,7 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit ...@@ -184,7 +185,7 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit
le_uint16 chainSubClassSetCount; le_uint16 chainSubClassSetCount;
Offset chainSubClassSetTableOffsetArray[ANY_NUMBER]; Offset chainSubClassSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
struct ChainSubClassSetTable struct ChainSubClassSetTable
...@@ -222,7 +223,7 @@ struct ChainingContextualSubstitutionFormat3Subtable ...@@ -222,7 +223,7 @@ struct ChainingContextualSubstitutionFormat3Subtable
//le_uint16 substCount; //le_uint16 substCount;
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -73,6 +73,10 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const ...@@ -73,6 +73,10 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const
le_uint16 probe = power; le_uint16 probe = power;
le_uint16 index = 0; le_uint16 index = 0;
if (count == 0) {
return -1;
}
if (SWAPW(glyphArray[extra]) <= ttGlyphID) { if (SWAPW(glyphArray[extra]) <= ttGlyphID) {
index = extra; index = extra;
} }
......
...@@ -59,6 +59,8 @@ le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const ...@@ -59,6 +59,8 @@ le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const
entryAnchorTable->getAnchor(glyphID, fontInstance, entryAnchor); entryAnchorTable->getAnchor(glyphID, fontInstance, entryAnchor);
glyphIterator->setCursiveEntryPoint(entryAnchor); glyphIterator->setCursiveEntryPoint(entryAnchor);
} else {
//glyphIterator->clearCursiveEntryPoint();
} }
if (exitOffset != 0) { if (exitOffset != 0) {
...@@ -66,6 +68,8 @@ le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const ...@@ -66,6 +68,8 @@ le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const
exitAnchorTable->getAnchor(glyphID, fontInstance, exitAnchor); exitAnchorTable->getAnchor(glyphID, fontInstance, exitAnchor);
glyphIterator->setCursiveExitPoint(exitAnchor); glyphIterator->setCursiveExitPoint(exitAnchor);
} else {
//glyphIterator->clearCursiveExitPoint();
} }
return 1; return 1;
......
...@@ -41,13 +41,15 @@ const le_uint16 DeviceTable::fieldMasks[] = {0x0003, 0x000F, 0x00FF}; ...@@ -41,13 +41,15 @@ const le_uint16 DeviceTable::fieldMasks[] = {0x0003, 0x000F, 0x00FF};
const le_uint16 DeviceTable::fieldSignBits[] = {0x0002, 0x0008, 0x0080}; const le_uint16 DeviceTable::fieldSignBits[] = {0x0002, 0x0008, 0x0080};
const le_uint16 DeviceTable::fieldBits[] = { 2, 4, 8}; const le_uint16 DeviceTable::fieldBits[] = { 2, 4, 8};
#define FORMAT_COUNT LE_ARRAY_SIZE(fieldBits)
le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const
{ {
le_uint16 start = SWAPW(startSize); le_uint16 start = SWAPW(startSize);
le_uint16 format = SWAPW(deltaFormat) - 1; le_uint16 format = SWAPW(deltaFormat) - 1;
le_int16 result = 0; le_int16 result = 0;
if (ppem >= start && ppem <= SWAPW(endSize)) { if (ppem >= start && ppem <= SWAPW(endSize) && format < FORMAT_COUNT) {
le_uint16 sizeIndex = ppem - start; le_uint16 sizeIndex = ppem - start;
le_uint16 bits = fieldBits[format]; le_uint16 bits = fieldBits[format];
le_uint16 count = 16 / bits; le_uint16 count = 16 / bits;
......
...@@ -40,18 +40,24 @@ ...@@ -40,18 +40,24 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
// read a 32-bit value that might only be 16-bit-aligned in memory
#define READ_LONG(code) (le_uint32)((SWAPW(*(le_uint16*)&code) << 16) + SWAPW(*(((le_uint16*)&code) + 1)))
// FIXME: should look at the format too... maybe have a sub-class for it? // FIXME: should look at the format too... maybe have a sub-class for it?
le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType, le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) {
return 0;
}
le_uint16 elt = SWAPW(extensionLookupType); le_uint16 elt = SWAPW(extensionLookupType);
if (elt != lookupType) { if (elt != lookupType) {
le_uint32 extOffset = SWAPL(extensionOffset); le_uint32 extOffset = READ_LONG(extensionOffset);
LookupSubtable *subtable = (LookupSubtable *) ((char *) this + extOffset); LookupSubtable *subtable = (LookupSubtable *) ((char *) this + extOffset);
return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance); return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success);
} }
return 0; return 0;
......
...@@ -53,7 +53,7 @@ struct ExtensionSubtable //: GlyphSubstitutionSubtable ...@@ -53,7 +53,7 @@ struct ExtensionSubtable //: GlyphSubstitutionSubtable
le_uint32 extensionOffset; le_uint32 extensionOffset;
le_uint32 process(const LookupProcessor *lookupProcessor, le_uint16 lookupType, le_uint32 process(const LookupProcessor *lookupProcessor, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "LETypes.h" #include "LETypes.h"
#include "OpenTypeUtilities.h" #include "OpenTypeUtilities.h"
#include "OpenTypeTables.h" #include "OpenTypeTables.h"
#include "Features.h" #include "ICUFeatures.h"
#include "LESwaps.h" #include "LESwaps.h"
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
......
...@@ -41,8 +41,8 @@ U_NAMESPACE_BEGIN ...@@ -41,8 +41,8 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine)
GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable) GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success)
: LayoutEngine(fontInstance, scriptCode, languageCode, 0), fMorphTable(morphTable) : LayoutEngine(fontInstance, scriptCode, languageCode, 0, success), fMorphTable(morphTable)
{ {
// nothing else to do? // nothing else to do?
} }
......
...@@ -67,13 +67,14 @@ public: ...@@ -67,13 +67,14 @@ public:
* @param scriptCode - the script * @param scriptCode - the script
* @param langaugeCode - the language * @param langaugeCode - the language
* @param morphTable - the 'mort' table * @param morphTable - the 'mort' table
* @param success - set to an error code if the operation fails
* *
* @see LayoutEngine::layoutEngineFactory * @see LayoutEngine::layoutEngineFactory
* @see ScriptAndLangaugeTags.h for script and language codes * @see ScriptAndLangaugeTags.h for script and language codes
* *
* @internal * @internal
*/ */
GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable); GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success);
/** /**
* The destructor, virtual for correct polymorphic invocation. * The destructor, virtual for correct polymorphic invocation.
......
...@@ -44,7 +44,7 @@ GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjus ...@@ -44,7 +44,7 @@ GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjus
FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader) FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
: direction(1), position(-1), nextLimit(-1), prevLimit(-1), : direction(1), position(-1), nextLimit(-1), prevLimit(-1),
glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments), glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL) glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL)
{ {
...@@ -78,6 +78,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that) ...@@ -78,6 +78,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that)
destIndex = that.destIndex; destIndex = that.destIndex;
lookupFlags = that.lookupFlags; lookupFlags = that.lookupFlags;
featureMask = that.featureMask; featureMask = that.featureMask;
glyphGroup = that.glyphGroup;
glyphClassDefinitionTable = that.glyphClassDefinitionTable; glyphClassDefinitionTable = that.glyphClassDefinitionTable;
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
} }
...@@ -95,6 +96,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask) ...@@ -95,6 +96,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask)
destIndex = that.destIndex; destIndex = that.destIndex;
lookupFlags = that.lookupFlags; lookupFlags = that.lookupFlags;
featureMask = newFeatureMask; featureMask = newFeatureMask;
glyphGroup = 0;
glyphClassDefinitionTable = that.glyphClassDefinitionTable; glyphClassDefinitionTable = that.glyphClassDefinitionTable;
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
} }
...@@ -112,6 +114,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags) ...@@ -112,6 +114,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags)
destIndex = that.destIndex; destIndex = that.destIndex;
lookupFlags = newLookupFlags; lookupFlags = newLookupFlags;
featureMask = that.featureMask; featureMask = that.featureMask;
glyphGroup = that.glyphGroup;
glyphClassDefinitionTable = that.glyphClassDefinitionTable; glyphClassDefinitionTable = that.glyphClassDefinitionTable;
markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
} }
...@@ -125,12 +128,13 @@ void GlyphIterator::reset(le_uint16 newLookupFlags, FeatureMask newFeatureMask) ...@@ -125,12 +128,13 @@ void GlyphIterator::reset(le_uint16 newLookupFlags, FeatureMask newFeatureMask)
{ {
position = prevLimit; position = prevLimit;
featureMask = newFeatureMask; featureMask = newFeatureMask;
glyphGroup = 0;
lookupFlags = newLookupFlags; lookupFlags = newLookupFlags;
} }
LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count) LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count, LEErrorCode& success)
{ {
return glyphStorage.insertGlyphs(position, count); return glyphStorage.insertGlyphs(position, count, success);
} }
le_int32 GlyphIterator::applyInsertions() le_int32 GlyphIterator::applyInsertions()
...@@ -299,6 +303,36 @@ void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float ...@@ -299,6 +303,36 @@ void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float
glyphPositionAdjustments->setYAdvance(position, yAdvanceAdjust); glyphPositionAdjustments->setYAdvance(position, yAdvanceAdjust);
} }
void GlyphIterator::clearCursiveEntryPoint()
{
if (direction < 0) {
if (position <= nextLimit || position >= prevLimit) {
return;
}
} else {
if (position <= prevLimit || position >= nextLimit) {
return;
}
}
glyphPositionAdjustments->clearEntryPoint(position);
}
void GlyphIterator::clearCursiveExitPoint()
{
if (direction < 0) {
if (position <= nextLimit || position >= prevLimit) {
return;
}
} else {
if (position <= prevLimit || position >= nextLimit) {
return;
}
}
glyphPositionAdjustments->clearExitPoint(position);
}
void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint) void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint)
{ {
if (direction < 0) { if (direction < 0) {
...@@ -391,7 +425,7 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const ...@@ -391,7 +425,7 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const
} }
} }
le_bool GlyphIterator::hasFeatureTag() const le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup) const
{ {
if (featureMask == 0) { if (featureMask == 0) {
return TRUE; return TRUE;
...@@ -400,14 +434,18 @@ le_bool GlyphIterator::hasFeatureTag() const ...@@ -400,14 +434,18 @@ le_bool GlyphIterator::hasFeatureTag() const
LEErrorCode success = LE_NO_ERROR; LEErrorCode success = LE_NO_ERROR;
FeatureMask fm = glyphStorage.getAuxData(position, success); FeatureMask fm = glyphStorage.getAuxData(position, success);
return (fm & featureMask) != 0; return ((fm & featureMask) == featureMask) && (!matchGroup || (le_int32)(fm & LE_GLYPH_GROUP_MASK) == glyphGroup);
} }
le_bool GlyphIterator::findFeatureTag() le_bool GlyphIterator::findFeatureTag()
{ {
//glyphGroup = 0;
while (nextInternal()) { while (nextInternal()) {
if (hasFeatureTag()) { if (hasFeatureTag(FALSE)) {
prevInternal(); LEErrorCode success = LE_NO_ERROR;
glyphGroup = (glyphStorage.getAuxData(position, success) & LE_GLYPH_GROUP_MASK);
return TRUE; return TRUE;
} }
} }
...@@ -435,7 +473,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta) ...@@ -435,7 +473,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta)
le_bool GlyphIterator::next(le_uint32 delta) le_bool GlyphIterator::next(le_uint32 delta)
{ {
return nextInternal(delta) && hasFeatureTag(); return nextInternal(delta) && hasFeatureTag(TRUE);
} }
le_bool GlyphIterator::prevInternal(le_uint32 delta) le_bool GlyphIterator::prevInternal(le_uint32 delta)
...@@ -457,7 +495,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta) ...@@ -457,7 +495,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta)
le_bool GlyphIterator::prev(le_uint32 delta) le_bool GlyphIterator::prev(le_uint32 delta)
{ {
return prevInternal(delta) && hasFeatureTag(); return prevInternal(delta) && hasFeatureTag(TRUE);
} }
le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const
......
...@@ -88,16 +88,18 @@ public: ...@@ -88,16 +88,18 @@ public:
void setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust, void setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
float xAdvanceAdjust, float yAdvanceAdjust); float xAdvanceAdjust, float yAdvanceAdjust);
void clearCursiveEntryPoint();
void clearCursiveExitPoint();
void setCursiveEntryPoint(LEPoint &entryPoint); void setCursiveEntryPoint(LEPoint &entryPoint);
void setCursiveExitPoint(LEPoint &exitPoint); void setCursiveExitPoint(LEPoint &exitPoint);
void setCursiveGlyph(); void setCursiveGlyph();
LEGlyphID *insertGlyphs(le_int32 count); LEGlyphID *insertGlyphs(le_int32 count, LEErrorCode& success);
le_int32 applyInsertions(); le_int32 applyInsertions();
private: private:
le_bool filterGlyph(le_uint32 index) const; le_bool filterGlyph(le_uint32 index) const;
le_bool hasFeatureTag() const; le_bool hasFeatureTag(le_bool matchGroup) const;
le_bool nextInternal(le_uint32 delta = 1); le_bool nextInternal(le_uint32 delta = 1);
le_bool prevInternal(le_uint32 delta = 1); le_bool prevInternal(le_uint32 delta = 1);
...@@ -113,6 +115,7 @@ private: ...@@ -113,6 +115,7 @@ private:
le_int32 destIndex; le_int32 destIndex;
le_uint16 lookupFlags; le_uint16 lookupFlags;
FeatureMask featureMask; FeatureMask featureMask;
le_int32 glyphGroup;
const GlyphClassDefinitionTable *glyphClassDefinitionTable; const GlyphClassDefinitionTable *glyphClassDefinitionTable;
const MarkAttachClassDefinitionTable *markAttachClassDefinitionTable; const MarkAttachClassDefinitionTable *markAttachClassDefinitionTable;
......
...@@ -71,6 +71,20 @@ const LEPoint *GlyphPositionAdjustments::getExitPoint(le_int32 index, LEPoint &e ...@@ -71,6 +71,20 @@ const LEPoint *GlyphPositionAdjustments::getExitPoint(le_int32 index, LEPoint &e
return fEntryExitPoints[index].getExitPoint(exitPoint); return fEntryExitPoints[index].getExitPoint(exitPoint);
} }
void GlyphPositionAdjustments::clearEntryPoint(le_int32 index)
{
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
fEntryExitPoints[index].clearEntryPoint();
}
void GlyphPositionAdjustments::clearExitPoint(le_int32 index)
{
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
fEntryExitPoints[index].clearExitPoint();
}
void GlyphPositionAdjustments::setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd) void GlyphPositionAdjustments::setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
{ {
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount); CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
...@@ -152,7 +166,12 @@ void GlyphPositionAdjustments::applyCursiveAdjustments(LEGlyphStorage &glyphStor ...@@ -152,7 +166,12 @@ void GlyphPositionAdjustments::applyCursiveAdjustments(LEGlyphStorage &glyphStor
lastExitGlyphID = glyphID; lastExitGlyphID = glyphID;
} else { } else {
if (baselineIsLogicalEnd(i) && firstExitPoint >= 0 && lastExitPoint >= 0) { if (baselineIsLogicalEnd(i) && firstExitPoint >= 0 && lastExitPoint >= 0) {
le_int32 limit = lastExitPoint + dir; le_int32 limit = lastExitPoint /*+ dir*/;
LEPoint dummyAnchor;
if (getEntryPoint(i, dummyAnchor) != NULL) {
limit += dir;
}
for (le_int32 j = firstExitPoint; j != limit; j += dir) { for (le_int32 j = firstExitPoint; j != limit; j += dir) {
if (isCursiveGlyph(j)) { if (isCursiveGlyph(j)) {
......
...@@ -97,6 +97,8 @@ private: ...@@ -97,6 +97,8 @@ private:
LEPoint *getEntryPoint(LEPoint &entryPoint) const; LEPoint *getEntryPoint(LEPoint &entryPoint) const;
LEPoint *getExitPoint(LEPoint &exitPoint) const; LEPoint *getExitPoint(LEPoint &exitPoint) const;
inline void clearEntryPoint();
inline void clearExitPoint();
inline void setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd); inline void setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
inline void setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd); inline void setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
inline void setCursiveGlyph(le_bool baselineIsLogicalEnd); inline void setCursiveGlyph(le_bool baselineIsLogicalEnd);
...@@ -151,6 +153,8 @@ public: ...@@ -151,6 +153,8 @@ public:
inline void adjustXAdvance(le_int32 index, float xAdjustment); inline void adjustXAdvance(le_int32 index, float xAdjustment);
inline void adjustYAdvance(le_int32 index, float yAdjustment); inline void adjustYAdvance(le_int32 index, float yAdjustment);
void clearEntryPoint(le_int32 index);
void clearExitPoint(le_int32 index);
void setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd); void setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
void setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd); void setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
void setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd); void setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd);
...@@ -266,6 +270,16 @@ inline le_bool GlyphPositionAdjustments::EntryExitPoint::baselineIsLogicalEnd() ...@@ -266,6 +270,16 @@ inline le_bool GlyphPositionAdjustments::EntryExitPoint::baselineIsLogicalEnd()
return (fFlags & EEF_BASELINE_IS_LOGICAL_END) != 0; return (fFlags & EEF_BASELINE_IS_LOGICAL_END) != 0;
} }
inline void GlyphPositionAdjustments::EntryExitPoint::clearEntryPoint()
{
fFlags &= ~EEF_HAS_ENTRY_POINT;
}
inline void GlyphPositionAdjustments::EntryExitPoint::clearExitPoint()
{
fFlags &= ~EEF_HAS_EXIT_POINT;
}
inline void GlyphPositionAdjustments::EntryExitPoint::setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd) inline void GlyphPositionAdjustments::EntryExitPoint::setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
{ {
if (baselineIsLogicalEnd) { if (baselineIsLogicalEnd) {
......
...@@ -43,12 +43,19 @@ U_NAMESPACE_BEGIN ...@@ -43,12 +43,19 @@ U_NAMESPACE_BEGIN
void GlyphPositioningTableHeader::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft, void GlyphPositioningTableHeader::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft,
LETag scriptTag, LETag languageTag, LETag scriptTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success,
const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const
{ {
GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder); if (LE_FAILURE(success)) {
return;
}
processor.process(glyphStorage, glyphPositionAdjustments, rightToLeft, glyphDefinitionTableHeader, fontInstance); GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success);
if (LE_FAILURE(success)) {
return;
}
processor.process(glyphStorage, glyphPositionAdjustments, rightToLeft, glyphDefinitionTableHeader, fontInstance, success);
glyphPositionAdjustments->applyCursiveAdjustments(glyphStorage, rightToLeft, fontInstance); glyphPositionAdjustments->applyCursiveAdjustments(glyphStorage, rightToLeft, fontInstance);
} }
......
...@@ -53,7 +53,7 @@ struct GlyphPositioningTableHeader : public GlyphLookupTableHeader ...@@ -53,7 +53,7 @@ struct GlyphPositioningTableHeader : public GlyphLookupTableHeader
{ {
void process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, void process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
le_bool rightToLeft, LETag scriptTag, LETag languageTag, le_bool rightToLeft, LETag scriptTag, LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success,
const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const; const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const;
}; };
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include "LETypes.h" #include "LETypes.h"
#include "LEFontInstance.h" #include "LEFontInstance.h"
#include "OpenTypeTables.h" #include "OpenTypeTables.h"
#include "Features.h" #include "ICUFeatures.h"
#include "Lookups.h" #include "Lookups.h"
#include "ScriptAndLanguage.h" #include "ScriptAndLanguage.h"
#include "GlyphDefinitionTables.h" #include "GlyphDefinitionTables.h"
...@@ -58,13 +58,24 @@ typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubt ...@@ -58,13 +58,24 @@ typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubt
GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor( GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor(
const GlyphPositioningTableHeader *glyphPositioningTableHeader, const GlyphPositioningTableHeader *glyphPositioningTableHeader,
LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) LETag scriptTag,
LETag languageTag,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode& success)
: LookupProcessor( : LookupProcessor(
(char *) glyphPositioningTableHeader, (char *) glyphPositioningTableHeader,
SWAPW(glyphPositioningTableHeader->scriptListOffset), SWAPW(glyphPositioningTableHeader->scriptListOffset),
SWAPW(glyphPositioningTableHeader->featureListOffset), SWAPW(glyphPositioningTableHeader->featureListOffset),
SWAPW(glyphPositioningTableHeader->lookupListOffset), SWAPW(glyphPositioningTableHeader->lookupListOffset),
scriptTag, languageTag, featureMap, featureMapCount, featureOrder) scriptTag,
languageTag,
featureMap,
featureMapCount,
featureOrder,
success
)
{ {
// anything? // anything?
} }
...@@ -75,8 +86,13 @@ GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor() ...@@ -75,8 +86,13 @@ GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor()
le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType,
GlyphIterator *glyphIterator, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance) const const LEFontInstance *fontInstance,
LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) {
return 0;
}
le_uint32 delta = 0; le_uint32 delta = 0;
switch(lookupType) switch(lookupType)
...@@ -136,7 +152,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l ...@@ -136,7 +152,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
{ {
const ContextualPositioningSubtable *subtable = (const ContextualPositioningSubtable *) lookupSubtable; const ContextualPositioningSubtable *subtable = (const ContextualPositioningSubtable *) lookupSubtable;
delta = subtable->process(this, glyphIterator, fontInstance); delta = subtable->process(this, glyphIterator, fontInstance, success);
break; break;
} }
...@@ -144,7 +160,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l ...@@ -144,7 +160,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
{ {
const ChainingContextualPositioningSubtable *subtable = (const ChainingContextualPositioningSubtable *) lookupSubtable; const ChainingContextualPositioningSubtable *subtable = (const ChainingContextualPositioningSubtable *) lookupSubtable;
delta = subtable->process(this, glyphIterator, fontInstance); delta = subtable->process(this, glyphIterator, fontInstance, success);
break; break;
} }
...@@ -152,7 +168,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l ...@@ -152,7 +168,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l
{ {
const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable; const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable;
delta = subtable->process(this, lookupType, glyphIterator, fontInstance); delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
break; break;
} }
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include "LEFontInstance.h" #include "LEFontInstance.h"
#include "OpenTypeTables.h" #include "OpenTypeTables.h"
#include "Lookups.h" #include "Lookups.h"
#include "Features.h" #include "ICUFeatures.h"
#include "GlyphDefinitionTables.h" #include "GlyphDefinitionTables.h"
#include "GlyphPositioningTables.h" #include "GlyphPositioningTables.h"
#include "GlyphIterator.h" #include "GlyphIterator.h"
...@@ -52,12 +52,17 @@ class GlyphPositioningLookupProcessor : public LookupProcessor ...@@ -52,12 +52,17 @@ class GlyphPositioningLookupProcessor : public LookupProcessor
{ {
public: public:
GlyphPositioningLookupProcessor(const GlyphPositioningTableHeader *glyphPositioningTableHeader, GlyphPositioningLookupProcessor(const GlyphPositioningTableHeader *glyphPositioningTableHeader,
LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder); LETag scriptTag,
LETag languageTag,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode& success);
virtual ~GlyphPositioningLookupProcessor(); virtual ~GlyphPositioningLookupProcessor();
virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance) const; const LEFontInstance *fontInstance, LEErrorCode& success) const;
protected: protected:
GlyphPositioningLookupProcessor(); GlyphPositioningLookupProcessor();
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "LEGlyphFilter.h" #include "LEGlyphFilter.h"
#include "LEFontInstance.h" #include "LEFontInstance.h"
#include "OpenTypeTables.h" #include "OpenTypeTables.h"
#include "Features.h" #include "ICUFeatures.h"
#include "Lookups.h" #include "Lookups.h"
#include "ScriptAndLanguage.h" #include "ScriptAndLanguage.h"
#include "GlyphDefinitionTables.h" #include "GlyphDefinitionTables.h"
...@@ -52,13 +52,19 @@ U_NAMESPACE_BEGIN ...@@ -52,13 +52,19 @@ U_NAMESPACE_BEGIN
GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor( GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor(
const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader, const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader,
LETag scriptTag, LETag languageTag, const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) LETag scriptTag,
LETag languageTag,
const LEGlyphFilter *filter,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode& success)
: LookupProcessor( : LookupProcessor(
(char *) glyphSubstitutionTableHeader, (char *) glyphSubstitutionTableHeader,
SWAPW(glyphSubstitutionTableHeader->scriptListOffset), SWAPW(glyphSubstitutionTableHeader->scriptListOffset),
SWAPW(glyphSubstitutionTableHeader->featureListOffset), SWAPW(glyphSubstitutionTableHeader->featureListOffset),
SWAPW(glyphSubstitutionTableHeader->lookupListOffset), SWAPW(glyphSubstitutionTableHeader->lookupListOffset),
scriptTag, languageTag, featureMap, featureMapCount, featureOrder), fFilter(filter) scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success), fFilter(filter)
{ {
// anything? // anything?
} }
...@@ -68,8 +74,12 @@ GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor() ...@@ -68,8 +74,12 @@ GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor()
} }
le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType,
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
{ {
if (LE_FAILURE(success)) {
return 0;
}
le_uint32 delta = 0; le_uint32 delta = 0;
switch(lookupType) switch(lookupType)
...@@ -89,7 +99,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * ...@@ -89,7 +99,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
{ {
const MultipleSubstitutionSubtable *subtable = (const MultipleSubstitutionSubtable *) lookupSubtable; const MultipleSubstitutionSubtable *subtable = (const MultipleSubstitutionSubtable *) lookupSubtable;
delta = subtable->process(glyphIterator, fFilter); delta = subtable->process(glyphIterator, success, fFilter);
break; break;
} }
...@@ -113,7 +123,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * ...@@ -113,7 +123,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
{ {
const ContextualSubstitutionSubtable *subtable = (const ContextualSubstitutionSubtable *) lookupSubtable; const ContextualSubstitutionSubtable *subtable = (const ContextualSubstitutionSubtable *) lookupSubtable;
delta = subtable->process(this, glyphIterator, fontInstance); delta = subtable->process(this, glyphIterator, fontInstance, success);
break; break;
} }
...@@ -121,7 +131,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * ...@@ -121,7 +131,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
{ {
const ChainingContextualSubstitutionSubtable *subtable = (const ChainingContextualSubstitutionSubtable *) lookupSubtable; const ChainingContextualSubstitutionSubtable *subtable = (const ChainingContextualSubstitutionSubtable *) lookupSubtable;
delta = subtable->process(this, glyphIterator, fontInstance); delta = subtable->process(this, glyphIterator, fontInstance, success);
break; break;
} }
...@@ -129,7 +139,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * ...@@ -129,7 +139,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *
{ {
const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable; const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable;
delta = subtable->process(this, lookupType, glyphIterator, fontInstance); delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
break; break;
} }
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#include "LEFontInstance.h" #include "LEFontInstance.h"
#include "OpenTypeTables.h" #include "OpenTypeTables.h"
#include "Lookups.h" #include "Lookups.h"
#include "Features.h" #include "ICUFeatures.h"
#include "GlyphDefinitionTables.h" #include "GlyphDefinitionTables.h"
#include "GlyphSubstitutionTables.h" #include "GlyphSubstitutionTables.h"
#include "GlyphIterator.h" #include "GlyphIterator.h"
...@@ -53,12 +53,18 @@ class GlyphSubstitutionLookupProcessor : public LookupProcessor ...@@ -53,12 +53,18 @@ class GlyphSubstitutionLookupProcessor : public LookupProcessor
{ {
public: public:
GlyphSubstitutionLookupProcessor(const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader, GlyphSubstitutionLookupProcessor(const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader,
LETag scriptTag, LETag languageTag, const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder); LETag scriptTag,
LETag languageTag,
const LEGlyphFilter *filter,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode& success);
virtual ~GlyphSubstitutionLookupProcessor(); virtual ~GlyphSubstitutionLookupProcessor();
virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
const LEFontInstance *fontInstance) const; const LEFontInstance *fontInstance, LEErrorCode& success) const;
protected: protected:
GlyphSubstitutionLookupProcessor(); GlyphSubstitutionLookupProcessor();
......
...@@ -42,13 +42,23 @@ ...@@ -42,13 +42,23 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag, le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage,
le_bool rightToLeft,
LETag scriptTag,
LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const const LEGlyphFilter *filter,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode &success) const
{ {
GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder); if (LE_FAILURE(success)) {
return 0;
}
return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL); GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success);
return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL, success);
} }
U_NAMESPACE_END U_NAMESPACE_END
...@@ -50,9 +50,16 @@ struct GlyphDefinitionTableHeader; ...@@ -50,9 +50,16 @@ struct GlyphDefinitionTableHeader;
struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader
{ {
le_int32 process(LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag, le_int32 process(LEGlyphStorage &glyphStorage,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEGlyphFilter *filter, le_bool rightToLeft,
const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const; LETag scriptTag,
LETag languageTag,
const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
const LEGlyphFilter *filter,
const FeatureMap *featureMap,
le_int32 featureMapCount,
le_bool featureOrder,
LEErrorCode &success) const;
}; };
enum GlyphSubstitutionSubtableTypes enum GlyphSubstitutionSubtableTypes
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* /*
* HanLayoutEngine.cpp: OpenType processing for Han fonts. * HanLayoutEngine.cpp: OpenType processing for Han fonts.
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved. * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved.
*/ */
#include "LETypes.h" #include "LETypes.h"
...@@ -64,8 +64,8 @@ static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap); ...@@ -64,8 +64,8 @@ static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
#define features (loclFeatureMask) #define features (loclFeatureMask)
HanOpenTypeLayoutEngine::HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, HanOpenTypeLayoutEngine::HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{ {
fFeatureMap = featureMap; fFeatureMap = featureMap;
fFeatureMapCount = featureMapCount; fFeatureMapCount = featureMapCount;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
/* /*
* HanLayoutEngine.h: OpenType processing for Han fonts. * HanLayoutEngine.h: OpenType processing for Han fonts.
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved. * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved.
*/ */
#ifndef __HANLAYOUTENGINE_H #ifndef __HANLAYOUTENGINE_H
...@@ -64,6 +64,7 @@ public: ...@@ -64,6 +64,7 @@ public:
* @param scriptCode - the script * @param scriptCode - the script
* @param langaugeCode - the language * @param langaugeCode - the language
* @param gsubTable - the GSUB table * @param gsubTable - the GSUB table
* @param success - set to an error code if the operation fails
* *
* @see LayoutEngine::layoutEngineFactory * @see LayoutEngine::layoutEngineFactory
* @see OpenTypeLayoutEngine * @see OpenTypeLayoutEngine
...@@ -72,7 +73,7 @@ public: ...@@ -72,7 +73,7 @@ public:
* @internal * @internal
*/ */
HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable); le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTablem, LEErrorCode &success);
/** /**
......
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* HangulLayoutEngine.cpp: OpenType processing for Han fonts.
*
* (C) Copyright IBM Corp. 1998-2010 - 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
{
le_int32 newState;
le_int32 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, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, gsubTable, success)
{
fFeatureMap = featureMap;
fFeatureMapCount = featureMapCount;
fFeatureOrder = TRUE;
}
HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/,
le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, success)
{
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;
le_int32 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, 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, success);
}
if ((transition.actionFlags & AF_V) != 0) {
outChars[outCharCount] = vowel;
glyphStorage.setCharIndex(outCharCount, i-offset, success);
glyphStorage.setAuxData(outCharCount++, vjmoFeatures, success);
}
if ((transition.actionFlags & AF_T) != 0) {
outChars[outCharCount] = trail;
glyphStorage.setCharIndex(outCharCount, i-offset, success);
glyphStorage.setAuxData(outCharCount++, tjmoFeatures, 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, 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, success);
}
}
}
}
glyphStorage.adoptGlyphCount(outCharCount);
return outCharCount;
}
U_NAMESPACE_END
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
*
* (C) Copyright IBM Corp. 1998-2010 - 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
* @param success - set to an error code if the operation fails
*
* @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, LEErrorCode &success);
/**
* 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
* @param success - set to an error code if the operation fails
*
* @see OpenTypeLayoutEngine
* @see ScriptAndLangaugeTags.h for script and language codes
*
* @internal
*/
HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, LEErrorCode &success);
/**
* 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
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
*
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
*
* WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
* YOU REALLY KNOW WHAT YOU'RE DOING.
*
*/
#include "LETypes.h"
#include "HebrewShaping.h"
const le_uint8 HebrewShaping::glyphSubstitutionTable[] = {
0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x1E, 0x00, 0x2C, 0x00, 0x01, 0x68, 0x65, 0x62, 0x72,
0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x6C, 0x69, 0x67, 0x61, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04,
0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x01, 0x62, 0x00, 0x16, 0x00, 0x32,
0x00, 0x4C, 0x00, 0x5E, 0x00, 0x68, 0x00, 0x72, 0x00, 0x7C, 0x00, 0x8E, 0x00, 0x98, 0x00, 0xA2,
0x00, 0xAC, 0x00, 0xB6, 0x00, 0xC8, 0x00, 0xD2, 0x00, 0xDC, 0x00, 0xE6, 0x00, 0xF0, 0x00, 0xFA,
0x01, 0x0C, 0x01, 0x16, 0x01, 0x20, 0x01, 0x2A, 0x01, 0x58, 0x00, 0x03, 0x00, 0x08, 0x00, 0x0E,
0x00, 0x14, 0xFB, 0x2E, 0x00, 0x02, 0x05, 0xB7, 0xFB, 0x2F, 0x00, 0x02, 0x05, 0xB8, 0xFB, 0x30,
0x00, 0x02, 0x05, 0xBC, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0C, 0xFB, 0x31, 0x00, 0x02, 0x05, 0xBC,
0xFB, 0x4C, 0x00, 0x02, 0x05, 0xBF, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x32, 0x00, 0x02, 0x05, 0xBC,
0x00, 0x01, 0x00, 0x04, 0xFB, 0x33, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x34,
0x00, 0x02, 0x05, 0xBC, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0C, 0xFB, 0x4B, 0x00, 0x02, 0x05, 0xB9,
0xFB, 0x35, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x36, 0x00, 0x02, 0x05, 0xBC,
0x00, 0x01, 0x00, 0x04, 0xFB, 0x38, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x39,
0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x3A, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x02,
0x00, 0x06, 0x00, 0x0C, 0xFB, 0x3B, 0x00, 0x02, 0x05, 0xBC, 0xFB, 0x4D, 0x00, 0x02, 0x05, 0xBF,
0x00, 0x01, 0x00, 0x04, 0xFB, 0x3C, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x3E,
0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x40, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01,
0x00, 0x04, 0xFB, 0x41, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x43, 0x00, 0x02,
0x05, 0xBC, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0C, 0xFB, 0x44, 0x00, 0x02, 0x05, 0xBC, 0xFB, 0x4E,
0x00, 0x02, 0x05, 0xBF, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x46, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01,
0x00, 0x04, 0xFB, 0x47, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x04, 0xFB, 0x48, 0x00, 0x02,
0x05, 0xBC, 0x00, 0x05, 0x00, 0x0C, 0x00, 0x14, 0x00, 0x1C, 0x00, 0x22, 0x00, 0x28, 0xFB, 0x2C,
0x00, 0x03, 0x05, 0xBC, 0x05, 0xC1, 0xFB, 0x2D, 0x00, 0x03, 0x05, 0xBC, 0x05, 0xC2, 0xFB, 0x49,
0x00, 0x02, 0x05, 0xBC, 0xFB, 0x2A, 0x00, 0x02, 0x05, 0xC1, 0xFB, 0x2B, 0x00, 0x02, 0x05, 0xC2,
0x00, 0x01, 0x00, 0x04, 0xFB, 0x4A, 0x00, 0x02, 0x05, 0xBC, 0x00, 0x01, 0x00, 0x16, 0x05, 0xD0,
0x05, 0xD1, 0x05, 0xD2, 0x05, 0xD3, 0x05, 0xD4, 0x05, 0xD5, 0x05, 0xD6, 0x05, 0xD8, 0x05, 0xD9,
0x05, 0xDA, 0x05, 0xDB, 0x05, 0xDC, 0x05, 0xDE, 0x05, 0xE0, 0x05, 0xE1, 0x05, 0xE3, 0x05, 0xE4,
0x05, 0xE6, 0x05, 0xE7, 0x05, 0xE8, 0x05, 0xE9, 0x05, 0xEA
};
const le_uint8 HebrewShaping::glyphDefinitionTable[] = {
0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x15,
0x05, 0x91, 0x05, 0xA1, 0x00, 0x03, 0x05, 0xA3, 0x05, 0xB9, 0x00, 0x03, 0x05, 0xBB, 0x05, 0xBD,
0x00, 0x03, 0x05, 0xBE, 0x05, 0xBE, 0x00, 0x01, 0x05, 0xBF, 0x05, 0xBF, 0x00, 0x03, 0x05, 0xC0,
0x05, 0xC0, 0x00, 0x01, 0x05, 0xC1, 0x05, 0xC2, 0x00, 0x03, 0x05, 0xC3, 0x05, 0xC3, 0x00, 0x01,
0x05, 0xC4, 0x05, 0xC4, 0x00, 0x03, 0x05, 0xD0, 0x05, 0xEA, 0x00, 0x01, 0x05, 0xF0, 0x05, 0xF2,
0x00, 0x02, 0x05, 0xF3, 0x05, 0xF4, 0x00, 0x01, 0xFB, 0x1E, 0xFB, 0x1E, 0x00, 0x03, 0xFB, 0x1F,
0xFB, 0x1F, 0x00, 0x02, 0xFB, 0x20, 0xFB, 0x36, 0x00, 0x01, 0xFB, 0x38, 0xFB, 0x3C, 0x00, 0x01,
0xFB, 0x3E, 0xFB, 0x3E, 0x00, 0x01, 0xFB, 0x40, 0xFB, 0x41, 0x00, 0x01, 0xFB, 0x43, 0xFB, 0x44,
0x00, 0x01, 0xFB, 0x46, 0xFB, 0x4E, 0x00, 0x01, 0xFB, 0x4F, 0xFB, 0x4F, 0x00, 0x02
};
...@@ -25,28 +25,45 @@ ...@@ -25,28 +25,45 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998, 1999, 2000 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* *
*/ */
#ifndef __HEBREWSHAPING_H #ifndef __ICUFEATURES_H
#define __HEBREWSHAPING_H #define __ICUFEATURES_H
/**
* \file
* \internal
*/
#include "LETypes.h" #include "LETypes.h"
#include "OpenTypeTables.h" #include "OpenTypeTables.h"
class HebrewShaping U_NAMESPACE_BEGIN
struct FeatureRecord
{
ATag featureTag;
Offset featureTableOffset;
};
struct FeatureTable
{
Offset featureParamsOffset;
le_uint16 lookupCount;
le_uint16 lookupListIndexArray[ANY_NUMBER];
};
struct FeatureListTable
{ {
public: le_uint16 featureCount;
static void shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax, FeatureRecord featureRecordArray[ANY_NUMBER];
le_bool rightToLeft, const LETag **tags);
static const le_uint8 glyphSubstitutionTable[]; const FeatureTable *getFeatureTable(le_uint16 featureIndex, LETag *featureTag) const;
static const le_uint8 glyphDefinitionTable[];
private: const FeatureTable *getFeatureTable(LETag featureTag) const;
// forbid instantiation
HebrewShaping();
}; };
U_NAMESPACE_END
#endif #endif
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* *
*/ */
...@@ -73,6 +73,7 @@ U_NAMESPACE_BEGIN ...@@ -73,6 +73,7 @@ U_NAMESPACE_BEGIN
#define _m2 (CC_SPLIT_VOWEL_PIECE_2 | CF_LENGTH_MARK) #define _m2 (CC_SPLIT_VOWEL_PIECE_2 | CF_LENGTH_MARK)
#define _m3 (CC_SPLIT_VOWEL_PIECE_3 | CF_LENGTH_MARK) #define _m3 (CC_SPLIT_VOWEL_PIECE_3 | CF_LENGTH_MARK)
#define _vr (CC_VIRAMA) #define _vr (CC_VIRAMA)
#define _al (CC_AL_LAKUNA)
// split matras // split matras
#define _s1 (_dv | _x1) #define _s1 (_dv | _x1)
...@@ -90,6 +91,7 @@ U_NAMESPACE_BEGIN ...@@ -90,6 +91,7 @@ U_NAMESPACE_BEGIN
// special forms... (Bengali RA?) // special forms... (Bengali RA?)
#define _bb (_ct | CF_BELOW_BASE) #define _bb (_ct | CF_BELOW_BASE)
#define _pb (_ct | CF_POST_BASE) #define _pb (_ct | CF_POST_BASE)
#define _fb (_ct | CF_PRE_BASE)
#define _vt (_bb | CF_VATTU) #define _vt (_bb | CF_VATTU)
#define _rv (_vt | CF_REPH) #define _rv (_vt | CF_REPH)
#define _rp (_pb | CF_REPH) #define _rp (_pb | CF_REPH)
...@@ -119,7 +121,7 @@ static const IndicClassTable::CharClass bengCharClasses[] = ...@@ -119,7 +121,7 @@ static const IndicClassTable::CharClass bengCharClasses[] =
_dr, _db, _db, _db, _db, _xx, _xx, _l1, _dl, _xx, _xx, _s1, _s2, _vr, _xx, _xx, // 09C0 - 09CF _dr, _db, _db, _db, _db, _xx, _xx, _l1, _dl, _xx, _xx, _s1, _s2, _vr, _xx, _xx, // 09C0 - 09CF
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _cn, _cn, _xx, _cn, // 09D0 - 09DF _xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _cn, _cn, _xx, _cn, // 09D0 - 09DF
_iv, _iv, _dv, _dv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 09E0 - 09EF _iv, _iv, _dv, _dv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 09E0 - 09EF
_ct, _ct, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 09F0 - 09FA _rv, _ct, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 09F0 - 09FA
}; };
static const IndicClassTable::CharClass punjCharClasses[] = static const IndicClassTable::CharClass punjCharClasses[] =
...@@ -142,9 +144,22 @@ static const IndicClassTable::CharClass gujrCharClasses[] = ...@@ -142,9 +144,22 @@ static const IndicClassTable::CharClass gujrCharClasses[] =
_rv, _xx, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _nu, _xx, _dr, _dl, // 0AB0 - 0ABF _rv, _xx, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _nu, _xx, _dr, _dl, // 0AB0 - 0ABF
_dr, _db, _db, _db, _db, _da, _xx, _da, _da, _dr, _xx, _dr, _dr, _vr, _xx, _xx, // 0AC0 - 0ACF _dr, _db, _db, _db, _db, _da, _xx, _da, _da, _dr, _xx, _dr, _dr, _vr, _xx, _xx, // 0AC0 - 0ACF
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0AD0 - 0ADF _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0AD0 - 0ADF
_iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0AE0 - 0AEF _iv, _iv, _db, _db, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0AE0 - 0AEF
}; };
#if 1
static const IndicClassTable::CharClass oryaCharClasses[] =
{
_xx, _ma, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _iv, /* 0B00 - 0B0F */
_iv, _xx, _xx, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _ct, _bb, /* 0B10 - 0B1F */
_bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _pb, /* 0B20 - 0B2F */
_rb, _xx, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _nu, _xx, _dr, _da, /* 0B30 - 0B3F */
_dr, _db, _db, _db, _xx, _xx, _xx, _dl, _s1, _xx, _xx, _s2, _s3, _vr, _xx, _xx, /* 0B40 - 0B4F */
_xx, _xx, _xx, _xx, _xx, _xx, _da, _dr, _xx, _xx, _xx, _xx, _cn, _cn, _xx, _pb, /* 0B50 - 0B5F */
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, /* 0B60 - 0B6F */
_xx, _bb /* 0B70 - 0B71 */
};
#else
static const IndicClassTable::CharClass oryaCharClasses[] = static const IndicClassTable::CharClass oryaCharClasses[] =
{ {
_xx, _ma, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _iv, // 0B00 - 0B0F _xx, _ma, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _iv, // 0B00 - 0B0F
...@@ -156,13 +171,14 @@ static const IndicClassTable::CharClass oryaCharClasses[] = ...@@ -156,13 +171,14 @@ static const IndicClassTable::CharClass oryaCharClasses[] =
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0B60 - 0B6F _iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0B60 - 0B6F
_xx, _ct // 0B70 - 0B71 _xx, _ct // 0B70 - 0B71
}; };
#endif
static const IndicClassTable::CharClass tamlCharClasses[] = 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 _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 _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 _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _xx, _r2, _dr, // 0BB0 - 0BBF
_da, _dr, _dr, _xx, _xx, _xx, _l1, _l1, _dl, _xx, _s1, _s2, _s3, _vr, _xx, _xx, // 0BC0 - 0BCF _da, _dr, _dr, _xx, _xx, _xx, _l1, _l1, _dl, _xx, _s1, _s2, _s3, _vr, _xx, _xx, // 0BC0 - 0BCF
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0BD0 - 0BDF _xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0BD0 - 0BDF
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0BE0 - 0BEF _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0BE0 - 0BEF
...@@ -175,7 +191,7 @@ static const IndicClassTable::CharClass teluCharClasses[] = ...@@ -175,7 +191,7 @@ static const IndicClassTable::CharClass teluCharClasses[] =
_xx, _mp, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0C00 - 0C0F _xx, _mp, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0C00 - 0C0F
_iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C10 - 0C1F _iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C10 - 0C1F
_bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0C20 - 0C2F _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0C20 - 0C2F
_bb, _ct, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _da, _da, // 0C30 - 0C3F _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _da, _da, // 0C30 - 0C3F
_da, _dr, _dr, _dr, _dr, _xx, _a1, _da, _s1, _xx, _da, _da, _da, _vr, _xx, _xx, // 0C40 - 0C4F _da, _dr, _dr, _dr, _dr, _xx, _a1, _da, _s1, _xx, _da, _da, _da, _vr, _xx, _xx, // 0C40 - 0C4F
_xx, _xx, _xx, _xx, _xx, _da, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0C50 - 0C5F _xx, _xx, _xx, _xx, _xx, _da, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0C50 - 0C5F
_iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0C60 - 0C6F _iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0C60 - 0C6F
...@@ -189,7 +205,7 @@ static const IndicClassTable::CharClass teluCharClasses[] = ...@@ -189,7 +205,7 @@ static const IndicClassTable::CharClass teluCharClasses[] =
// http://brahmi.sourceforge.net/docs/KannadaComputing.html // http://brahmi.sourceforge.net/docs/KannadaComputing.html
static const IndicClassTable::CharClass kndaCharClasses[] = static const IndicClassTable::CharClass kndaCharClasses[] =
{ {
_xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, // 0C80 - 0C8F _xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0C80 - 0C8F
_iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C90 - 0C9F _iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C90 - 0C9F
_bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0CA0 - 0CAF _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0CA0 - 0CAF
_rb, _ct, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _dr, _da, // 0CB0 - 0CBF _rb, _ct, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _dr, _da, // 0CB0 - 0CBF
...@@ -203,9 +219,9 @@ static const IndicClassTable::CharClass kndaCharClasses[] = ...@@ -203,9 +219,9 @@ static const IndicClassTable::CharClass kndaCharClasses[] =
static const IndicClassTable::CharClass mlymCharClasses[] = static const IndicClassTable::CharClass mlymCharClasses[] =
{ {
_xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0D00 - 0D0F _xx, _xx, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0D00 - 0D0F
_iv, _xx, _iv, _iv, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _bb, // 0D10 - 0D1F _iv, _xx, _iv, _iv, _iv, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, // 0D10 - 0D1F
_ct, _ct, _ct, _bb, _ct, _bb, _bb, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _pb, // 0D20 - 0D2F _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _ct, _ct, _ct, _ct, _ct, _pb, // 0D20 - 0D2F
_pb, _cn, _bb, _ct, _ct, _pb, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _xx, _r2, _dr, // 0D30 - 0D3F _fb, _fb, _bb, _ct, _ct, _pb, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _xx, _r2, _dr, // 0D30 - 0D3F
_dr, _dr, _dr, _dr, _xx, _xx, _l1, _l1, _dl, _xx, _s1, _s2, _s3, _vr, _xx, _xx, // 0D40 - 0D4F _dr, _dr, _dr, _dr, _xx, _xx, _l1, _l1, _dl, _xx, _s1, _s2, _s3, _vr, _xx, _xx, // 0D40 - 0D4F
_xx, _xx, _xx, _xx, _xx, _xx, _xx, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0D50 - 0D5F _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 _iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0D60 - 0D6F
...@@ -217,7 +233,7 @@ static const IndicClassTable::CharClass sinhCharClasses[] = ...@@ -217,7 +233,7 @@ static const IndicClassTable::CharClass sinhCharClasses[] =
_iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _xx, _xx, _ct, _ct, _ct, _ct, _ct, _ct, // 0D90 - 0D9F _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, _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, _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 _ct, _ct, _ct, _ct, _ct, _ct, _ct, _xx, _xx, _xx, _al, _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 _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, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0DE0 - 0DEF
_xx, _xx, _dr, _dr, _xx // 0DF0 - 0DF4 _xx, _xx, _dr, _dr, _xx // 0DF0 - 0DF4
...@@ -248,17 +264,18 @@ static const SplitMatra sinhSplitTable[] = {{0x0DD9, 0x0DCA}, {0x0DD9, 0x0DCF}, ...@@ -248,17 +264,18 @@ static const SplitMatra sinhSplitTable[] = {{0x0DD9, 0x0DCA}, {0x0DD9, 0x0DCF},
// FIXME: post 'GSUB' reordering of MATRA_PRE's for Malayalam and Tamil // FIXME: post 'GSUB' reordering of MATRA_PRE's for Malayalam and Tamil
// FIXME: reformed Malayalam needs to reorder VATTU to before base glyph... // FIXME: reformed Malayalam needs to reorder VATTU to before base glyph...
// FIXME: not sure passing ZWJ/ZWNJ is best way to render Malayalam Cillu...
// FIXME: eyelash RA only for Devanagari?? // FIXME: eyelash RA only for Devanagari??
#define DEVA_SCRIPT_FLAGS (SF_EYELASH_RA | 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) #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) #define PUNJ_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
#define GUJR_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT) #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) #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) #define TAML_SCRIPT_FLAGS (SF_MPRE_FIXUP | SF_NO_POST_BASE_LIMIT | SF_FILTER_ZERO_WIDTH)
#define TELU_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | 3) #define TELU_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | SF_FILTER_ZERO_WIDTH | 3)
#define KNDA_SCRIPT_FLAGS (SF_MATRAS_AFTER_BASE | 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) #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) #define SINH_SCRIPT_FLAGS (SF_NO_POST_BASE_LIMIT)
// //
// Indic Class Tables // Indic Class Tables
...@@ -286,7 +303,7 @@ static const IndicClassTable sinhClassTable = {0x0D80, 0x0DF4, 4, SINH_SCRIPT_FL ...@@ -286,7 +303,7 @@ static const IndicClassTable sinhClassTable = {0x0D80, 0x0DF4, 4, SINH_SCRIPT_FL
// //
// IndicClassTable addresses // IndicClassTable addresses
// //
static const IndicClassTable * const indicClassTables[] = { static const IndicClassTable * const indicClassTables[scriptCodeCount] = {
NULL, /* 'zyyy' (COMMON) */ NULL, /* 'zyyy' (COMMON) */
NULL, /* 'qaai' (INHERITED) */ NULL, /* 'qaai' (INHERITED) */
NULL, /* 'arab' (ARABIC) */ NULL, /* 'arab' (ARABIC) */
...@@ -348,7 +365,79 @@ static const IndicClassTable * const indicClassTables[] = { ...@@ -348,7 +365,79 @@ static const IndicClassTable * const indicClassTables[] = {
NULL, /* 'sylo' (SYLOTI_NAGRI) */ NULL, /* 'sylo' (SYLOTI_NAGRI) */
NULL, /* 'talu' (NEW_TAI_LUE) */ NULL, /* 'talu' (NEW_TAI_LUE) */
NULL, /* 'tfng' (TIFINAGH) */ NULL, /* 'tfng' (TIFINAGH) */
NULL /* 'xpeo' (OLD_PERSIAN) */ 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) */
NULL, /* 'cari' (CARI) */
NULL, /* 'jpan' (JPAN) */
NULL, /* 'lana' (LANA) */
NULL, /* 'lyci' (LYCI) */
NULL, /* 'lydi' (LYDI) */
NULL, /* 'olck' (OLCK) */
NULL, /* 'rjng' (RJNG) */
NULL, /* 'saur' (SAUR) */
NULL, /* 'sgnw' (SGNW) */
NULL, /* 'sund' (SUND) */
NULL, /* 'moon' (MOON) */
NULL, /* 'mtei' (MTEI) */
NULL, /* 'armi' (ARMI) */
NULL, /* 'avst' (AVST) */
NULL, /* 'cakm' (CAKM) */
NULL, /* 'kore' (KORE) */
NULL, /* 'kthi' (KTHI) */
NULL, /* 'mani' (MANI) */
NULL, /* 'phli' (PHLI) */
NULL, /* 'phlp' (PHLP) */
NULL, /* 'phlv' (PHLV) */
NULL, /* 'prti' (PRTI) */
NULL, /* 'samr' (SAMR) */
NULL, /* 'tavt' (TAVT) */
NULL, /* 'zmth' (ZMTH) */
NULL, /* 'zsym' (ZSYM) */
NULL, /* 'bamu' (BAMUM) */
NULL, /* 'lisu' (LISU) */
NULL, /* 'nkgb' (NKGB) */
NULL /* 'sarb' (OLD_SOUTH_ARABIAN) */
}; };
IndicClassTable::CharClass IndicClassTable::getCharClass(LEUnicode ch) const IndicClassTable::CharClass IndicClassTable::getCharClass(LEUnicode ch) const
...@@ -388,4 +477,15 @@ le_int32 IndicReordering::getWorstCaseExpansion(le_int32 scriptCode) ...@@ -388,4 +477,15 @@ le_int32 IndicReordering::getWorstCaseExpansion(le_int32 scriptCode)
return classTable->getWorstCaseExpansion(); 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 U_NAMESPACE_END
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
* *
*/ */
...@@ -44,24 +44,31 @@ ...@@ -44,24 +44,31 @@
#include "LEGlyphStorage.h" #include "LEGlyphStorage.h"
#include "IndicReordering.h" #include "IndicReordering.h"
#include <stdio.h>
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable), fMPreFixups(NULL) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL)
{ {
if ( version2 ) {
fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount);
} else {
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount); fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
}
fFeatureOrder = TRUE; fFeatureOrder = TRUE;
fVersion2 = version2;
fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode);
} }
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags) IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fMPreFixups(NULL) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMPreFixups(NULL)
{ {
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount); fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE; fFeatureOrder = TRUE;
fVersion2 = FALSE;
} }
IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine() IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine()
...@@ -89,8 +96,13 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_ ...@@ -89,8 +96,13 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
return 0; return 0;
} }
IndicReordering::adjustMPres(fMPreFixups, glyphStorage); if (fVersion2) {
IndicReordering::finalReordering(glyphStorage,retCount);
IndicReordering::applyPresentationForms(glyphStorage,retCount);
OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success);
} else {
IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success);
}
return retCount; return retCount;
} }
...@@ -128,7 +140,18 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], ...@@ -128,7 +140,18 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
// NOTE: assumes this allocates featureTags... // NOTE: assumes this allocates featureTags...
// (probably better than doing the worst case stuff here...) // (probably better than doing the worst case stuff here...)
le_int32 outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups);
le_int32 outCharCount;
if (fVersion2) {
outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage);
} else {
outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success);
}
if (LE_FAILURE(success)) {
LE_DELETE_ARRAY(outChars);
return 0;
}
glyphStorage.adoptGlyphCount(outCharCount); glyphStorage.adoptGlyphCount(outCharCount);
return outCharCount; return outCharCount;
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
* *
*/ */
...@@ -72,6 +72,7 @@ public: ...@@ -72,6 +72,7 @@ public:
* @param scriptCode - the script * @param scriptCode - the script
* @param langaugeCode - the language * @param langaugeCode - the language
* @param gsubTable - the GSUB table * @param gsubTable - the GSUB table
* @param success - set to an error code if the operation fails
* *
* @see LayoutEngine::layoutEngineFactory * @see LayoutEngine::layoutEngineFactory
* @see OpenTypeLayoutEngine * @see OpenTypeLayoutEngine
...@@ -80,7 +81,7 @@ public: ...@@ -80,7 +81,7 @@ public:
* @internal * @internal
*/ */
IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable); le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
/** /**
* This constructor is used when the font requires a "canned" GSUB table which can't be known * This constructor is used when the font requires a "canned" GSUB table which can't be known
...@@ -89,6 +90,7 @@ public: ...@@ -89,6 +90,7 @@ public:
* @param fontInstance - the font * @param fontInstance - the font
* @param scriptCode - the script * @param scriptCode - the script
* @param langaugeCode - the language * @param langaugeCode - the language
* @param success - set to an error code if the operation fails
* *
* @see OpenTypeLayoutEngine * @see OpenTypeLayoutEngine
* @see ScriptAndLangaugeTags.h for script and language codes * @see ScriptAndLangaugeTags.h for script and language codes
...@@ -96,7 +98,7 @@ public: ...@@ -96,7 +98,7 @@ public:
* @internal * @internal
*/ */
IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags); le_int32 typoFlags, LEErrorCode &success);
/** /**
* The destructor, virtual for correct polymorphic invocation. * The destructor, virtual for correct polymorphic invocation.
...@@ -177,9 +179,12 @@ protected: ...@@ -177,9 +179,12 @@ protected:
virtual le_int32 glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, virtual le_int32 glyphProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
LEGlyphStorage &glyphStorage, LEErrorCode &success); LEGlyphStorage &glyphStorage, LEErrorCode &success);
le_bool fVersion2;
private: private:
MPreFixups *fMPreFixups; MPreFixups *fMPreFixups;
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
* *
*/ */
...@@ -62,7 +62,8 @@ U_NAMESPACE_BEGIN ...@@ -62,7 +62,8 @@ U_NAMESPACE_BEGIN
#define CC_SPLIT_VOWEL_PIECE_3 12U #define CC_SPLIT_VOWEL_PIECE_3 12U
#define CC_VIRAMA 13U #define CC_VIRAMA 13U
#define CC_ZERO_WIDTH_MARK 14U #define CC_ZERO_WIDTH_MARK 14U
#define CC_COUNT 15U #define CC_AL_LAKUNA 15U
#define CC_COUNT 16U
// Character class flags // Character class flags
#define CF_CLASS_MASK 0x0000FFFFU #define CF_CLASS_MASK 0x0000FFFFU
...@@ -74,6 +75,7 @@ U_NAMESPACE_BEGIN ...@@ -74,6 +75,7 @@ U_NAMESPACE_BEGIN
#define CF_BELOW_BASE 0x10000000U #define CF_BELOW_BASE 0x10000000U
#define CF_POST_BASE 0x08000000U #define CF_POST_BASE 0x08000000U
#define CF_LENGTH_MARK 0x04000000U #define CF_LENGTH_MARK 0x04000000U
#define CF_PRE_BASE 0x02000000U
#define CF_POS_BEFORE 0x00300000U #define CF_POS_BEFORE 0x00300000U
#define CF_POS_BELOW 0x00200000U #define CF_POS_BELOW 0x00200000U
...@@ -89,6 +91,7 @@ U_NAMESPACE_BEGIN ...@@ -89,6 +91,7 @@ U_NAMESPACE_BEGIN
#define SF_REPH_AFTER_BELOW 0x40000000U #define SF_REPH_AFTER_BELOW 0x40000000U
#define SF_EYELASH_RA 0x20000000U #define SF_EYELASH_RA 0x20000000U
#define SF_MPRE_FIXUP 0x10000000U #define SF_MPRE_FIXUP 0x10000000U
#define SF_FILTER_ZERO_WIDTH 0x08000000U
#define SF_POST_BASE_LIMIT_MASK 0x0000FFFFU #define SF_POST_BASE_LIMIT_MASK 0x0000FFFFU
#define SF_NO_POST_BASE_LIMIT 0x00007FFFU #define SF_NO_POST_BASE_LIMIT 0x00007FFFU
...@@ -98,6 +101,15 @@ typedef LEUnicode SplitMatra[3]; ...@@ -98,6 +101,15 @@ typedef LEUnicode SplitMatra[3];
class MPreFixups; class MPreFixups;
class LEGlyphStorage; class LEGlyphStorage;
// Dynamic Properties ( v2 fonts only )
typedef le_uint32 DynamicProperties;
#define DP_REPH 0x80000000U
#define DP_HALF 0x40000000U
#define DP_PREF 0x20000000U
#define DP_BLWF 0x10000000U
#define DP_PSTF 0x08000000U
struct IndicClassTable struct IndicClassTable
{ {
typedef le_uint32 CharClass; typedef le_uint32 CharClass;
...@@ -111,6 +123,7 @@ struct IndicClassTable ...@@ -111,6 +123,7 @@ struct IndicClassTable
const SplitMatra *splitMatraTable; const SplitMatra *splitMatraTable;
inline le_int32 getWorstCaseExpansion() const; inline le_int32 getWorstCaseExpansion() const;
inline le_bool getFilterZeroWidth() const;
CharClass getCharClass(LEUnicode ch) const; CharClass getCharClass(LEUnicode ch) const;
...@@ -121,6 +134,7 @@ struct IndicClassTable ...@@ -121,6 +134,7 @@ struct IndicClassTable
inline le_bool isConsonant(LEUnicode ch) const; inline le_bool isConsonant(LEUnicode ch) const;
inline le_bool isReph(LEUnicode ch) const; inline le_bool isReph(LEUnicode ch) const;
inline le_bool isVirama(LEUnicode ch) const; inline le_bool isVirama(LEUnicode ch) const;
inline le_bool isAlLakuna(LEUnicode ch) const;
inline le_bool isNukta(LEUnicode ch) const; inline le_bool isNukta(LEUnicode ch) const;
inline le_bool isVattu(LEUnicode ch) const; inline le_bool isVattu(LEUnicode ch) const;
inline le_bool isMatra(LEUnicode ch) const; inline le_bool isMatra(LEUnicode ch) const;
...@@ -129,12 +143,15 @@ struct IndicClassTable ...@@ -129,12 +143,15 @@ struct IndicClassTable
inline le_bool hasPostOrBelowBaseForm(LEUnicode ch) const; inline le_bool hasPostOrBelowBaseForm(LEUnicode ch) const;
inline le_bool hasPostBaseForm(LEUnicode ch) const; inline le_bool hasPostBaseForm(LEUnicode ch) const;
inline le_bool hasBelowBaseForm(LEUnicode ch) const; inline le_bool hasBelowBaseForm(LEUnicode ch) const;
inline le_bool hasAboveBaseForm(LEUnicode ch) const;
inline le_bool hasPreBaseForm(LEUnicode ch) const;
inline static le_bool isVowelModifier(CharClass charClass); inline static le_bool isVowelModifier(CharClass charClass);
inline static le_bool isStressMark(CharClass charClass); inline static le_bool isStressMark(CharClass charClass);
inline static le_bool isConsonant(CharClass charClass); inline static le_bool isConsonant(CharClass charClass);
inline static le_bool isReph(CharClass charClass); inline static le_bool isReph(CharClass charClass);
inline static le_bool isVirama(CharClass charClass); inline static le_bool isVirama(CharClass charClass);
inline static le_bool isAlLakuna(CharClass charClass);
inline static le_bool isNukta(CharClass charClass); inline static le_bool isNukta(CharClass charClass);
inline static le_bool isVattu(CharClass charClass); inline static le_bool isVattu(CharClass charClass);
inline static le_bool isMatra(CharClass charClass); inline static le_bool isMatra(CharClass charClass);
...@@ -143,6 +160,8 @@ struct IndicClassTable ...@@ -143,6 +160,8 @@ struct IndicClassTable
inline static le_bool hasPostOrBelowBaseForm(CharClass charClass); inline static le_bool hasPostOrBelowBaseForm(CharClass charClass);
inline static le_bool hasPostBaseForm(CharClass charClass); inline static le_bool hasPostBaseForm(CharClass charClass);
inline static le_bool hasBelowBaseForm(CharClass charClass); inline static le_bool hasBelowBaseForm(CharClass charClass);
inline static le_bool hasAboveBaseForm(CharClass charClass);
inline static le_bool hasPreBaseForm(CharClass charClass);
static const IndicClassTable *getScriptClassTable(le_int32 scriptCode); static const IndicClassTable *getScriptClassTable(le_int32 scriptCode);
}; };
...@@ -151,14 +170,27 @@ class IndicReordering /* not : public UObject because all methods are static */ ...@@ -151,14 +170,27 @@ class IndicReordering /* not : public UObject because all methods are static */
public: public:
static le_int32 getWorstCaseExpansion(le_int32 scriptCode); 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, static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
LEUnicode *outChars, LEGlyphStorage &glyphStorage, LEUnicode *outChars, LEGlyphStorage &glyphStorage,
MPreFixups **outMPreFixups); MPreFixups **outMPreFixups, LEErrorCode& success);
static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage, LEErrorCode& success);
static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage); static le_int32 v2process(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode,
LEUnicode *outChars, LEGlyphStorage &glyphStorage);
static const FeatureMap *getFeatureMap(le_int32 &count); static const FeatureMap *getFeatureMap(le_int32 &count);
static const FeatureMap *getv2FeatureMap(le_int32 &count);
static void applyPresentationForms(LEGlyphStorage &glyphStorage, le_int32 count);
static void finalReordering(LEGlyphStorage &glyphStorage, le_int32 count);
static void getDynamicProperties(DynamicProperties *dProps, const IndicClassTable *classTable);
private: private:
// do not instantiate // do not instantiate
IndicReordering(); IndicReordering();
...@@ -172,6 +204,11 @@ inline le_int32 IndicClassTable::getWorstCaseExpansion() const ...@@ -172,6 +204,11 @@ inline le_int32 IndicClassTable::getWorstCaseExpansion() const
return worstCaseExpansion; return worstCaseExpansion;
} }
inline le_bool IndicClassTable::getFilterZeroWidth() const
{
return (scriptFlags & SF_FILTER_ZERO_WIDTH) != 0;
}
inline const SplitMatra *IndicClassTable::getSplitMatra(CharClass charClass) const inline const SplitMatra *IndicClassTable::getSplitMatra(CharClass charClass) const
{ {
le_int32 index = (charClass & CF_INDEX_MASK) >> CF_INDEX_SHIFT; le_int32 index = (charClass & CF_INDEX_MASK) >> CF_INDEX_SHIFT;
...@@ -209,6 +246,11 @@ inline le_bool IndicClassTable::isVirama(CharClass charClass) ...@@ -209,6 +246,11 @@ inline le_bool IndicClassTable::isVirama(CharClass charClass)
return (charClass & CF_CLASS_MASK) == CC_VIRAMA; return (charClass & CF_CLASS_MASK) == CC_VIRAMA;
} }
inline le_bool IndicClassTable::isAlLakuna(CharClass charClass)
{
return (charClass & CF_CLASS_MASK) == CC_AL_LAKUNA;
}
inline le_bool IndicClassTable::isVattu(CharClass charClass) inline le_bool IndicClassTable::isVattu(CharClass charClass)
{ {
return (charClass & CF_VATTU) != 0; return (charClass & CF_VATTU) != 0;
...@@ -241,11 +283,21 @@ inline le_bool IndicClassTable::hasPostBaseForm(CharClass charClass) ...@@ -241,11 +283,21 @@ inline le_bool IndicClassTable::hasPostBaseForm(CharClass charClass)
return (charClass & CF_POST_BASE) != 0; return (charClass & CF_POST_BASE) != 0;
} }
inline le_bool IndicClassTable::hasPreBaseForm(CharClass charClass)
{
return (charClass & CF_PRE_BASE) != 0;
}
inline le_bool IndicClassTable::hasBelowBaseForm(CharClass charClass) inline le_bool IndicClassTable::hasBelowBaseForm(CharClass charClass)
{ {
return (charClass & CF_BELOW_BASE) != 0; return (charClass & CF_BELOW_BASE) != 0;
} }
inline le_bool IndicClassTable::hasAboveBaseForm(CharClass charClass)
{
return ((charClass & CF_POS_MASK) == CF_POS_ABOVE);
}
inline le_bool IndicClassTable::isVowelModifier(LEUnicode ch) const inline le_bool IndicClassTable::isVowelModifier(LEUnicode ch) const
{ {
return isVowelModifier(getCharClass(ch)); return isVowelModifier(getCharClass(ch));
...@@ -271,6 +323,11 @@ inline le_bool IndicClassTable::isVirama(LEUnicode ch) const ...@@ -271,6 +323,11 @@ inline le_bool IndicClassTable::isVirama(LEUnicode ch) const
return isVirama(getCharClass(ch)); return isVirama(getCharClass(ch));
} }
inline le_bool IndicClassTable::isAlLakuna(LEUnicode ch) const
{
return isAlLakuna(getCharClass(ch));
}
inline le_bool IndicClassTable::isNukta(LEUnicode ch) const inline le_bool IndicClassTable::isNukta(LEUnicode ch) const
{ {
return isNukta(getCharClass(ch)); return isNukta(getCharClass(ch));
...@@ -311,5 +368,14 @@ inline le_bool IndicClassTable::hasBelowBaseForm(LEUnicode ch) const ...@@ -311,5 +368,14 @@ inline le_bool IndicClassTable::hasBelowBaseForm(LEUnicode ch) const
return hasBelowBaseForm(getCharClass(ch)); return hasBelowBaseForm(getCharClass(ch));
} }
inline le_bool IndicClassTable::hasPreBaseForm(LEUnicode ch) const
{
return hasPreBaseForm(getCharClass(ch));
}
inline le_bool IndicClassTable::hasAboveBaseForm(LEUnicode ch) const
{
return hasAboveBaseForm(getCharClass(ch));
}
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* /*
* *
* *
* (C) Copyright IBM Corp. 2004-2005 - All Rights Reserved * (C) Copyright IBM Corp. 2004-2010 - All Rights Reserved
* *
*/ */
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "LEGlyphStorage.h" #include "LEGlyphStorage.h"
#include "LESwaps.h" #include "LESwaps.h"
#include "OpenTypeUtilities.h"
#include <stdio.h> #include <stdio.h>
...@@ -91,8 +92,8 @@ struct KernTableHeader { ...@@ -91,8 +92,8 @@ struct KernTableHeader {
* TODO: support multiple subtables * TODO: support multiple subtables
* TODO: respect header flags * TODO: respect header flags
*/ */
KernTable::KernTable(const LEFontInstance* font, const void* tableData) KernTable::KernTable(const LEFontInstance* font_, const void* tableData)
: pairs(0), font(font) : pairs(0), font(font_)
{ {
const KernTableHeader* header = (const KernTableHeader*)tableData; const KernTableHeader* header = (const KernTableHeader*)tableData;
if (header == 0) { if (header == 0) {
...@@ -120,10 +121,18 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData) ...@@ -120,10 +121,18 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData)
coverage = SWAPW(subhead->coverage); coverage = SWAPW(subhead->coverage);
if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning
const Subtable_0* table = (const Subtable_0*)((char*)subhead + KERN_SUBTABLE_HEADER_SIZE); const Subtable_0* table = (const Subtable_0*)((char*)subhead + KERN_SUBTABLE_HEADER_SIZE);
nPairs = SWAPW(table->nPairs);
searchRange = SWAPW(table->searchRange) / KERN_PAIRINFO_SIZE ; nPairs = SWAPW(table->nPairs);
#if 0 // some old fonts have bad values here...
searchRange = SWAPW(table->searchRange);
entrySelector = SWAPW(table->entrySelector); entrySelector = SWAPW(table->entrySelector);
rangeShift = SWAPW(table->rangeShift) / KERN_PAIRINFO_SIZE; rangeShift = SWAPW(table->rangeShift);
#else
entrySelector = OpenTypeUtilities::highBit(nPairs);
searchRange = (1 << entrySelector) * KERN_PAIRINFO_SIZE;
rangeShift = (nPairs * KERN_PAIRINFO_SIZE) - searchRange;
#endif
pairs = (PairInfo*)font->getKernPairs(); pairs = (PairInfo*)font->getKernPairs();
if (pairs == NULL) { if (pairs == NULL) {
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/* /*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* *
* This file is a modification of the ICU file IndicLayoutEngine.cpp * This file is a modification of the ICU file IndicLayoutEngine.cpp
* by Jens Herden and Javier Sola for Khmer language * by Jens Herden and Javier Sola for Khmer language
...@@ -43,16 +43,16 @@ U_NAMESPACE_BEGIN ...@@ -43,16 +43,16 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine)
KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable) le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{ {
fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount); fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE; fFeatureOrder = TRUE;
} }
KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags) le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{ {
fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount); fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE; fFeatureOrder = TRUE;
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
* *
* This file is a modification of the ICU file IndicLayoutEngine.h * This file is a modification of the ICU file IndicLayoutEngine.h
* by Jens Herden and Javier Sola for Khmer language * by Jens Herden and Javier Sola for Khmer language
...@@ -72,8 +72,9 @@ public: ...@@ -72,8 +72,9 @@ public:
* *
* @param fontInstance - the font * @param fontInstance - the font
* @param scriptCode - the script * @param scriptCode - the script
* @param languageCode - the language * @param langaugeCode - the language
* @param gsubTable - the GSUB table * @param gsubTable - the GSUB table
* @param success - set to an error code if the operation fails
* *
* @see LayoutEngine::layoutEngineFactory * @see LayoutEngine::layoutEngineFactory
* @see OpenTypeLayoutEngine * @see OpenTypeLayoutEngine
...@@ -82,7 +83,7 @@ public: ...@@ -82,7 +83,7 @@ public:
* @internal * @internal
*/ */
KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable); le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
/** /**
* This constructor is used when the font requires a "canned" GSUB table which can't be known * This constructor is used when the font requires a "canned" GSUB table which can't be known
...@@ -91,6 +92,7 @@ public: ...@@ -91,6 +92,7 @@ public:
* @param fontInstance - the font * @param fontInstance - the font
* @param scriptCode - the script * @param scriptCode - the script
* @param langaugeCode - the language * @param langaugeCode - the language
* @param success - set to an error code if the operation fails
* *
* @see OpenTypeLayoutEngine * @see OpenTypeLayoutEngine
* @see ScriptAndLangaugeTags.h for script and language codes * @see ScriptAndLangaugeTags.h for script and language codes
...@@ -98,7 +100,7 @@ public: ...@@ -98,7 +100,7 @@ public:
* @internal * @internal
*/ */
KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags); le_int32 typoFlags, LEErrorCode &success);
/** /**
* The destructor, virtual for correct polymorphic invocation. * The destructor, virtual for correct polymorphic invocation.
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
* *
* This file is a modification of the ICU file IndicReordering.cpp * This file is a modification of the ICU file IndicReordering.cpp
* by Jens Herden and Javier Sola for Khmer language * by Jens Herden and Javier Sola for Khmer language
...@@ -149,8 +149,9 @@ const KhmerClassTable *KhmerClassTable::getKhmerClassTable() ...@@ -149,8 +149,9 @@ const KhmerClassTable *KhmerClassTable::getKhmerClassTable()
class ReorderingOutput : public UMemory { class KhmerReorderingOutput : public UMemory {
private: private:
le_int32 fSyllableCount;
le_int32 fOutIndex; le_int32 fOutIndex;
LEUnicode *fOutChars; LEUnicode *fOutChars;
...@@ -158,17 +159,22 @@ private: ...@@ -158,17 +159,22 @@ private:
public: public:
ReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage) KhmerReorderingOutput(LEUnicode *outChars, LEGlyphStorage &glyphStorage)
: fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage) : fSyllableCount(0), fOutIndex(0), fOutChars(outChars), fGlyphStorage(glyphStorage)
{ {
// nothing else to do... // nothing else to do...
} }
~ReorderingOutput() ~KhmerReorderingOutput()
{ {
// nothing to do here... // nothing to do here...
} }
void reset()
{
fSyllableCount += 1;
}
void writeChar(LEUnicode ch, le_uint32 charIndex, FeatureMask charFeatures) void writeChar(LEUnicode ch, le_uint32 charIndex, FeatureMask charFeatures)
{ {
LEErrorCode success = LE_NO_ERROR; LEErrorCode success = LE_NO_ERROR;
...@@ -176,7 +182,7 @@ public: ...@@ -176,7 +182,7 @@ public:
fOutChars[fOutIndex] = ch; fOutChars[fOutIndex] = ch;
fGlyphStorage.setCharIndex(fOutIndex, charIndex, success); fGlyphStorage.setCharIndex(fOutIndex, charIndex, success);
fGlyphStorage.setAuxData(fOutIndex, charFeatures, success); fGlyphStorage.setAuxData(fOutIndex, charFeatures | (fSyllableCount & LE_GLYPH_GROUP_MASK), success);
fOutIndex += 1; fOutIndex += 1;
} }
...@@ -328,12 +334,12 @@ static const le_int8 khmerStateTable[][KhmerClassTable::CC_COUNT] = ...@@ -328,12 +334,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, -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, 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, 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, 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}, // 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, 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, 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, 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}, // 19 - Third coeng
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, // 20 - dependent vowel after a Robat {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, // 20 - dependent vowel after a Robat
...@@ -380,7 +386,7 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le ...@@ -380,7 +386,7 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
{ {
const KhmerClassTable *classTable = KhmerClassTable::getKhmerClassTable(); const KhmerClassTable *classTable = KhmerClassTable::getKhmerClassTable();
ReorderingOutput output(outChars, glyphStorage); KhmerReorderingOutput output(outChars, glyphStorage);
KhmerClassTable::CharClass charClass; KhmerClassTable::CharClass charClass;
le_int32 i, prev = 0, coengRo; le_int32 i, prev = 0, coengRo;
...@@ -390,6 +396,8 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le ...@@ -390,6 +396,8 @@ le_int32 KhmerReordering::reorder(const LEUnicode *chars, le_int32 charCount, le
while (prev < charCount) { while (prev < charCount) {
le_int32 syllable = findSyllable(classTable, chars, prev, charCount); le_int32 syllable = findSyllable(classTable, chars, prev, charCount);
output.reset();
// write a pre vowel or the pre part of a split vowel first // write a pre vowel or the pre part of a split vowel first
// and look out for coeng + ro. RO is the only vowel of type 2, and // and look out for coeng + ro. RO is the only vowel of type 2, and
// therefore the only one that requires saving space before the base. // therefore the only one that requires saving space before the base.
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* /*
******************************************************************************* *******************************************************************************
* *
* Copyright (C) 1999-2005, International Business Machines * Copyright (C) 1999-2007, International Business Machines
* Corporation and others. All Rights Reserved. * Corporation and others. All Rights Reserved.
* *
******************************************************************************* *******************************************************************************
...@@ -45,6 +45,16 @@ U_NAMESPACE_BEGIN ...@@ -45,6 +45,16 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEFontInstance) 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, const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int32 *offset, le_int32 limit,
le_int32 script, LEErrorCode &success) const le_int32 script, LEErrorCode &success) const
{ {
...@@ -62,7 +72,7 @@ const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int ...@@ -62,7 +72,7 @@ const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int
} }
void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, 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; le_int32 i, out = 0, dir = 1;
...@@ -83,7 +93,7 @@ void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, ...@@ -83,7 +93,7 @@ void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset,
} }
} }
glyphStorage[out] = mapCharToGlyph(code, mapper); glyphStorage[out] = mapCharToGlyph(code, mapper, filterZeroWidth);
if (code >= 0x10000) { if (code >= 0x10000) {
i += 1; i += 1;
...@@ -93,15 +103,72 @@ void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, ...@@ -93,15 +103,72 @@ void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset,
} }
LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const 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); LEUnicode32 mappedChar = mapper->mapChar(ch);
if (mappedChar == 0xFFFE || mappedChar == 0xFFFF || if (mappedChar == 0xFFFE || mappedChar == 0xFFFF) {
mappedChar == 0x200C || mappedChar == 0x200D) {
return 0xFFFF; return 0xFFFF;
} }
if (filterZeroWidth && (mappedChar == 0x200C || mappedChar == 0x200D)) {
return canDisplay(mappedChar)? 0x0001 : 0xFFFF;
}
return mapCharToGlyph(mappedChar); 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();
}
U_NAMESPACE_END U_NAMESPACE_END
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
* *
*/ */
...@@ -57,7 +57,7 @@ public: ...@@ -57,7 +57,7 @@ public:
* Destructor. * Destructor.
* @stable ICU 3.2 * @stable ICU 3.2
*/ */
virtual inline ~LECharMapper() {}; virtual ~LECharMapper();
/** /**
* This method does the adjustments. * This method does the adjustments.
...@@ -75,7 +75,7 @@ public: ...@@ -75,7 +75,7 @@ public:
* This is a forward reference to the class which holds the per-glyph * This is a forward reference to the class which holds the per-glyph
* storage. * storage.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
class LEGlyphStorage; class LEGlyphStorage;
...@@ -101,7 +101,7 @@ class LEGlyphStorage; ...@@ -101,7 +101,7 @@ class LEGlyphStorage;
* methods with some default behavior such as returning constant values, or using the * methods with some default behavior such as returning constant values, or using the
* values from the first subfont. * values from the first subfont.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
class U_LAYOUT_API LEFontInstance : public UObject class U_LAYOUT_API LEFontInstance : public UObject
{ {
...@@ -113,7 +113,7 @@ public: ...@@ -113,7 +113,7 @@ public:
* *
* @stable ICU 2.8 * @stable ICU 2.8
*/ */
virtual inline ~LEFontInstance() {}; virtual ~LEFontInstance();
/** /**
* Get a physical font which can render the given text. For composite fonts, * Get a physical font which can render the given text. For composite fonts,
...@@ -209,7 +209,7 @@ public: ...@@ -209,7 +209,7 @@ public:
* *
* @stable ICU 3.2 * @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 * This method returns the number of design units in
...@@ -237,13 +237,31 @@ public: ...@@ -237,13 +237,31 @@ public:
* @param count - the number of characters * @param count - the number of characters
* @param reverse - if <code>TRUE</code>, store the glyph indices in reverse order. * @param reverse - if <code>TRUE</code>, store the glyph indices in reverse order.
* @param mapper - the character mapper. * @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 * @param glyphStorage - the object which contains the output glyph array
* *
* @see LECharMapper * @see LECharMapper
* *
* @draft ICU 3.0 * @stable 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
*
* @stable 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 * This method maps a single character to a glyph index, using the
...@@ -335,7 +353,7 @@ public: ...@@ -335,7 +353,7 @@ public:
* *
* @stable ICU 3.2 * @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 * This method converts font design units in the
...@@ -347,7 +365,7 @@ public: ...@@ -347,7 +365,7 @@ public:
* *
* @stable ICU 3.2 * @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. * This method converts font design units to points.
...@@ -357,7 +375,7 @@ public: ...@@ -357,7 +375,7 @@ public:
* *
* @stable ICU 3.2 * @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 * This method converts pixels in the
...@@ -369,7 +387,7 @@ public: ...@@ -369,7 +387,7 @@ public:
* *
* @stable ICU 3.2 * @stable ICU 3.2
*/ */
virtual inline float xPixelsToUnits(float xPixels) const; virtual float xPixelsToUnits(float xPixels) const;
/** /**
* This method converts pixels in the * This method converts pixels in the
...@@ -381,7 +399,7 @@ public: ...@@ -381,7 +399,7 @@ public:
* *
* @stable ICU 3.2 * @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. * This method converts pixels to font design units.
...@@ -391,7 +409,7 @@ public: ...@@ -391,7 +409,7 @@ public:
* *
* @stable ICU 3.2 * @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 * Get the X scale factor from the font's transform. The default
...@@ -433,7 +451,7 @@ public: ...@@ -433,7 +451,7 @@ public:
* *
* @stable ICU 3.2 * @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 * This is a convenience method used to convert
...@@ -523,49 +541,6 @@ public: ...@@ -523,49 +541,6 @@ public:
}; };
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) inline float LEFontInstance::fixedToFloat(le_int32 fixed)
{ {
return (float) (fixed / 65536.0); return (float) (fixed / 65536.0);
...@@ -576,11 +551,6 @@ inline le_int32 LEFontInstance::floatToFixed(float theFloat) ...@@ -576,11 +551,6 @@ inline le_int32 LEFontInstance::floatToFixed(float theFloat)
return (le_int32) (theFloat * 65536.0); return (le_int32) (theFloat * 65536.0);
} }
inline le_int32 LEFontInstance::getLineHeight() const
{
return getAscent() + getDescent() + getLeading();
}
U_NAMESPACE_END U_NAMESPACE_END
#endif #endif
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/* /*
********************************************************************** **********************************************************************
* Copyright (C) 1998-2005, International Business Machines * Copyright (C) 1998-2009, International Business Machines
* Corporation and others. All Rights Reserved. * Corporation and others. All Rights Reserved.
********************************************************************** **********************************************************************
*/ */
...@@ -38,6 +38,11 @@ U_NAMESPACE_BEGIN ...@@ -38,6 +38,11 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEGlyphStorage) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEGlyphStorage)
LEInsertionCallback::~LEInsertionCallback()
{
// nothing to do...
}
LEGlyphStorage::LEGlyphStorage() LEGlyphStorage::LEGlyphStorage()
: fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL), : fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0) fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
...@@ -129,8 +134,18 @@ void LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool righ ...@@ -129,8 +134,18 @@ void LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool righ
if (fInsertionList == NULL) { if (fInsertionList == NULL) {
// FIXME: check this for failure? // FIXME: check this for failure?
fInsertionList = new LEInsertionList(rightToLeft); fInsertionList = new LEInsertionList(rightToLeft);
if (fInsertionList == NULL) {
LE_DELETE_ARRAY(fCharIndices);
fCharIndices = NULL;
LE_DELETE_ARRAY(fGlyphs);
fGlyphs = NULL;
success = LE_MEMORY_ALLOCATION_ERROR;
return;
} }
} }
}
// FIXME: do we want to initialize the positions to [0, 0]? // FIXME: do we want to initialize the positions to [0, 0]?
le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success) le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
...@@ -139,6 +154,11 @@ le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success) ...@@ -139,6 +154,11 @@ le_int32 LEGlyphStorage::allocatePositions(LEErrorCode &success)
return -1; return -1;
} }
if (fPositions != NULL) {
success = LE_INTERNAL_ERROR;
return -1;
}
fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1)); fPositions = LE_NEW_ARRAY(float, 2 * (fGlyphCount + 1));
if (fPositions == NULL) { if (fPositions == NULL) {
...@@ -156,6 +176,11 @@ le_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success) ...@@ -156,6 +176,11 @@ le_int32 LEGlyphStorage::allocateAuxData(LEErrorCode &success)
return -1; return -1;
} }
if (fAuxData != NULL) {
success = LE_INTERNAL_ERROR;
return -1;
}
fAuxData = LE_NEW_ARRAY(le_uint32, fGlyphCount); fAuxData = LE_NEW_ARRAY(le_uint32, fGlyphCount);
if (fAuxData == NULL) { if (fAuxData == NULL) {
...@@ -510,10 +535,49 @@ void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount) ...@@ -510,10 +535,49 @@ void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount)
fGlyphCount = newGlyphCount; fGlyphCount = newGlyphCount;
} }
// FIXME: add error checking? // Move a glyph to a different position in the LEGlyphStorage ( used for Indic v2 processing )
void LEGlyphStorage::moveGlyph(le_int32 fromPosition, le_int32 toPosition, le_uint32 marker )
{
LEErrorCode success = LE_NO_ERROR;
LEGlyphID holdGlyph = getGlyphID(fromPosition,success);
le_int32 holdCharIndex = getCharIndex(fromPosition,success);
le_uint32 holdAuxData = getAuxData(fromPosition,success);
if ( fromPosition < toPosition ) {
for ( le_int32 i = fromPosition ; i < toPosition ; i++ ) {
setGlyphID(i,getGlyphID(i+1,success),success);
setCharIndex(i,getCharIndex(i+1,success),success);
setAuxData(i,getAuxData(i+1,success),success);
}
} else {
for ( le_int32 i = toPosition ; i > fromPosition ; i-- ) {
setGlyphID(i,getGlyphID(i-1,success),success);
setCharIndex(i,getCharIndex(i-1,success),success);
setAuxData(i,getAuxData(i-1,success),success);
}
}
setGlyphID(toPosition,holdGlyph,success);
setCharIndex(toPosition,holdCharIndex,success);
setAuxData(toPosition,holdAuxData | marker,success);
}
// Glue code for existing stable API
LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount) LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount)
{ {
return fInsertionList->insert(atIndex, insertCount); LEErrorCode ignored = LE_NO_LAYOUT_ERROR;
return insertGlyphs(atIndex, insertCount, ignored);
}
// FIXME: add error checking?
LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success)
{
return fInsertionList->insert(atIndex, insertCount, success);
} }
le_int32 LEGlyphStorage::applyInsertions() le_int32 LEGlyphStorage::applyInsertions()
...@@ -526,11 +590,27 @@ le_int32 LEGlyphStorage::applyInsertions() ...@@ -526,11 +590,27 @@ le_int32 LEGlyphStorage::applyInsertions()
le_int32 newGlyphCount = fGlyphCount + growAmount; le_int32 newGlyphCount = fGlyphCount + growAmount;
fGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount); LEGlyphID *newGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount);
fCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount); if (newGlyphs == NULL) {
// Could not grow the glyph array
return fGlyphCount;
}
fGlyphs = newGlyphs;
le_int32 *newCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount);
if (newCharIndices == NULL) {
// Could not grow the glyph array
return fGlyphCount;
}
fCharIndices = newCharIndices;
if (fAuxData != NULL) { if (fAuxData != NULL) {
fAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount); le_uint32 *newAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount);
if (newAuxData == NULL) {
// could not grow the aux data array
return fGlyphCount;
}
fAuxData = (le_uint32 *)newAuxData;
} }
fSrcIndex = fGlyphCount - 1; fSrcIndex = fGlyphCount - 1;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/* /*
********************************************************************** **********************************************************************
* Copyright (C) 1998-2005, International Business Machines * Copyright (C) 1998-2010, International Business Machines
* Corporation and others. All Rights Reserved. * Corporation and others. All Rights Reserved.
********************************************************************** **********************************************************************
*/ */
...@@ -54,7 +54,7 @@ U_NAMESPACE_BEGIN ...@@ -54,7 +54,7 @@ U_NAMESPACE_BEGIN
* *
* @see LEInsertionList.h * @see LEInsertionList.h
* *
* @draft ICU 3.6 * @stable ICU 3.6
*/ */
class U_LAYOUT_API LEGlyphStorage : public UObject, protected LEInsertionCallback class U_LAYOUT_API LEGlyphStorage : public UObject, protected LEInsertionCallback
{ {
...@@ -130,7 +130,7 @@ protected: ...@@ -130,7 +130,7 @@ protected:
* *
* @see LEInsertionList.h * @see LEInsertionList.h
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]); virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]);
...@@ -141,14 +141,14 @@ public: ...@@ -141,14 +141,14 @@ public:
* <code>allocateGlyphArray, allocatePositions and allocateAuxData</code> * <code>allocateGlyphArray, allocatePositions and allocateAuxData</code>
* to allocate the data. * to allocate the data.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
LEGlyphStorage(); LEGlyphStorage();
/** /**
* The destructor. This will deallocate all of the arrays. * The destructor. This will deallocate all of the arrays.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
~LEGlyphStorage(); ~LEGlyphStorage();
...@@ -157,7 +157,7 @@ public: ...@@ -157,7 +157,7 @@ public:
* *
* @return the number of glyphs in the glyph array * @return the number of glyphs in the glyph array
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
inline le_int32 getGlyphCount() const; inline le_int32 getGlyphCount() const;
...@@ -169,7 +169,7 @@ public: ...@@ -169,7 +169,7 @@ public:
* @param glyphs - the destiniation glyph array * @param glyphs - the destiniation glyph array
* @param success - set to an error code if the operation fails * @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; void getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const;
...@@ -183,7 +183,7 @@ public: ...@@ -183,7 +183,7 @@ public:
* @param extraBits - this value will be ORed with each glyph index * @param extraBits - this value will be ORed with each glyph index
* @param success - set to an error code if the operation fails * @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; void getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const;
...@@ -195,7 +195,7 @@ public: ...@@ -195,7 +195,7 @@ public:
* @param charIndices - the destiniation character index array * @param charIndices - the destiniation character index array
* @param success - set to an error code if the operation fails * @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; void getCharIndices(le_int32 charIndices[], LEErrorCode &success) const;
...@@ -208,7 +208,7 @@ public: ...@@ -208,7 +208,7 @@ public:
* @param indexBase - an offset which will be added to each index * @param indexBase - an offset which will be added to each index
* @param success - set to an error code if the operation fails * @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; void getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const;
...@@ -221,7 +221,7 @@ public: ...@@ -221,7 +221,7 @@ public:
* @param positions - the destiniation position array * @param positions - the destiniation position array
* @param success - set to an error code if the operation fails * @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; void getGlyphPositions(float positions[], LEErrorCode &success) const;
...@@ -237,7 +237,7 @@ public: ...@@ -237,7 +237,7 @@ public:
* @param y - the glyph's Y position * @param y - the glyph's Y position
* @param success - set to an error code if the operation fails * @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; void getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const;
...@@ -251,7 +251,7 @@ public: ...@@ -251,7 +251,7 @@ public:
* @param success set to an error code if the storage cannot be allocated of if the initial * @param success set to an error code if the storage cannot be allocated of if the initial
* glyph count is not positive. * glyph count is not positive.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
void allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success); void allocateGlyphArray(le_int32 initialGlyphCount, le_bool rightToLeft, LEErrorCode &success);
...@@ -263,7 +263,7 @@ public: ...@@ -263,7 +263,7 @@ public:
* *
* @return the number of X, Y position pairs allocated. * @return the number of X, Y position pairs allocated.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
le_int32 allocatePositions(LEErrorCode &success); le_int32 allocatePositions(LEErrorCode &success);
...@@ -274,7 +274,7 @@ public: ...@@ -274,7 +274,7 @@ public:
* *
* @return the size of the auxillary data array. * @return the size of the auxillary data array.
* *
* @draft ICU 3.6 * @stable ICU 3.6
*/ */
le_int32 allocateAuxData(LEErrorCode &success); le_int32 allocateAuxData(LEErrorCode &success);
...@@ -284,7 +284,7 @@ public: ...@@ -284,7 +284,7 @@ public:
* @param auxData the auxillary data array will be copied to this address * @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 * @param success set to an error code if the data cannot be copied
* *
* @draft ICU 3.6 * @stable ICU 3.6
*/ */
void getAuxData(le_uint32 auxData[], LEErrorCode &success) const; void getAuxData(le_uint32 auxData[], LEErrorCode &success) const;
...@@ -296,7 +296,7 @@ public: ...@@ -296,7 +296,7 @@ public:
* *
* @return the glyph ID * @return the glyph ID
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
LEGlyphID getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const; LEGlyphID getGlyphID(le_int32 glyphIndex, LEErrorCode &success) const;
...@@ -308,7 +308,7 @@ public: ...@@ -308,7 +308,7 @@ public:
* *
* @return the character index * @return the character index
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
le_int32 getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const; le_int32 getCharIndex(le_int32 glyphIndex, LEErrorCode &success) const;
...@@ -321,7 +321,7 @@ public: ...@@ -321,7 +321,7 @@ public:
* *
* @return the auxillary data * @return the auxillary data
* *
* @draft ICU 3.6 * @stable ICU 3.6
*/ */
le_uint32 getAuxData(le_int32 glyphIndex, LEErrorCode &success) const; le_uint32 getAuxData(le_int32 glyphIndex, LEErrorCode &success) const;
...@@ -333,7 +333,7 @@ public: ...@@ -333,7 +333,7 @@ public:
* *
* @return a reference to the given location in the glyph array * @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; inline LEGlyphID &operator[](le_int32 glyphIndex) const;
...@@ -346,15 +346,51 @@ public: ...@@ -346,15 +346,51 @@ public:
* *
* @param atIndex the index of the glyph to be replaced * @param atIndex the index of the glyph to be replaced
* @param insertCount the number of glyphs to replace it with * @param insertCount the number of glyphs to replace it with
* @param success set to an error code if the auxillary data cannot be retrieved.
*
* @return the address at which to store the replacement glyphs.
*
* @see LEInsertionList.h
*
* @stable ICU 4.2
*/
LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success);
/**
* Call this method to replace a single glyph in the glyph array
* with multiple glyphs. This method uses the <code>LEInsertionList</code>
* to do the insertion. It returns the address of storage where the new
* glyph IDs can be stored. They will not actually be inserted into the
* glyph array until <code>applyInsertions</code> is called.
*
* Note: Don't use this version, use the other version of this function which has an error code.
*
* @param atIndex the index of the glyph to be replaced
* @param insertCount the number of glyphs to replace it with
* *
* @return the address at which to store the replacement glyphs. * @return the address at which to store the replacement glyphs.
* *
* @see LEInsetionList.h * @see LEInsertionList.h
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount); LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount);
/**
* This method is used to reposition glyphs during Indic v2 processing. It moves
* all of the relevant glyph information ( glyph, indices, positions, and auxData ),
* from the source position to the target position, and also allows for a marker bit
* to be set in the target glyph's auxData so that it won't be reprocessed later in the
* cycle.
*
* @param fromPosition - position of the glyph to be moved
* @param toPosition - target position of the glyph
* @param marker marker bit
*
* @stable ICU 4.2
*/
void moveGlyph(le_int32 fromPosition, le_int32 toPosition, le_uint32 marker);
/** /**
* This method causes all of the glyph insertions recorded by * This method causes all of the glyph insertions recorded by
* <code>insertGlyphs</code> to be applied to the glyph array. The * <code>insertGlyphs</code> to be applied to the glyph array. The
...@@ -365,7 +401,7 @@ public: ...@@ -365,7 +401,7 @@ public:
* *
* @see LEInsertionList.h * @see LEInsertionList.h
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
le_int32 applyInsertions(); le_int32 applyInsertions();
...@@ -376,7 +412,7 @@ public: ...@@ -376,7 +412,7 @@ public:
* @param glyphID the new glyph ID * @param glyphID the new glyph ID
* @param success will be set to an error code if the glyph ID cannot be set. * @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); void setGlyphID(le_int32 glyphIndex, LEGlyphID glyphID, LEErrorCode &success);
...@@ -387,7 +423,7 @@ public: ...@@ -387,7 +423,7 @@ public:
* @param charIndex the new char index * @param charIndex the new char index
* @param success will be set to an error code if the char index cannot be set. * @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); void setCharIndex(le_int32 glyphIndex, le_int32 charIndex, LEErrorCode &success);
...@@ -399,7 +435,7 @@ public: ...@@ -399,7 +435,7 @@ public:
* @param y the new Y position * @param y the new Y position
* @param success will be set to an error code if the position cannot be set. * @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); void setPosition(le_int32 glyphIndex, float x, float y, LEErrorCode &success);
...@@ -411,7 +447,7 @@ public: ...@@ -411,7 +447,7 @@ public:
* @param yAdjust the adjustment to the glyph's Y position * @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. * @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); void adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success);
...@@ -422,7 +458,7 @@ public: ...@@ -422,7 +458,7 @@ public:
* @param auxData the new auxillary data * @param auxData the new auxillary data
* @param success will be set to an error code if the auxillary data cannot be set. * @param success will be set to an error code if the auxillary data cannot be set.
* *
* @draft ICU 3.6 * @stable ICU 3.6
*/ */
void setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success); void setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success);
...@@ -434,7 +470,7 @@ public: ...@@ -434,7 +470,7 @@ public:
* @param from the <code>LEGlyphStorage</code> object from which * @param from the <code>LEGlyphStorage</code> object from which
* to get the new glyph array. * to get the new glyph array.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
void adoptGlyphArray(LEGlyphStorage &from); void adoptGlyphArray(LEGlyphStorage &from);
...@@ -446,7 +482,7 @@ public: ...@@ -446,7 +482,7 @@ public:
* @param from the <code>LEGlyphStorage</code> object from which * @param from the <code>LEGlyphStorage</code> object from which
* to get the new char indices array. * to get the new char indices array.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
void adoptCharIndicesArray(LEGlyphStorage &from); void adoptCharIndicesArray(LEGlyphStorage &from);
...@@ -458,7 +494,7 @@ public: ...@@ -458,7 +494,7 @@ public:
* @param from the <code>LEGlyphStorage</code> object from which * @param from the <code>LEGlyphStorage</code> object from which
* to get the new position array. * to get the new position array.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
void adoptPositionArray(LEGlyphStorage &from); void adoptPositionArray(LEGlyphStorage &from);
...@@ -470,7 +506,7 @@ public: ...@@ -470,7 +506,7 @@ public:
* @param from the <code>LEGlyphStorage</code> object from which * @param from the <code>LEGlyphStorage</code> object from which
* to get the new auxillary data array. * to get the new auxillary data array.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
void adoptAuxDataArray(LEGlyphStorage &from); void adoptAuxDataArray(LEGlyphStorage &from);
...@@ -481,7 +517,7 @@ public: ...@@ -481,7 +517,7 @@ public:
* @param from the <code>LEGlyphStorage</code> object from which * @param from the <code>LEGlyphStorage</code> object from which
* to get the new glyph count. * to get the new glyph count.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
void adoptGlyphCount(LEGlyphStorage &from); void adoptGlyphCount(LEGlyphStorage &from);
...@@ -490,7 +526,7 @@ public: ...@@ -490,7 +526,7 @@ public:
* *
* @param newGlyphCount the new glyph count. * @param newGlyphCount the new glyph count.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
void adoptGlyphCount(le_int32 newGlyphCount); void adoptGlyphCount(le_int32 newGlyphCount);
...@@ -500,21 +536,21 @@ public: ...@@ -500,21 +536,21 @@ public:
* to layout a different characer array. (This method is also called * to layout a different characer array. (This method is also called
* by the destructor) * by the destructor)
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
void reset(); void reset();
/** /**
* ICU "poor man's RTTI", returns a UClassID for the actual class. * ICU "poor man's RTTI", returns a UClassID for the actual class.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
virtual UClassID getDynamicClassID() const; virtual UClassID getDynamicClassID() const;
/** /**
* ICU "poor man's RTTI", returns a UClassID for this class. * ICU "poor man's RTTI", returns a UClassID for this class.
* *
* @draft ICU 3.0 * @stable ICU 3.0
*/ */
static UClassID getStaticClassID(); static UClassID getStaticClassID();
}; };
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/* /*
********************************************************************** **********************************************************************
* Copyright (C) 1998-2004, International Business Machines * Copyright (C) 1998-2008, International Business Machines
* Corporation and others. All Rights Reserved. * Corporation and others. All Rights Reserved.
********************************************************************** **********************************************************************
*/ */
...@@ -76,9 +76,17 @@ le_int32 LEInsertionList::getGrowAmount() ...@@ -76,9 +76,17 @@ le_int32 LEInsertionList::getGrowAmount()
return growAmount; return growAmount;
} }
LEGlyphID *LEInsertionList::insert(le_int32 position, le_int32 count) LEGlyphID *LEInsertionList::insert(le_int32 position, le_int32 count, LEErrorCode &success)
{ {
if (LE_FAILURE(success)) {
return 0;
}
InsertionRecord *insertion = (InsertionRecord *) LE_NEW_ARRAY(char, sizeof(InsertionRecord) + (count - ANY_NUMBER) * sizeof (LEGlyphID)); InsertionRecord *insertion = (InsertionRecord *) LE_NEW_ARRAY(char, sizeof(InsertionRecord) + (count - ANY_NUMBER) * sizeof (LEGlyphID));
if (insertion == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
insertion->position = position; insertion->position = position;
insertion->count = count; insertion->count = count;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/* /*
********************************************************************** **********************************************************************
* Copyright (C) 1998-2004, International Business Machines * Copyright (C) 1998-2008, International Business Machines
* Corporation and others. All Rights Reserved. * Corporation and others. All Rights Reserved.
********************************************************************** **********************************************************************
*/ */
...@@ -45,7 +45,7 @@ struct InsertionRecord; ...@@ -45,7 +45,7 @@ struct InsertionRecord;
* *
* @internal * @internal
*/ */
class LEInsertionCallback class U_LAYOUT_API LEInsertionCallback
{ {
public: public:
/** /**
...@@ -62,6 +62,11 @@ public: ...@@ -62,6 +62,11 @@ public:
* @internal * @internal
*/ */
virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]) = 0; virtual le_bool applyInsertion(le_int32 atPosition, le_int32 count, LEGlyphID newGlyphs[]) = 0;
/**
* The destructor
*/
virtual ~LEInsertionCallback();
}; };
/** /**
...@@ -103,13 +108,14 @@ public: ...@@ -103,13 +108,14 @@ public:
* @param position the glyph at this position in the array will be * @param position the glyph at this position in the array will be
* replaced by the new glyphs. * replaced by the new glyphs.
* @param count the number of new glyphs * @param count the number of new glyphs
* @param success set to an error code if the auxillary data cannot be retrieved.
* *
* @return the address of an array in which to store the new glyphs. This will * @return the address of an array in which to store the new glyphs. This will
* <em>not</em> be in the glyph array. * <em>not</em> be in the glyph array.
* *
* @internal * @internal
*/ */
LEGlyphID *insert(le_int32 position, le_int32 count); LEGlyphID *insert(le_int32 position, le_int32 count, LEErrorCode &success);
/** /**
* Return the number of new glyphs that have been inserted. * Return the number of new glyphs that have been inserted.
......
...@@ -25,12 +25,12 @@ ...@@ -25,12 +25,12 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005. All Rights Reserved. * (C) Copyright IBM Corp. 1998-2010. All Rights Reserved.
* *
* WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
* YOU REALLY KNOW WHAT YOU'RE DOING. * YOU REALLY KNOW WHAT YOU'RE DOING.
* *
* Generated on: 07/19/2005 01:01:08 PM PDT * Generated on: 10/26/2010 02:53:33 PM PDT
*/ */
#ifndef __LELANGUAGES_H #ifndef __LELANGUAGES_H
...@@ -50,7 +50,7 @@ U_NAMESPACE_BEGIN ...@@ -50,7 +50,7 @@ U_NAMESPACE_BEGIN
* this is just a list of languages which the LayoutEngine * this is just a list of languages which the LayoutEngine
* supports. * supports.
* *
* @draft ICU 3.4 * @stable ICU 2.6
*/ */
enum LanguageCodes { enum LanguageCodes {
...@@ -85,7 +85,51 @@ enum LanguageCodes { ...@@ -85,7 +85,51 @@ enum LanguageCodes {
zhsLanguageCode = 28, zhsLanguageCode = 28,
zhtLanguageCode = 29, zhtLanguageCode = 29,
languageCodeCount = 30 /** New language codes added 03/13/2008 @stable ICU 4.0 */
afkLanguageCode = 30,
belLanguageCode = 31,
bgrLanguageCode = 32,
catLanguageCode = 33,
cheLanguageCode = 34,
copLanguageCode = 35,
csyLanguageCode = 36,
danLanguageCode = 37,
deuLanguageCode = 38,
dznLanguageCode = 39,
ellLanguageCode = 40,
engLanguageCode = 41,
espLanguageCode = 42,
etiLanguageCode = 43,
euqLanguageCode = 44,
finLanguageCode = 45,
fraLanguageCode = 46,
gaeLanguageCode = 47,
hauLanguageCode = 48,
hrvLanguageCode = 49,
hunLanguageCode = 50,
hyeLanguageCode = 51,
indLanguageCode = 52,
itaLanguageCode = 53,
khmLanguageCode = 54,
mngLanguageCode = 55,
mtsLanguageCode = 56,
nepLanguageCode = 57,
nldLanguageCode = 58,
pasLanguageCode = 59,
plkLanguageCode = 60,
ptgLanguageCode = 61,
romLanguageCode = 62,
rusLanguageCode = 63,
skyLanguageCode = 64,
slvLanguageCode = 65,
sqiLanguageCode = 66,
srbLanguageCode = 67,
sveLanguageCode = 68,
tibLanguageCode = 69,
trkLanguageCode = 70,
welLanguageCode = 71,
languageCodeCount = 72
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -25,40 +25,43 @@ ...@@ -25,40 +25,43 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005. All Rights Reserved. * (C) Copyright IBM Corp. 1998-2010. All Rights Reserved.
* *
* WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
* YOU REALLY KNOW WHAT YOU'RE DOING. * YOU REALLY KNOW WHAT YOU'RE DOING.
*
* Generated on: 10/26/2010 02:53:33 PM PDT
*/ */
#ifndef __LESCRIPTS_H #ifndef __LESCRIPTS_H
#define __LESCRIPTS_H #define __LESCRIPTS_H
#include "LETypes.h" #include "LETypes.h"
/** /**
* \file * \file
* \brief C++ API: Constants for Unicode script values * \brief C++ API: Constants for Unicode script values
*/ */
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
/** /**
* Constants for Unicode script values, generated using * Constants for Unicode script values, generated using
* ICU4J's <code>UScript</code> class. * ICU4J's <code>UScript</code> class.
* *
* @draft ICU 3.0 * @stable ICU 2.2
*/ */
enum ScriptCodes { enum ScriptCodes {
zyyyScriptCode = 0, zyyyScriptCode = 0,
qaaiScriptCode = 1, zinhScriptCode = 1,
qaaiScriptCode = zinhScriptCode, /* manually added alias, for API stability */
arabScriptCode = 2, arabScriptCode = 2,
armnScriptCode = 3, armnScriptCode = 3,
bengScriptCode = 4, bengScriptCode = 4,
bopoScriptCode = 5, bopoScriptCode = 5,
cherScriptCode = 6, cherScriptCode = 6,
qaacScriptCode = 7, coptScriptCode = 7,
cyrlScriptCode = 8, cyrlScriptCode = 8,
dsrtScriptCode = 9, dsrtScriptCode = 9,
devaScriptCode = 10, devaScriptCode = 10,
...@@ -91,12 +94,24 @@ enum ScriptCodes { ...@@ -91,12 +94,24 @@ enum ScriptCodes {
thaaScriptCode = 37, thaaScriptCode = 37,
thaiScriptCode = 38, thaiScriptCode = 38,
tibtScriptCode = 39, tibtScriptCode = 39,
/**
* @stable ICU 2.6
*/
cansScriptCode = 40, cansScriptCode = 40,
/**
* @stable ICU 2.2
*/
yiiiScriptCode = 41, yiiiScriptCode = 41,
tglgScriptCode = 42, tglgScriptCode = 42,
hanoScriptCode = 43, hanoScriptCode = 43,
buhdScriptCode = 44, buhdScriptCode = 44,
tagbScriptCode = 45, tagbScriptCode = 45,
/**
* @stable ICU 2.6
*/
braiScriptCode = 46, braiScriptCode = 46,
cprtScriptCode = 47, cprtScriptCode = 47,
limbScriptCode = 48, limbScriptCode = 48,
...@@ -105,9 +120,129 @@ enum ScriptCodes { ...@@ -105,9 +120,129 @@ enum ScriptCodes {
shawScriptCode = 51, shawScriptCode = 51,
taleScriptCode = 52, taleScriptCode = 52,
ugarScriptCode = 53, ugarScriptCode = 53,
/**
* @stable ICU 3.0
*/
hrktScriptCode = 54, hrktScriptCode = 54,
/**
* @stable ICU 3.4
*/
bugiScriptCode = 55,
glagScriptCode = 56,
kharScriptCode = 57,
syloScriptCode = 58,
taluScriptCode = 59,
tfngScriptCode = 60,
xpeoScriptCode = 61,
/**
* @stable ICU 3.6
*/
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,
/**
* @stable ICU 3.8
*/
cariScriptCode = 104,
jpanScriptCode = 105,
lanaScriptCode = 106,
lyciScriptCode = 107,
lydiScriptCode = 108,
olckScriptCode = 109,
rjngScriptCode = 110,
saurScriptCode = 111,
sgnwScriptCode = 112,
sundScriptCode = 113,
moonScriptCode = 114,
mteiScriptCode = 115,
/**
* @stable ICU 4.0
*/
armiScriptCode = 116,
avstScriptCode = 117,
cakmScriptCode = 118,
koreScriptCode = 119,
kthiScriptCode = 120,
maniScriptCode = 121,
phliScriptCode = 122,
phlpScriptCode = 123,
phlvScriptCode = 124,
prtiScriptCode = 125,
samrScriptCode = 126,
tavtScriptCode = 127,
zmthScriptCode = 128,
zsymScriptCode = 129,
/**
* @stable ICU 4.4
*/
bamuScriptCode = 130,
lisuScriptCode = 131,
nkgbScriptCode = 132,
sarbScriptCode = 133,
/**
* @stable ICU 4.6
*/
bassScriptCode = 134,
duplScriptCode = 135,
elbaScriptCode = 136,
granScriptCode = 137,
kpelScriptCode = 138,
lomaScriptCode = 139,
mendScriptCode = 140,
mercScriptCode = 141,
narbScriptCode = 142,
nbatScriptCode = 143,
palmScriptCode = 144,
sindScriptCode = 145,
waraScriptCode = 146,
scriptCodeCount = 55 scriptCodeCount = 147
}; };
U_NAMESPACE_END U_NAMESPACE_END
......
...@@ -26,6 +26,15 @@ ...@@ -26,6 +26,15 @@
#ifndef __LESTANDALONE #ifndef __LESTANDALONE
#define __LESTANDALONE #define __LESTANDALONE
#ifndef U_COPYRIGHT_STRING
#define U_COPYRIGHT_STRING " (C) Copyright IBM Corp and Others. 1998-2010 - All Rights Reserved"
#endif
/* ICU Version number */
#ifndef U_ICU_VERSION
#define U_ICU_VERSION "4.6"
#endif
/* Definitions to make Layout Engine work away from ICU. */ /* Definitions to make Layout Engine work away from ICU. */
#ifndef U_NAMESPACE_BEGIN #ifndef U_NAMESPACE_BEGIN
#define U_NAMESPACE_BEGIN #define U_NAMESPACE_BEGIN
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* *
*/ */
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/* /*
* *
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* *
*/ */
...@@ -472,6 +472,7 @@ enum LEFeatureTags { ...@@ -472,6 +472,7 @@ enum LEFeatureTags {
LE_CALT_FEATURE_TAG = 0x63616C74UL, /**< 'calt' */ LE_CALT_FEATURE_TAG = 0x63616C74UL, /**< 'calt' */
LE_CASE_FEATURE_TAG = 0x63617365UL, /**< 'case' */ LE_CASE_FEATURE_TAG = 0x63617365UL, /**< 'case' */
LE_CCMP_FEATURE_TAG = 0x63636D70UL, /**< 'ccmp' */ LE_CCMP_FEATURE_TAG = 0x63636D70UL, /**< 'ccmp' */
LE_CJCT_FEATURE_TAG = 0x636A6374UL, /**< 'cjct' */
LE_CLIG_FEATURE_TAG = 0x636C6967UL, /**< 'clig' */ LE_CLIG_FEATURE_TAG = 0x636C6967UL, /**< 'clig' */
LE_CPSP_FEATURE_TAG = 0x63707370UL, /**< 'cpsp' */ LE_CPSP_FEATURE_TAG = 0x63707370UL, /**< 'cpsp' */
LE_CSWH_FEATURE_TAG = 0x63737768UL, /**< 'cswh' */ LE_CSWH_FEATURE_TAG = 0x63737768UL, /**< 'cswh' */
...@@ -535,6 +536,7 @@ enum LEFeatureTags { ...@@ -535,6 +536,7 @@ enum LEFeatureTags {
LE_RAND_FEATURE_TAG = 0x72616E64UL, /**< 'rand' */ LE_RAND_FEATURE_TAG = 0x72616E64UL, /**< 'rand' */
LE_RLIG_FEATURE_TAG = 0x726C6967UL, /**< 'rlig' */ LE_RLIG_FEATURE_TAG = 0x726C6967UL, /**< 'rlig' */
LE_RPHF_FEATURE_TAG = 0x72706866UL, /**< 'rphf' */ LE_RPHF_FEATURE_TAG = 0x72706866UL, /**< 'rphf' */
LE_RKRF_FEATURE_TAG = 0x726B7266UL, /**< 'rkrf' */
LE_RTBD_FEATURE_TAG = 0x72746264UL, /**< 'rtbd' */ LE_RTBD_FEATURE_TAG = 0x72746264UL, /**< 'rtbd' */
LE_RTLA_FEATURE_TAG = 0x72746C61UL, /**< 'rtla' */ LE_RTLA_FEATURE_TAG = 0x72746C61UL, /**< 'rtla' */
LE_RUBY_FEATURE_TAG = 0x72756279UL, /**< 'ruby' */ LE_RUBY_FEATURE_TAG = 0x72756279UL, /**< 'ruby' */
......
...@@ -38,10 +38,11 @@ ...@@ -38,10 +38,11 @@
#include "ArabicLayoutEngine.h" #include "ArabicLayoutEngine.h"
#include "CanonShaping.h" #include "CanonShaping.h"
#include "HanLayoutEngine.h" #include "HanLayoutEngine.h"
#include "HangulLayoutEngine.h"
#include "IndicLayoutEngine.h" #include "IndicLayoutEngine.h"
#include "KhmerLayoutEngine.h" #include "KhmerLayoutEngine.h"
#include "ThaiLayoutEngine.h" #include "ThaiLayoutEngine.h"
//#include "TibetanLayoutEngine.h" #include "TibetanLayoutEngine.h"
#include "GXLayoutEngine.h" #include "GXLayoutEngine.h"
#include "ScriptAndLanguageTags.h" #include "ScriptAndLanguageTags.h"
#include "CharSubstitutionFilter.h" #include "CharSubstitutionFilter.h"
...@@ -59,6 +60,9 @@ ...@@ -59,6 +60,9 @@
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
/* Leave this copyright notice here! It needs to go somewhere in this library. */
static const char copyright[] = U_COPYRIGHT_STRING;
const LEUnicode32 DefaultCharMapper::controlChars[] = { const LEUnicode32 DefaultCharMapper::controlChars[] = {
0x0009, 0x000A, 0x000D, 0x0009, 0x000A, 0x000D,
/*0x200C, 0x200D,*/ 0x200E, 0x200F, /*0x200C, 0x200D,*/ 0x200E, 0x200F,
...@@ -96,9 +100,8 @@ LEUnicode32 DefaultCharMapper::mapChar(LEUnicode32 ch) const ...@@ -96,9 +100,8 @@ LEUnicode32 DefaultCharMapper::mapChar(LEUnicode32 ch) const
} }
if (fFilterControls) { if (fFilterControls) {
le_int32 index = OpenTypeUtilities::search((le_uint32)ch, le_int32 index = OpenTypeUtilities::search((le_uint32)ch, (le_uint32 *)controlChars, controlCharsCount);
(le_uint32 *)controlChars,
controlCharsCount);
if (controlChars[index] == ch) { if (controlChars[index] == ch) {
return 0xFFFF; return 0xFFFF;
} }
...@@ -134,6 +137,37 @@ CharSubstitutionFilter::~CharSubstitutionFilter() ...@@ -134,6 +137,37 @@ CharSubstitutionFilter::~CharSubstitutionFilter()
// nothing to do // nothing to do
} }
class CanonMarkFilter : public UMemory, public LEGlyphFilter
{
private:
const GlyphClassDefinitionTable *classDefTable;
CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class
CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class
public:
CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
virtual ~CanonMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const;
};
CanonMarkFilter::CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
{
classDefTable = gdefTable->getMarkAttachClassDefinitionTable();
}
CanonMarkFilter::~CanonMarkFilter()
{
// nothing to do?
}
le_bool CanonMarkFilter::accept(LEGlyphID glyph) const
{
le_int32 glyphClass = classDefTable->getGlyphClass(glyph);
return glyphClass != 0;
}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine) UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine)
...@@ -150,11 +184,22 @@ static const FeatureMap canonFeatureMap[] = ...@@ -150,11 +184,22 @@ static const FeatureMap canonFeatureMap[] =
static const le_int32 canonFeatureMapCount = LE_ARRAY_SIZE(canonFeatureMap); static const le_int32 canonFeatureMapCount = LE_ARRAY_SIZE(canonFeatureMap);
LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags) LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance,
le_int32 scriptCode,
le_int32 languageCode,
le_int32 typoFlags,
LEErrorCode &success)
: fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode), : fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode),
fTypoFlags(typoFlags) fTypoFlags(typoFlags), fFilterZeroWidth(TRUE)
{ {
if (LE_FAILURE(success)) {
return;
}
fGlyphStorage = new LEGlyphStorage(); fGlyphStorage = new LEGlyphStorage();
if (fGlyphStorage == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
}
} }
le_int32 LayoutEngine::getGlyphCount() const le_int32 LayoutEngine::getGlyphCount() const
...@@ -183,37 +228,6 @@ void LayoutEngine::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const ...@@ -183,37 +228,6 @@ void LayoutEngine::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
fGlyphStorage->getGlyphs(glyphs, success); fGlyphStorage->getGlyphs(glyphs, success);
} }
class CanonMarkFilter : public LEGlyphFilter
{
private:
const GlyphClassDefinitionTable *classDefTable;
CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class
CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class
public:
CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
virtual ~CanonMarkFilter();
virtual le_bool accept(LEGlyphID glyph) const;
};
CanonMarkFilter::CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
{
classDefTable = gdefTable->getMarkAttachClassDefinitionTable();
}
CanonMarkFilter::~CanonMarkFilter()
{
// nothing to do?
}
le_bool CanonMarkFilter::accept(LEGlyphID glyph) const
{
le_int32 glyphClass = classDefTable->getGlyphClass(glyph);
return glyphClass != 0;
}
void LayoutEngine::getGlyphPositions(float positions[], LEErrorCode &success) const void LayoutEngine::getGlyphPositions(float positions[], LEErrorCode &success) const
{ {
...@@ -244,8 +258,21 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -244,8 +258,21 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
if (canonGSUBTable->coversScript(scriptTag)) { if (canonGSUBTable->coversScript(scriptTag)) {
CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance); CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance);
if (substitutionFilter == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
const LEUnicode *inChars = &chars[offset]; const LEUnicode *inChars = &chars[offset];
LEUnicode *reordered = NULL; LEUnicode *reordered = NULL;
LEGlyphStorage fakeGlyphStorage;
fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success);
if (LE_FAILURE(success)) {
delete substitutionFilter;
return 0;
}
// This is the cheapest way to get mark reordering only for Hebrew. // This is the cheapest way to get mark reordering only for Hebrew.
// We could just do the mark reordering for all scripts, but most // We could just do the mark reordering for all scripts, but most
...@@ -254,18 +281,19 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -254,18 +281,19 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
reordered = LE_NEW_ARRAY(LEUnicode, count); reordered = LE_NEW_ARRAY(LEUnicode, count);
if (reordered == NULL) { if (reordered == NULL) {
delete substitutionFilter;
success = LE_MEMORY_ALLOCATION_ERROR; success = LE_MEMORY_ALLOCATION_ERROR;
return 0; return 0;
} }
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, glyphStorage); CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
inChars = reordered; inChars = reordered;
} }
glyphStorage.allocateGlyphArray(count, rightToLeft, success); fakeGlyphStorage.allocateAuxData(success);
glyphStorage.allocateAuxData(success);
if (LE_FAILURE(success)) { if (LE_FAILURE(success)) {
delete substitutionFilter;
return 0; return 0;
} }
...@@ -275,21 +303,41 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off ...@@ -275,21 +303,41 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
} }
for (i = 0; i < count; i += 1, out += dir) { for (i = 0; i < count; i += 1, out += dir) {
glyphStorage[out] = (LEGlyphID) inChars[i]; fakeGlyphStorage[out] = (LEGlyphID) inChars[i];
glyphStorage.setAuxData(out, canonFeatures, success); fakeGlyphStorage.setAuxData(out, canonFeatures, success);
} }
if (reordered != NULL) { if (reordered != NULL) {
LE_DELETE_ARRAY(reordered); LE_DELETE_ARRAY(reordered);
} }
outCharCount = canonGSUBTable->process(glyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE); outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
if (LE_FAILURE(success)) {
delete substitutionFilter;
return 0;
}
out = (rightToLeft? outCharCount - 1 : 0);
out = (rightToLeft? count - 1 : 0); /*
* The char indices array in fakeGlyphStorage has the correct mapping
* back to the original input characters. Save it in glyphStorage. The
* subsequent call to glyphStoratge.allocateGlyphArray will keep this
* array rather than allocating and initializing a new one.
*/
glyphStorage.adoptCharIndicesArray(fakeGlyphStorage);
outChars = LE_NEW_ARRAY(LEUnicode, outCharCount); outChars = LE_NEW_ARRAY(LEUnicode, outCharCount);
if (outChars == NULL) {
delete substitutionFilter;
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
for (i = 0; i < outCharCount; i += 1, out += dir) { 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; delete substitutionFilter;
...@@ -474,7 +522,7 @@ void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le ...@@ -474,7 +522,7 @@ void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le
DefaultCharMapper charMapper(TRUE, mirror); DefaultCharMapper charMapper(TRUE, mirror);
fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, glyphStorage); fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, fFilterZeroWidth, glyphStorage);
} }
// Input: characters, font? // Input: characters, font?
...@@ -494,6 +542,10 @@ le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_ ...@@ -494,6 +542,10 @@ le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_
le_int32 glyphCount; le_int32 glyphCount;
if (fGlyphStorage->getGlyphCount() > 0) {
fGlyphStorage->reset();
}
glyphCount = computeGlyphs(chars, offset, count, max, rightToLeft, *fGlyphStorage, success); glyphCount = computeGlyphs(chars, offset, count, max, rightToLeft, *fGlyphStorage, success);
positionGlyphs(*fGlyphStorage, x, y, success); positionGlyphs(*fGlyphStorage, x, y, success);
adjustGlyphPositions(chars, offset, count, rightToLeft, *fGlyphStorage, success); adjustGlyphPositions(chars, offset, count, rightToLeft, *fGlyphStorage, success);
...@@ -525,8 +577,15 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -525,8 +577,15 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
LayoutEngine *result = NULL; LayoutEngine *result = NULL;
LETag scriptTag = 0x00000000; LETag scriptTag = 0x00000000;
LETag languageTag = 0x00000000; LETag languageTag = 0x00000000;
LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode);
if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) { // Right now, only invoke V2 processing for Devanagari. TODO: Allow more V2 scripts as they are
// properly tested.
if ( v2ScriptTag == dev2ScriptTag && gsubTable != NULL && gsubTable->coversScript( v2ScriptTag )) {
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success);
}
else if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) {
switch (scriptCode) { switch (scriptCode) {
case bengScriptCode: case bengScriptCode:
case devaScriptCode: case devaScriptCode:
...@@ -538,11 +597,15 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -538,11 +597,15 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
case tamlScriptCode: case tamlScriptCode:
case teluScriptCode: case teluScriptCode:
case sinhScriptCode: case sinhScriptCode:
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, FALSE, gsubTable, success);
break; break;
case arabScriptCode: case arabScriptCode:
result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break;
case hangScriptCode:
result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break; break;
case haniScriptCode: case haniScriptCode:
...@@ -554,36 +617,35 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -554,36 +617,35 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
case zhtLanguageCode: case zhtLanguageCode:
case zhsLanguageCode: case zhsLanguageCode:
if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) { if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) {
result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break; break;
} }
// note: falling through to default case. // note: falling through to default case.
default: default:
result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break; break;
} }
break; break;
#if 0
case tibtScriptCode: case tibtScriptCode:
result = new TibetanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); result = new TibetanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break; break;
#endif
case khmrScriptCode: case khmrScriptCode:
result = new KhmerOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); result = new KhmerOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break; break;
default: default:
result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable); result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break; break;
} }
} else { } else {
const MorphTableHeader *morphTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag); const MorphTableHeader *morphTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
if (morphTable != NULL) { if (morphTable != NULL) {
result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable); result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable, success);
} else { } else {
switch (scriptCode) { switch (scriptCode) {
case bengScriptCode: case bengScriptCode:
...@@ -597,29 +659,38 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan ...@@ -597,29 +659,38 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
case teluScriptCode: case teluScriptCode:
case sinhScriptCode: case sinhScriptCode:
{ {
result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break; break;
} }
case arabScriptCode: case arabScriptCode:
//case hebrScriptCode: //case hebrScriptCode:
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break; break;
//case hebrScriptCode: //case hebrScriptCode:
// return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); // return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
case thaiScriptCode: case thaiScriptCode:
result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break;
case hangScriptCode:
result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break; break;
default: default:
result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags); result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
break; break;
} }
} }
} }
if (result && LE_FAILURE(success)) {
delete result;
result = NULL;
}
if (result == NULL) { if (result == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR; success = LE_MEMORY_ALLOCATION_ERROR;
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* /*
* *
* *
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved
* *
*/ */
...@@ -58,10 +58,6 @@ le_uint32 LigatureSubstitutionSubtable::process(GlyphIterator *glyphIterator, co ...@@ -58,10 +58,6 @@ le_uint32 LigatureSubstitutionSubtable::process(GlyphIterator *glyphIterator, co
TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph); TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph);
le_uint16 comp; le_uint16 comp;
if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, ligGlyph))) {
continue;
}
for (comp = 0; comp < compCount; comp += 1) { for (comp = 0; comp < compCount; comp += 1) {
if (! glyphIterator->next()) { if (! glyphIterator->next()) {
break; break;
...@@ -72,7 +68,7 @@ le_uint32 LigatureSubstitutionSubtable::process(GlyphIterator *glyphIterator, co ...@@ -72,7 +68,7 @@ le_uint32 LigatureSubstitutionSubtable::process(GlyphIterator *glyphIterator, co
} }
} }
if (comp == compCount) { if (comp == compCount && (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, ligGlyph)))) {
GlyphIterator tempIterator(*glyphIterator); GlyphIterator tempIterator(*glyphIterator);
TTGlyphID deletedGlyph = tempIterator.ignoresMarks()? 0xFFFE : 0xFFFF; TTGlyphID deletedGlyph = tempIterator.ignoresMarks()? 0xFFFE : 0xFFFF;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
/* /*
* *
* (C) Copyright IBM Corp. 2002-2004 - All Rights Reserved * (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved
* *
*/ */
...@@ -54,7 +54,7 @@ public: ...@@ -54,7 +54,7 @@ public:
void add(le_int32 baseIndex, le_int32 mpreIndex); void add(le_int32 baseIndex, le_int32 mpreIndex);
void apply(LEGlyphStorage &glyphStorage); void apply(LEGlyphStorage &glyphStorage, LEErrorCode& success);
private: private:
FixupData *fFixupData; FixupData *fFixupData;
......
...@@ -74,7 +74,7 @@ void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage) ...@@ -74,7 +74,7 @@ void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage)
if (offset != 0) { if (offset != 0) {
TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader + offset); TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader + offset);
TTGlyphID newGlyph = (TTGlyphID)SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]); TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]);
glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
} }
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册