X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/374ca955a76ecab1204ca8bfa63ff9238d998416..ef6cf650f4a75c3f97de06b51fa104f2069b9ea2:/icuSources/layout/GlyphIterator.cpp diff --git a/icuSources/layout/GlyphIterator.cpp b/icuSources/layout/GlyphIterator.cpp index 20bcc860..72d2dd13 100644 --- a/icuSources/layout/GlyphIterator.cpp +++ b/icuSources/layout/GlyphIterator.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -15,20 +15,22 @@ U_NAMESPACE_BEGIN -GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustment *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag, - const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader) +GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, + FeatureMask theFeatureMask, const LEReferenceTo &theGlyphDefinitionTableHeader) : direction(1), position(-1), nextLimit(-1), prevLimit(-1), - cursiveFirstPosition(-1), cursiveLastPosition(-1), cursiveBaselineAdjustment(0), glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments), - srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureTag(theFeatureTag), - glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL) + srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0), + 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; @@ -39,6 +41,7 @@ GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjus nextLimit = -1; prevLimit = glyphCount; } + filterResetCache(); } GlyphIterator::GlyphIterator(GlyphIterator &that) @@ -49,19 +52,18 @@ GlyphIterator::GlyphIterator(GlyphIterator &that) nextLimit = that.nextLimit; prevLimit = that.prevLimit; - cursiveFirstPosition = that.cursiveFirstPosition; - cursiveLastPosition = that.cursiveLastPosition; - glyphPositionAdjustments = that.glyphPositionAdjustments; srcIndex = that.srcIndex; destIndex = that.destIndex; lookupFlags = that.lookupFlags; - featureTag = that.featureTag; + featureMask = that.featureMask; + glyphGroup = that.glyphGroup; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; + filterResetCache(); } -GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag) +GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask) : glyphStorage(that.glyphStorage) { direction = that.direction; @@ -69,16 +71,15 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag) nextLimit = that.nextLimit; prevLimit = that.prevLimit; - cursiveFirstPosition = that.cursiveFirstPosition; - cursiveLastPosition = that.cursiveLastPosition; - glyphPositionAdjustments = that.glyphPositionAdjustments; srcIndex = that.srcIndex; destIndex = that.destIndex; lookupFlags = that.lookupFlags; - featureTag = newFeatureTag; + featureMask = newFeatureMask; + glyphGroup = 0; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; + filterResetCache(); } GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags) @@ -89,17 +90,15 @@ GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags) nextLimit = that.nextLimit; prevLimit = that.prevLimit; - - cursiveFirstPosition = that.cursiveFirstPosition; - cursiveLastPosition = that.cursiveLastPosition; - glyphPositionAdjustments = that.glyphPositionAdjustments; srcIndex = that.srcIndex; destIndex = that.destIndex; lookupFlags = newLookupFlags; - featureTag = that.featureTag; + featureMask = that.featureMask; + glyphGroup = that.glyphGroup; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; + filterResetCache(); } GlyphIterator::~GlyphIterator() @@ -107,16 +106,18 @@ GlyphIterator::~GlyphIterator() // nothing to do, right? } -void GlyphIterator::reset(le_uint16 newLookupFlags, LETag newFeatureTag) +void GlyphIterator::reset(le_uint16 newLookupFlags, FeatureMask newFeatureMask) { - position = prevLimit; - featureTag = newFeatureTag; - lookupFlags = newLookupFlags; + position = prevLimit; + 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() @@ -152,16 +153,6 @@ le_bool GlyphIterator::baselineIsLogicalEnd() const return (lookupFlags & lfBaselineIsLogicalEnd) != 0; } -le_bool GlyphIterator::hasCursiveFirstExitPoint() const -{ - return cursiveFirstPosition >= 0; -} - -le_bool GlyphIterator::hasCursiveLastExitPoint() const -{ - return cursiveLastPosition >= 0; -} - LEGlyphID GlyphIterator::getCurrGlyphID() const { if (direction < 0) { @@ -177,39 +168,10 @@ LEGlyphID GlyphIterator::getCurrGlyphID() const return glyphStorage[position]; } -LEGlyphID GlyphIterator::getCursiveLastGlyphID() const +void GlyphIterator::getCursiveEntryPoint(LEPoint &entryPoint) const { if (direction < 0) { - if (cursiveLastPosition <= nextLimit || cursiveLastPosition >= prevLimit) { - return 0xFFFF; - } - } else { - if (cursiveLastPosition <= prevLimit || cursiveLastPosition >= nextLimit) { - return 0xFFFF; - } - } - - return glyphStorage[cursiveLastPosition]; -} - -void GlyphIterator::getCursiveLastExitPoint(LEPoint &exitPoint) const -{ - if (cursiveLastPosition >= 0) { - exitPoint = cursiveLastExitPoint; - } -} - -float GlyphIterator::getCursiveBaselineAdjustment() const -{ - return cursiveBaselineAdjustment; -} - -void GlyphIterator::getCurrGlyphPositionAdjustment(GlyphPositionAdjustment &adjustment) const -{ - if (direction < 0) - { - if (position <= nextLimit || position >= prevLimit) - { + if (position <= nextLimit || position >= prevLimit) { return; } } else { @@ -218,24 +180,22 @@ void GlyphIterator::getCurrGlyphPositionAdjustment(GlyphPositionAdjustment &adju } } - adjustment = glyphPositionAdjustments[position]; + glyphPositionAdjustments->getEntryPoint(position, entryPoint); } -void GlyphIterator::getCursiveLastPositionAdjustment(GlyphPositionAdjustment &adjustment) const +void GlyphIterator::getCursiveExitPoint(LEPoint &exitPoint) const { - if (direction < 0) - { - if (cursiveLastPosition <= nextLimit || cursiveLastPosition >= prevLimit) - { + if (direction < 0) { + if (position <= nextLimit || position >= prevLimit) { return; } } else { - if (cursiveLastPosition <= prevLimit || cursiveLastPosition >= nextLimit) { + if (position <= prevLimit || position >= nextLimit) { return; } } - adjustment = glyphPositionAdjustments[cursiveLastPosition]; + glyphPositionAdjustments->getExitPoint(position, exitPoint); } void GlyphIterator::setCurrGlyphID(TTGlyphID glyphID) @@ -247,10 +207,6 @@ void GlyphIterator::setCurrGlyphID(TTGlyphID glyphID) void GlyphIterator::setCurrStreamPosition(le_int32 newPosition) { - cursiveFirstPosition = -1; - cursiveLastPosition = -1; - cursiveBaselineAdjustment = 0; - if (direction < 0) { if (newPosition >= prevLimit) { position = prevLimit; @@ -277,7 +233,7 @@ void GlyphIterator::setCurrStreamPosition(le_int32 newPosition) next(); } -void GlyphIterator::setCurrGlyphPositionAdjustment(const GlyphPositionAdjustment *adjustment) +void GlyphIterator::setCurrGlyphBaseOffset(le_int32 baseOffset) { if (direction < 0) { if (position <= nextLimit || position >= prevLimit) { @@ -289,10 +245,11 @@ void GlyphIterator::setCurrGlyphPositionAdjustment(const GlyphPositionAdjustment } } - glyphPositionAdjustments[position] = *adjustment; + glyphPositionAdjustments->setBaseOffset(position, baseOffset); } -void GlyphIterator::setCurrGlyphBaseOffset(le_int32 baseOffset) +void GlyphIterator::adjustCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust, + float xAdvanceAdjust, float yAdvanceAdjust) { if (direction < 0) { if (position <= nextLimit || position >= prevLimit) { @@ -304,10 +261,13 @@ void GlyphIterator::setCurrGlyphBaseOffset(le_int32 baseOffset) } } - glyphPositionAdjustments[position].setBaseOffset(baseOffset); + glyphPositionAdjustments->adjustXPlacement(position, xPlacementAdjust); + glyphPositionAdjustments->adjustYPlacement(position, yPlacementAdjust); + glyphPositionAdjustments->adjustXAdvance(position, xAdvanceAdjust); + glyphPositionAdjustments->adjustYAdvance(position, yAdvanceAdjust); } -void GlyphIterator::adjustCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust, +void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust, float xAdvanceAdjust, float yAdvanceAdjust) { if (direction < 0) { @@ -320,14 +280,13 @@ void GlyphIterator::adjustCurrGlyphPositionAdjustment(float xPlacementAdjust, fl } } - glyphPositionAdjustments[position].adjustXPlacement(xPlacementAdjust); - glyphPositionAdjustments[position].adjustYPlacement(yPlacementAdjust); - glyphPositionAdjustments[position].adjustXAdvance(xAdvanceAdjust); - glyphPositionAdjustments[position].adjustYAdvance(yAdvanceAdjust); + glyphPositionAdjustments->setXPlacement(position, xPlacementAdjust); + glyphPositionAdjustments->setYPlacement(position, yPlacementAdjust); + glyphPositionAdjustments->setXAdvance(position, xAdvanceAdjust); + glyphPositionAdjustments->setYAdvance(position, yAdvanceAdjust); } -void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust, - float xAdvanceAdjust, float yAdvanceAdjust) +void GlyphIterator::clearCursiveEntryPoint() { if (direction < 0) { if (position <= nextLimit || position >= prevLimit) { @@ -339,13 +298,10 @@ void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float } } - glyphPositionAdjustments[position].setXPlacement(xPlacementAdjust); - glyphPositionAdjustments[position].setYPlacement(yPlacementAdjust); - glyphPositionAdjustments[position].setXAdvance(xAdvanceAdjust); - glyphPositionAdjustments[position].setYAdvance(yAdvanceAdjust); + glyphPositionAdjustments->clearEntryPoint(position); } -void GlyphIterator::setCursiveFirstExitPoint() +void GlyphIterator::clearCursiveExitPoint() { if (direction < 0) { if (position <= nextLimit || position >= prevLimit) { @@ -357,31 +313,25 @@ void GlyphIterator::setCursiveFirstExitPoint() } } - cursiveFirstPosition = position; + glyphPositionAdjustments->clearExitPoint(position); } -void GlyphIterator::resetCursiveLastExitPoint() +void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint) { - if ((lookupFlags & lfBaselineIsLogicalEnd) != 0 && cursiveFirstPosition >= 0 && cursiveLastPosition >= 0) { - le_int32 savePosition = position, saveLimit = nextLimit; - - position = cursiveFirstPosition - direction; - nextLimit = cursiveLastPosition + direction; - - while (nextInternal()) { - glyphPositionAdjustments[position].adjustYPlacement(-cursiveBaselineAdjustment); + if (direction < 0) { + if (position <= nextLimit || position >= prevLimit) { + return; + } + } else { + if (position <= prevLimit || position >= nextLimit) { + return; } - - position = savePosition; - nextLimit = saveLimit; } - cursiveLastPosition = -1; - cursiveFirstPosition = -1; - cursiveBaselineAdjustment = 0; + glyphPositionAdjustments->setEntryPoint(position, entryPoint, baselineIsLogicalEnd()); } -void GlyphIterator::setCursiveLastExitPoint(LEPoint &exitPoint) +void GlyphIterator::setCursiveExitPoint(LEPoint &exitPoint) { if (direction < 0) { if (position <= nextLimit || position >= prevLimit) { @@ -393,110 +343,109 @@ void GlyphIterator::setCursiveLastExitPoint(LEPoint &exitPoint) } } - cursiveLastPosition = position; - cursiveLastExitPoint = exitPoint; - + glyphPositionAdjustments->setExitPoint(position, exitPoint, baselineIsLogicalEnd()); } -void GlyphIterator::setCursiveBaselineAdjustment(float adjustment) -{ - cursiveBaselineAdjustment = adjustment; -} - -void GlyphIterator::adjustCursiveLastGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust, - float xAdvanceAdjust, float yAdvanceAdjust) +void GlyphIterator::setCursiveGlyph() { if (direction < 0) { - if (cursiveLastPosition <= nextLimit || cursiveLastPosition >= prevLimit) { + if (position <= nextLimit || position >= prevLimit) { return; } } else { - if (cursiveLastPosition <= prevLimit || cursiveLastPosition >= nextLimit) { + if (position <= prevLimit || position >= nextLimit) { return; } } - glyphPositionAdjustments[cursiveLastPosition].adjustXPlacement(xPlacementAdjust); - glyphPositionAdjustments[cursiveLastPosition].adjustYPlacement(yPlacementAdjust); - glyphPositionAdjustments[cursiveLastPosition].adjustXAdvance(xAdvanceAdjust); - glyphPositionAdjustments[cursiveLastPosition].adjustYAdvance(yAdvanceAdjust); + 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); + } + 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; - le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift; + case gcdComponentGlyph: + filterResult = ((lookupFlags & lfIgnoreBaseGlyphs) != 0); + break; - if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) { - return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType; + default: + filterResult = FALSE; + break; } - - return FALSE; - } - - case gcdComponentGlyph: - return (lookupFlags & lfIgnoreBaseGlyphs) != 0; - - default: - return FALSE; + } + filterCacheValid = TRUE; } + + return filterCache.result; } -static const LETag emptyTag = 0; -static const LETag defaultTag = 0xFFFFFFFF; - -le_bool GlyphIterator::hasFeatureTag() const +le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup) const { - if (featureTag == defaultTag || featureTag == emptyTag) { + if (featureMask == 0) { return TRUE; } LEErrorCode success = LE_NO_ERROR; - const LETag *tagList = (const LETag *) glyphStorage.getAuxData(position, success); - - if (tagList != NULL) { - for (le_int32 tag = 0; tagList[tag] != emptyTag; tag += 1) { - if (tagList[tag] == featureTag) { - return TRUE; - } - } - } + FeatureMask fm = glyphStorage.getAuxData(position, success); - return FALSE; + return ((fm & featureMask) == featureMask) && (!matchGroup || (le_int32)(fm & LE_GLYPH_GROUP_MASK) == glyphGroup); } le_bool GlyphIterator::findFeatureTag() { + //glyphGroup = 0; + while (nextInternal()) { - if (hasFeatureTag()) { - prevInternal(); + if (hasFeatureTag(FALSE)) { + LEErrorCode success = LE_NO_ERROR; + + glyphGroup = (glyphStorage.getAuxData(position, success) & LE_GLYPH_GROUP_MASK); return TRUE; } } @@ -512,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; @@ -519,12 +469,13 @@ 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; } le_bool GlyphIterator::next(le_uint32 delta) { - return nextInternal(delta) && hasFeatureTag(); + return nextInternal(delta) && hasFeatureTag(TRUE); } le_bool GlyphIterator::prevInternal(le_uint32 delta) @@ -534,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; @@ -541,12 +493,13 @@ 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; } le_bool GlyphIterator::prev(le_uint32 delta) { - return prevInternal(delta) && hasFeatureTag(); + return prevInternal(delta) && hasFeatureTag(TRUE); } le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const