X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/46f4442e9a5a4f3b98b7c1083586332f6a8a99a4..ef6cf650f4a75c3f97de06b51fa104f2069b9ea2:/icuSources/layout/GlyphIterator.cpp?ds=sidebyside diff --git a/icuSources/layout/GlyphIterator.cpp b/icuSources/layout/GlyphIterator.cpp index d859c57c..72d2dd13 100644 --- a/icuSources/layout/GlyphIterator.cpp +++ b/icuSources/layout/GlyphIterator.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -16,18 +16,21 @@ U_NAMESPACE_BEGIN GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, - FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader) + FeatureMask theFeatureMask, const LEReferenceTo &theGlyphDefinitionTableHeader) : direction(1), position(-1), nextLimit(-1), prevLimit(-1), glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments), srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0), - glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL) + glyphClassDefinitionTable(), markAttachClassDefinitionTable() { + LEErrorCode success = LE_NO_ERROR; // TODO le_int32 glyphCount = glyphStorage.getGlyphCount(); - if (theGlyphDefinitionTableHeader != NULL) { - glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable(); - markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable(); + if (theGlyphDefinitionTableHeader.isValid()) { + glyphClassDefinitionTable = theGlyphDefinitionTableHeader + -> getGlyphClassDefinitionTable(theGlyphDefinitionTableHeader, success); + markAttachClassDefinitionTable = theGlyphDefinitionTableHeader + ->getMarkAttachClassDefinitionTable(theGlyphDefinitionTableHeader, success); } nextLimit = glyphCount; @@ -38,6 +41,7 @@ GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjus nextLimit = -1; prevLimit = glyphCount; } + filterResetCache(); } GlyphIterator::GlyphIterator(GlyphIterator &that) @@ -56,6 +60,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that) glyphGroup = that.glyphGroup; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; + filterResetCache(); } GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask) @@ -74,6 +79,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask) glyphGroup = 0; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; + filterResetCache(); } GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags) @@ -92,6 +98,7 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags) glyphGroup = that.glyphGroup; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; + filterResetCache(); } GlyphIterator::~GlyphIterator() @@ -105,11 +112,12 @@ void GlyphIterator::reset(le_uint16 newLookupFlags, FeatureMask newFeatureMask) featureMask = newFeatureMask; glyphGroup = 0; lookupFlags = newLookupFlags; + filterResetCache(); } -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() @@ -353,51 +361,68 @@ void GlyphIterator::setCursiveGlyph() glyphPositionAdjustments->setCursiveGlyph(position, baselineIsLogicalEnd()); } -le_bool GlyphIterator::filterGlyph(le_uint32 index) const +void GlyphIterator::filterResetCache(void) { + filterCacheValid = FALSE; +} + +le_bool GlyphIterator::filterGlyph(le_uint32 index) { LEGlyphID glyphID = glyphStorage[index]; - le_int32 glyphClass = gcdNoGlyphClass; - - if (LE_GET_GLYPH(glyphID) >= 0xFFFE) { - return TRUE; - } - - if (glyphClassDefinitionTable != NULL) { - glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID); - } - - switch (glyphClass) - { - case gcdNoGlyphClass: - return FALSE; - - case gcdSimpleGlyph: - return (lookupFlags & lfIgnoreBaseGlyphs) != 0; - case gcdLigatureGlyph: - return (lookupFlags & lfIgnoreLigatures) != 0; - - case gcdMarkGlyph: - { - if ((lookupFlags & lfIgnoreMarks) != 0) { - return TRUE; + if (!filterCacheValid || filterCache.id != glyphID) { + filterCache.id = glyphID; + + le_bool &filterResult = filterCache.result; // NB: Making this a reference to accept the updated value, in case + // we want more fancy cacheing in the future. + if (LE_GET_GLYPH(glyphID) >= 0xFFFE) { + filterResult = TRUE; + } else { + LEErrorCode success = LE_NO_ERROR; + le_int32 glyphClass = gcdNoGlyphClass; + if (glyphClassDefinitionTable.isValid()) { + glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success); } - - le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift; - - if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) { - return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType; + switch (glyphClass) { + case gcdNoGlyphClass: + filterResult = FALSE; + break; + + case gcdSimpleGlyph: + filterResult = (lookupFlags & lfIgnoreBaseGlyphs) != 0; + break; + + case gcdLigatureGlyph: + filterResult = (lookupFlags & lfIgnoreLigatures) != 0; + break; + + case gcdMarkGlyph: + if ((lookupFlags & lfIgnoreMarks) != 0) { + filterResult = TRUE; + } else { + le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift; + + if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) { + filterResult = (markAttachClassDefinitionTable + -> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType); + } else { + filterResult = FALSE; + } + } + break; + + case gcdComponentGlyph: + filterResult = ((lookupFlags & lfIgnoreBaseGlyphs) != 0); + break; + + default: + filterResult = FALSE; + break; } - - return FALSE; - } - - case gcdComponentGlyph: - return (lookupFlags & lfIgnoreBaseGlyphs) != 0; - - default: - return FALSE; + } + filterCacheValid = TRUE; } + + return filterCache.result; } le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup) const @@ -436,6 +461,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta) while (newPosition != nextLimit && delta > 0) { do { newPosition += direction; + //fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta); } while (newPosition != nextLimit && filterGlyph(newPosition)); delta -= 1; @@ -443,6 +469,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta) position = newPosition; + //fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta); return position != nextLimit; } @@ -458,6 +485,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta) while (newPosition != prevLimit && delta > 0) { do { newPosition -= direction; + //fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta); } while (newPosition != prevLimit && filterGlyph(newPosition)); delta -= 1; @@ -465,6 +493,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta) position = newPosition; + //fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta); return position != prevLimit; }