le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const { LEGlyphID glyph = (LEGlyphID) glyphIterator->getCurrGlyphID(); le_int32 coverageIndex = getGlyphCoverage(glyph); if (coverageIndex >= 0) { le_uint16 srSetCount = SWAPW(chainSubRuleSetCount); if (coverageIndex < srSetCount) { Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]); const ChainSubRuleSetTable *chainSubRuleSetTable = (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset); le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); GlyphIterator tempIterator(*glyphIterator); for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) { Offset chainSubRuleTableOffset = SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]); const ChainSubRuleTable *chainSubRuleTable = (const ChainSubRuleTable *) ((char *) chainSubRuleSetTable + chainSubRuleTableOffset); le_uint16 backtrackGlyphCount = SWAPW(chainSubRuleTable->backtrackGlyphCount); le_uint16 inputGlyphCount = (le_uint16) SWAPW(chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount]) - 1; const LEGlyphID *inputGlyphArray = &chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount + 1]; le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputGlyphArray[inputGlyphCount]); const LEGlyphID *lookaheadGlyphArray = &inputGlyphArray[inputGlyphCount + 1]; le_uint16 substCount = (le_uint16) SWAPW(lookaheadGlyphArray[lookaheadGlyphCount]); tempIterator.setCurrStreamPosition(position); tempIterator.prev(backtrackGlyphCount + 1); if (! matchGlyphIDs(chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount, &tempIterator)) { continue; } tempIterator.setCurrStreamPosition(position); tempIterator.next(inputGlyphCount); if (!matchGlyphIDs(lookaheadGlyphArray, lookaheadGlyphCount, &tempIterator)) { continue; } if (matchGlyphIDs(inputGlyphArray, inputGlyphCount, glyphIterator)) { const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1]; applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); return inputGlyphCount + 1; } glyphIterator->setCurrStreamPosition(position); } } // XXX If we get here, the table is mal-formed... } return 0; }
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); if (coverageIndex >= 0) { const ClassDefinitionTable *classDefinitionTable = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset)); le_uint16 scSetCount = SWAPW(subClassSetCount); le_int32 setClass = classDefinitionTable->getGlyphClass(glyphIterator->getCurrGlyphID()); if (setClass < scSetCount && subClassSetTableOffsetArray[setClass] != 0) { Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]); const SubClassSetTable *subClassSetTable = (const SubClassSetTable *) ((char *) this + subClassSetTableOffset); le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) { Offset subClassRuleTableOffset = SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]); const SubClassRuleTable *subClassRuleTable = (const SubClassRuleTable *) ((char *) subClassSetTable + subClassRuleTableOffset); le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1; le_uint16 substCount = SWAPW(subClassRuleTable->substCount); if (matchGlyphClasses(subClassRuleTable->classArray, matchCount, glyphIterator, classDefinitionTable)) { const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount]; applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return matchCount + 1; } glyphIterator->setCurrStreamPosition(position); } } // XXX If we get here, the table is mal-formed... } return 0; }
le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const { LEGlyphID glyph = (LEGlyphID) glyphIterator->getCurrGlyphID(); le_int32 coverageIndex = getGlyphCoverage(glyph); if (coverageIndex >= 0) { le_uint16 srSetCount = SWAPW(subRuleSetCount); if (coverageIndex < srSetCount) { Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]); const SubRuleSetTable *subRuleSetTable = (const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset); le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) { Offset subRuleTableOffset = SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]); const SubRuleTable *subRuleTable = (const SubRuleTable *) ((char *) subRuleSetTable + subRuleTableOffset); le_uint16 matchCount = SWAPW(subRuleTable->glyphCount) - 1; le_uint16 substCount = SWAPW(subRuleTable->substCount); if (matchGlyphIDs(subRuleTable->inputGlyphArray, matchCount, glyphIterator)) { const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount]; applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); return matchCount + 1; } glyphIterator->setCurrStreamPosition(position); } } // XXX If we get here, the table is mal-formed... } return 0; }
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const { LEGlyphID glyph = glyphIterator->getCurrGlyphID(); le_int32 coverageIndex = getGlyphCoverage(glyph); if (coverageIndex >= 0) { const ClassDefinitionTable *backtrackClassDefinitionTable = (const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset)); const ClassDefinitionTable *inputClassDefinitionTable = (const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset)); const ClassDefinitionTable *lookaheadClassDefinitionTable = (const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset)); le_uint16 scSetCount = SWAPW(chainSubClassSetCount); le_int32 setClass = inputClassDefinitionTable->getGlyphClass(glyphIterator->getCurrGlyphID()); if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) { Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]); const ChainSubClassSetTable *chainSubClassSetTable = (const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset); le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) { Offset chainSubClassRuleTableOffset = SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]); const ChainSubClassRuleTable *chainSubClassRuleTable = (const ChainSubClassRuleTable *) ((char *) chainSubClassSetTable + chainSubClassRuleTableOffset); le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount); le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1; const le_uint16 *inputClassArray = &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1]; le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray[inputGlyphCount]); const le_uint16 *lookaheadClassArray = &inputClassArray[inputGlyphCount + 1]; le_uint16 substCount = SWAPW(lookaheadClassArray[lookaheadGlyphCount]); tempIterator.setCurrStreamPosition(position); if (! tempIterator.prev(backtrackGlyphCount)) { continue; } tempIterator.prev(); if (! matchGlyphClasses(chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount, &tempIterator, backtrackClassDefinitionTable, TRUE)) { continue; } tempIterator.setCurrStreamPosition(position); tempIterator.next(inputGlyphCount); if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable)) { continue; } if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable)) { const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1]; applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); return inputGlyphCount + 1; } glyphIterator->setCurrStreamPosition(position); } } // XXX If we get here, the table is mal-formed... } return 0; }
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LETableReference &base, 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(lookupProcessor->getReference(), glyph, success); if (LE_FAILURE(success)) { return 0; } if (coverageIndex >= 0) { LEReferenceTo<ClassDefinitionTable> backtrackClassDefinitionTable(base, success, SWAPW(backtrackClassDefTableOffset)); LEReferenceTo<ClassDefinitionTable> inputClassDefinitionTable(base, success, SWAPW(inputClassDefTableOffset)); LEReferenceTo<ClassDefinitionTable> lookaheadClassDefinitionTable(base, success, SWAPW(lookaheadClassDefTableOffset)); le_uint16 scSetCount = SWAPW(chainSubClassSetCount); le_int32 setClass = inputClassDefinitionTable->getGlyphClass(inputClassDefinitionTable, glyphIterator->getCurrGlyphID(), success); LEReferenceToArrayOf<Offset> chainSubClassSetTableOffsetArrayRef(base, success, chainSubClassSetTableOffsetArray, scSetCount); if (LE_FAILURE(success)) { return 0; } if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) { Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]); LEReferenceTo<ChainSubClassSetTable> chainSubClassSetTable(base, success, chainSubClassSetTableOffset); if (LE_FAILURE(success)) { return 0; } le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); LEReferenceToArrayOf<Offset> chainSubClassRuleTableOffsetArrayRef(base, success, chainSubClassSetTable->chainSubClassRuleTableOffsetArray, chainSubClassRuleCount); if (LE_FAILURE(success)) { return 0; } for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) { Offset chainSubClassRuleTableOffset = SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]); LEReferenceTo<ChainSubClassRuleTable> chainSubClassRuleTable(chainSubClassSetTable, success, chainSubClassRuleTableOffset); if (LE_FAILURE(success)) { return 0; } le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount); LEReferenceToArrayOf<le_uint16> backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount); if( LE_FAILURE(success) ) { return 0; } le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1; LEReferenceToArrayOf<le_uint16> inputClassArray(base, success, &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1],inputGlyphCount+2); // +2 for the lookaheadGlyphCount count le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray.getObject(inputGlyphCount, success)); LEReferenceToArrayOf<le_uint16> lookaheadClassArray(base, success, inputClassArray.getAlias(inputGlyphCount + 1,success), lookaheadGlyphCount+2); // +2 for the substCount if( LE_FAILURE(success) ) { return 0; } le_uint16 substCount = SWAPW(lookaheadClassArray[lookaheadGlyphCount]); tempIterator.setCurrStreamPosition(position); if (! tempIterator.prev(backtrackGlyphCount)) { continue; } tempIterator.prev(); if (! matchGlyphClasses(backtrackClassArray, backtrackGlyphCount, &tempIterator, backtrackClassDefinitionTable, success, TRUE)) { continue; } tempIterator.setCurrStreamPosition(position); tempIterator.next(inputGlyphCount); if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable, success)) { continue; } if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable, success)) { LEReferenceToArrayOf<SubstitutionLookupRecord> substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadClassArray.getAlias(lookaheadGlyphCount + 1, success), substCount); if (LE_FAILURE(success)) { return 0; } applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return inputGlyphCount + 1; } glyphIterator->setCurrStreamPosition(position); } } // XXX If we get here, the table is mal-formed... } return 0; }
le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LETableReference &base, 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(lookupProcessor->getReference(), glyph, success); if (LE_FAILURE(success)) { return 0; } if (coverageIndex >= 0) { le_uint16 srSetCount = SWAPW(chainSubRuleSetCount); if (coverageIndex < srSetCount) { LEReferenceToArrayOf<Offset> chainSubRuleSetTableOffsetArrayRef(base, success, chainSubRuleSetTableOffsetArray, srSetCount); if (LE_FAILURE(success)) { return 0; } Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]); LEReferenceTo<ChainSubRuleSetTable> chainSubRuleSetTable(base, success, chainSubRuleSetTableOffset); if (LE_FAILURE(success)) { return 0; } le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); LEReferenceToArrayOf<Offset> chainSubRuleTableOffsetArrayRef(base, success, chainSubRuleSetTable->chainSubRuleTableOffsetArray, chainSubRuleCount); if (LE_FAILURE(success)) { return 0; } for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) { Offset chainSubRuleTableOffset = SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]); LEReferenceTo<ChainSubRuleTable> chainSubRuleTable = LEReferenceTo<ChainSubRuleTable>(chainSubRuleSetTable, success, chainSubRuleTableOffset); if( LE_FAILURE(success) ) { return 0; } le_uint16 backtrackGlyphCount = SWAPW(chainSubRuleTable->backtrackGlyphCount); LEReferenceToArrayOf<TTGlyphID> backtrackGlyphArray(base, success, chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount); if( LE_FAILURE(success) ) { return 0; } le_uint16 inputGlyphCount = (le_uint16) SWAPW(chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount]) - 1; LEReferenceToArrayOf<TTGlyphID> inputGlyphArray(base, success, &chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount + 1], inputGlyphCount+2); if( LE_FAILURE(success) ) { return 0; } le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputGlyphArray[inputGlyphCount]); LEReferenceToArrayOf<TTGlyphID> lookaheadGlyphArray(base, success, inputGlyphArray.getAlias(inputGlyphCount + 1,success), lookaheadGlyphCount+2); if( LE_FAILURE(success) ) { return 0; } le_uint16 substCount = (le_uint16) SWAPW(lookaheadGlyphArray[lookaheadGlyphCount]); tempIterator.setCurrStreamPosition(position); if (! tempIterator.prev(backtrackGlyphCount)) { continue; } tempIterator.prev(); if (! matchGlyphIDs(backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) { continue; } tempIterator.setCurrStreamPosition(position); tempIterator.next(inputGlyphCount); if (!matchGlyphIDs(lookaheadGlyphArray, lookaheadGlyphCount, &tempIterator)) { continue; } if (matchGlyphIDs(inputGlyphArray, inputGlyphCount, glyphIterator)) { LEReferenceToArrayOf<SubstitutionLookupRecord> substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadGlyphArray.getAlias(lookaheadGlyphCount + 1,success), substCount); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return inputGlyphCount + 1; } glyphIterator->setCurrStreamPosition(position); } } // XXX If we get here, the table is mal-formed... } return 0; }
le_uint32 ContextualSubstitutionFormat2Subtable::process(const LETableReference &base, 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(lookupProcessor->getReference(), glyph, success); if (LE_FAILURE(success)) { return 0; } if (coverageIndex >= 0) { LEReferenceTo<ClassDefinitionTable> classDefinitionTable(base, success, SWAPW(classDefTableOffset)); if (LE_FAILURE(success)) { return 0; } le_uint16 scSetCount = SWAPW(subClassSetCount); le_int32 setClass = classDefinitionTable->getGlyphClass(classDefinitionTable, glyphIterator->getCurrGlyphID(), success); if (setClass < scSetCount) { LEReferenceToArrayOf<Offset> subClassSetTableOffsetArrayRef(base, success, subClassSetTableOffsetArray, scSetCount); if (LE_FAILURE(success)) { return 0; } if (subClassSetTableOffsetArray[setClass] != 0) { Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]); LEReferenceTo<SubClassSetTable> subClassSetTable(base, success, subClassSetTableOffset); if (LE_FAILURE(success)) { return 0; } le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); LEReferenceToArrayOf<Offset> subClassRuleTableOffsetArrayRef(base, success, subClassSetTable->subClassRuleTableOffsetArray, subClassRuleCount); if (LE_FAILURE(success)) { return 0; } for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) { Offset subClassRuleTableOffset = SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]); LEReferenceTo<SubClassRuleTable> subClassRuleTable(subClassSetTable, success, subClassRuleTableOffset); if (LE_FAILURE(success)) { return 0; } le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1; le_uint16 substCount = SWAPW(subClassRuleTable->substCount); LEReferenceToArrayOf<le_uint16> classArray(base, success, subClassRuleTable->classArray, matchCount+1); if (LE_FAILURE(success)) { return 0; } if (matchGlyphClasses(classArray, matchCount, glyphIterator, classDefinitionTable, success)) { LEReferenceToArrayOf<SubstitutionLookupRecord> substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount], substCount); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return matchCount + 1; } glyphIterator->setCurrStreamPosition(position); } } } // XXX If we get here, the table is mal-formed... } return 0; }
le_uint32 ContextualSubstitutionFormat1Subtable::process(const LETableReference &base, 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(lookupProcessor->getReference(), glyph, success); if (LE_FAILURE(success)) { return 0; } if (coverageIndex >= 0) { le_uint16 srSetCount = SWAPW(subRuleSetCount); if (coverageIndex < srSetCount) { LEReferenceToArrayOf<Offset> subRuleSetTableOffsetArrayRef(base, success, subRuleSetTableOffsetArray, srSetCount); if (LE_FAILURE(success)) { return 0; } Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]); LEReferenceTo<SubRuleSetTable> subRuleSetTable(base, success, subRuleSetTableOffset); if (LE_FAILURE(success)) { return 0; } le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); LEReferenceToArrayOf<Offset> subRuleTableOffsetArrayRef(base, success, subRuleSetTable->subRuleTableOffsetArray, subRuleCount); if (LE_FAILURE(success)) { return 0; } for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) { Offset subRuleTableOffset = SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]); LEReferenceTo<SubRuleTable> subRuleTable(subRuleSetTable, success, subRuleTableOffset); if (LE_FAILURE(success)) { return 0; } le_uint16 matchCount = SWAPW(subRuleTable->glyphCount) - 1; le_uint16 substCount = SWAPW(subRuleTable->substCount); LEReferenceToArrayOf<TTGlyphID> inputGlyphArray(base, success, subRuleTable->inputGlyphArray, matchCount+2); if (LE_FAILURE(success)) { return 0; } if (matchGlyphIDs(inputGlyphArray, matchCount, glyphIterator)) { LEReferenceToArrayOf<SubstitutionLookupRecord> substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount], substCount); applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return matchCount + 1; } glyphIterator->setCurrStreamPosition(position); } } // XXX If we get here, the table is mal-formed... } return 0; }