X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..249c4c5ea9376c24572daf9c2effa7484a282f14:/icuSources/layout/MultipleSubstSubtables.cpp?ds=sidebyside diff --git a/icuSources/layout/MultipleSubstSubtables.cpp b/icuSources/layout/MultipleSubstSubtables.cpp index 65b0c610..4fdc0a4d 100644 --- a/icuSources/layout/MultipleSubstSubtables.cpp +++ b/icuSources/layout/MultipleSubstSubtables.cpp @@ -1,7 +1,6 @@ /* - * %W% %E% * - * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved * */ @@ -15,12 +14,33 @@ U_NAMESPACE_BEGIN -le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const +le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const { + if (LE_FAILURE(success)) { + return 0; + } + LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + + // If there's a filter, we only want to do the + // substitution if the *input* glyphs doesn't + // exist. + // + // FIXME: is this always the right thing to do? + // FIXME: should this only be done for a non-zero + // glyphCount? + if (filter != NULL && filter->accept(glyph)) { + return 0; + } + + le_int32 coverageIndex = getGlyphCoverage(base, glyph, success); le_uint16 seqCount = SWAPW(sequenceCount); + LEReferenceToArrayOf + sequenceTableOffsetArrayRef(base, success, sequenceTableOffsetArray, seqCount); + if (LE_FAILURE(success)) { + return 0; + } if (coverageIndex >= 0 && coverageIndex < seqCount) { Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]); const SequenceTable *sequenceTable = (const SequenceTable *) ((char *) this + sequenceTableOffset); @@ -29,17 +49,47 @@ le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, co if (glyphCount == 0) { glyphIterator->setCurrGlyphID(0xFFFF); return 1; - } else if (glyphCount >= 1) { + } else if (glyphCount == 1) { TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]); - if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, substitute))) { - glyphIterator->setCurrGlyphID(substitute); + if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute))) { + return 0; } + glyphIterator->setCurrGlyphID(substitute); return 1; } else { - // Can't do this 'till there's a way to - // grow the glyph array... + // If there's a filter, make sure all of the output glyphs + // exist. + if (filter != NULL) { + for (le_int32 i = 0; i < glyphCount; i += 1) { + TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]); + + if (! filter->accept(substitute)) { + return 0; + } + } + } + + LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount, success); + if (LE_FAILURE(success)) { + return 0; + } + + le_int32 insert = 0, direction = 1; + + if (glyphIterator->isRightToLeft()) { + insert = glyphCount - 1; + direction = -1; + } + + for (le_int32 i = 0; i < glyphCount; i += 1) { + TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]); + + newGlyphs[insert] = LE_SET_GLYPH(glyph, substitute); + insert += direction; + } + return 1; } }