X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/374ca955a76ecab1204ca8bfa63ff9238d998416..1546d4af2ed1219a41ef4170bf188f2ab91442e6:/icuSources/layout/ContextualSubstSubtables.cpp diff --git a/icuSources/layout/ContextualSubstSubtables.cpp b/icuSources/layout/ContextualSubstSubtables.cpp index a1541b9f..4c066f1e 100644 --- a/icuSources/layout/ContextualSubstSubtables.cpp +++ b/icuSources/layout/ContextualSubstSubtables.cpp @@ -1,6 +1,5 @@ /* - * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved * */ @@ -28,18 +27,23 @@ void ContextualSubstitutionBase::applySubstitutionLookups( le_uint16 substCount, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, - le_int32 position) + le_int32 position, + LEErrorCode& success) { + if (LE_FAILURE(success)) { + return; + } + 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 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex); tempIterator.setCurrStreamPosition(position); tempIterator.next(sequenceIndex); - lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance); + lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance, success); } } @@ -141,9 +145,15 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa return TRUE; } -le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + switch(SWAPW(subtableFormat)) { case 0: @@ -152,22 +162,19 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP case 1: { const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } case 2: { const ContextualSubstitutionFormat2Subtable *subtable = (const ContextualSubstitutionFormat2Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } case 3: { const ContextualSubstitutionFormat3Subtable *subtable = (const ContextualSubstitutionFormat3Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } default: @@ -175,11 +182,17 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP } } -le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success); if (coverageIndex >= 0) { le_uint16 srSetCount = SWAPW(subRuleSetCount); @@ -203,7 +216,7 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor * const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount]; - applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); + applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return matchCount + 1; } @@ -218,11 +231,17 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor * return 0; } -le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success); if (coverageIndex >= 0) { const ClassDefinitionTable *classDefinitionTable = @@ -249,7 +268,7 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor * const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount]; - applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); + applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return matchCount + 1; } @@ -264,9 +283,15 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor * return 0; } -le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance)const +le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success)const { + if (LE_FAILURE(success)) { + return 0; + } + le_uint16 gCount = SWAPW(glyphCount); le_uint16 subCount = SWAPW(substCount); le_int32 position = glyphIterator->getCurrStreamPosition(); @@ -281,7 +306,7 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor * const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount]; - ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position); + ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position, success); return gCount + 1; } @@ -291,9 +316,15 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor * return 0; } -le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + switch(SWAPW(subtableFormat)) { case 0: @@ -302,22 +333,19 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor case 1: { const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } case 2: { const ChainingContextualSubstitutionFormat2Subtable *subtable = (const ChainingContextualSubstitutionFormat2Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } case 3: { const ChainingContextualSubstitutionFormat3Subtable *subtable = (const ChainingContextualSubstitutionFormat3Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } default: @@ -325,13 +353,23 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor } } -static const LETag emptyTag = 0; +// NOTE: This could be a #define, but that seems to confuse +// the Visual Studio .NET 2003 compiler on the calls to the +// GlyphIterator constructor. It somehow can't decide if +// emptyFeatureList matches an le_uint32 or an le_uint16... +static const FeatureMask emptyFeatureList = 0x00000000UL; -le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success); if (coverageIndex >= 0) { le_uint16 srSetCount = SWAPW(chainSubRuleSetCount); @@ -342,7 +380,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset); le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); - GlyphIterator tempIterator(*glyphIterator, emptyTag); + GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) { Offset chainSubRuleTableOffset = @@ -377,7 +415,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1]; - applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); + applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return inputGlyphCount + 1; } @@ -392,11 +430,17 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro return 0; } -le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success); if (coverageIndex >= 0) { const ClassDefinitionTable *backtrackClassDefinitionTable = @@ -414,7 +458,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro (const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset); le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); - GlyphIterator tempIterator(*glyphIterator, emptyTag); + GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) { Offset chainSubClassRuleTableOffset = @@ -422,6 +466,12 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro const ChainSubClassRuleTable *chainSubClassRuleTable = (const ChainSubClassRuleTable *) ((char *) chainSubClassSetTable + chainSubClassRuleTableOffset); le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount); + + // TODO: Ticket #11557 - enable this check, originally from ticket #11525. + // Depends on other, more extensive, changes. + // LEReferenceToArrayOf backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount); + if( LE_FAILURE(success) ) { return 0; } + le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1; const le_uint16 *inputClassArray = &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1]; le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray[inputGlyphCount]); @@ -451,7 +501,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1]; - applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); + applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return inputGlyphCount + 1; } @@ -466,9 +516,15 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro return 0; } -le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode & success) const { + if (LE_FAILURE(success)) { + return 0; + } + le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount); le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]); const Offset *inputCoverageTableOffsetArray = &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1]; @@ -476,7 +532,7 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro const Offset *lookaheadCoverageTableOffsetArray = &inputCoverageTableOffsetArray[inputGlyphCount + 1]; le_uint16 substCount = (le_uint16) SWAPW(lookaheadCoverageTableOffsetArray[lookaheadGlyphCount]); le_int32 position = glyphIterator->getCurrStreamPosition(); - GlyphIterator tempIterator(*glyphIterator, emptyTag); + GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); if (! tempIterator.prev(backtrkGlyphCount)) { return 0; @@ -506,7 +562,7 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1]; - ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); + ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return inputGlyphCount; }