X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..ef6cf650f4a75c3f97de06b51fa104f2069b9ea2:/icuSources/layout/GlyphIterator.cpp?ds=sidebyside diff --git a/icuSources/layout/GlyphIterator.cpp b/icuSources/layout/GlyphIterator.cpp index b612e58e..72d2dd13 100644 --- a/icuSources/layout/GlyphIterator.cpp +++ b/icuSources/layout/GlyphIterator.cpp @@ -1,7 +1,6 @@ /* - * %W% %E% * - * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -10,99 +9,128 @@ #include "GlyphDefinitionTables.h" #include "GlyphPositionAdjustments.h" #include "GlyphIterator.h" +#include "LEGlyphStorage.h" #include "Lookups.h" #include "LESwaps.h" U_NAMESPACE_BEGIN -GlyphIterator::GlyphIterator(LEGlyphID *theGlyphs, GlyphPositionAdjustment *theGlyphPositionAdjustments, le_int32 theGlyphCount, - le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag, const LETag *theGlyphTags[], - const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader) - : direction(1), position(-1), nextLimit(theGlyphCount), prevLimit(-1), - cursiveFirstPosition(-1), cursiveLastPosition(-1), cursiveBaselineAdjustment(0), - glyphs(theGlyphs), glyphPositionAdjustments(theGlyphPositionAdjustments), lookupFlags(theLookupFlags), - featureTag(theFeatureTag), glyphTags(theGlyphTags), - glyphClassDefinitionTable(NULL), - markAttachClassDefinitionTable(NULL) +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), + glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments), + srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0), + glyphClassDefinitionTable(), markAttachClassDefinitionTable() { - if (theGlyphDefinitionTableHeader != NULL) { - glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable(); - markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable(); + LEErrorCode success = LE_NO_ERROR; // TODO + le_int32 glyphCount = glyphStorage.getGlyphCount(); + + if (theGlyphDefinitionTableHeader.isValid()) { + glyphClassDefinitionTable = theGlyphDefinitionTableHeader + -> getGlyphClassDefinitionTable(theGlyphDefinitionTableHeader, success); + markAttachClassDefinitionTable = theGlyphDefinitionTableHeader + ->getMarkAttachClassDefinitionTable(theGlyphDefinitionTableHeader, success); } + nextLimit = glyphCount; + if (rightToLeft) { direction = -1; - position = theGlyphCount; + position = glyphCount; nextLimit = -1; - prevLimit = theGlyphCount; + prevLimit = glyphCount; } + filterResetCache(); } GlyphIterator::GlyphIterator(GlyphIterator &that) + : glyphStorage(that.glyphStorage) { direction = that.direction; position = that.position; nextLimit = that.nextLimit; prevLimit = that.prevLimit; - cursiveFirstPosition = that.cursiveFirstPosition; - cursiveLastPosition = that.cursiveLastPosition; - - glyphs = that.glyphs; glyphPositionAdjustments = that.glyphPositionAdjustments; + srcIndex = that.srcIndex; + destIndex = that.destIndex; lookupFlags = that.lookupFlags; - featureTag = that.featureTag; - glyphTags = that.glyphTags; + 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; position = that.position; nextLimit = that.nextLimit; prevLimit = that.prevLimit; - cursiveFirstPosition = that.cursiveFirstPosition; - cursiveLastPosition = that.cursiveLastPosition; - - glyphs = that.glyphs; glyphPositionAdjustments = that.glyphPositionAdjustments; + srcIndex = that.srcIndex; + destIndex = that.destIndex; lookupFlags = that.lookupFlags; - featureTag = newFeatureTag; - glyphTags = that.glyphTags; + featureMask = newFeatureMask; + glyphGroup = 0; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; + filterResetCache(); } GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags) + : glyphStorage(that.glyphStorage) { direction = that.direction; position = that.position; nextLimit = that.nextLimit; prevLimit = that.prevLimit; - - cursiveFirstPosition = that.cursiveFirstPosition; - cursiveLastPosition = that.cursiveLastPosition; - - glyphs = that.glyphs; glyphPositionAdjustments = that.glyphPositionAdjustments; + srcIndex = that.srcIndex; + destIndex = that.destIndex; lookupFlags = newLookupFlags; - featureTag = that.featureTag; - glyphTags = that.glyphTags; + featureMask = that.featureMask; + glyphGroup = that.glyphGroup; glyphClassDefinitionTable = that.glyphClassDefinitionTable; markAttachClassDefinitionTable = that.markAttachClassDefinitionTable; + filterResetCache(); } -GlyphIterator::GlyphIterator() +GlyphIterator::~GlyphIterator() { -}; + // nothing to do, right? +} -GlyphIterator::~GlyphIterator() +void GlyphIterator::reset(le_uint16 newLookupFlags, FeatureMask newFeatureMask) +{ + position = prevLimit; + featureMask = newFeatureMask; + glyphGroup = 0; + lookupFlags = newLookupFlags; + filterResetCache(); +} + +LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count, LEErrorCode& success) { + return glyphStorage.insertGlyphs(position, count, success); +} + +le_int32 GlyphIterator::applyInsertions() +{ + le_int32 newGlyphCount = glyphStorage.applyInsertions(); + + if (direction < 0) { + prevLimit = newGlyphCount; + } else { + nextLimit = newGlyphCount; + } + + return newGlyphCount; } le_int32 GlyphIterator::getCurrStreamPosition() const @@ -125,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) { @@ -147,42 +165,13 @@ LEGlyphID GlyphIterator::getCurrGlyphID() const } } - return glyphs[position]; + 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 glyphs[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 { @@ -191,37 +180,33 @@ 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) { - glyphs[position] = LE_SET_GLYPH(glyphs[position], glyphID); + LEGlyphID glyph = glyphStorage[position]; + + glyphStorage[position] = LE_SET_GLYPH(glyph, glyphID); } void GlyphIterator::setCurrStreamPosition(le_int32 newPosition) { - cursiveFirstPosition = -1; - cursiveLastPosition = -1; - cursiveBaselineAdjustment = 0; - if (direction < 0) { if (newPosition >= prevLimit) { position = prevLimit; @@ -248,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) { @@ -260,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) { @@ -275,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) { @@ -291,13 +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::setCursiveFirstExitPoint() +void GlyphIterator::clearCursiveEntryPoint() { if (direction < 0) { if (position <= nextLimit || position >= prevLimit) { @@ -309,31 +298,25 @@ void GlyphIterator::setCursiveFirstExitPoint() } } - cursiveFirstPosition = position; + glyphPositionAdjustments->clearEntryPoint(position); } -void GlyphIterator::resetCursiveLastExitPoint() +void GlyphIterator::clearCursiveExitPoint() { - 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->clearExitPoint(position); } -void GlyphIterator::setCursiveLastExitPoint(LEPoint &exitPoint) +void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint) { if (direction < 0) { if (position <= nextLimit || position >= prevLimit) { @@ -345,114 +328,129 @@ void GlyphIterator::setCursiveLastExitPoint(LEPoint &exitPoint) } } - cursiveLastPosition = position; - cursiveLastExitPoint = exitPoint; - -} - -void GlyphIterator::setCursiveBaselineAdjustment(float adjustment) -{ - cursiveBaselineAdjustment = adjustment; + glyphPositionAdjustments->setEntryPoint(position, entryPoint, baselineIsLogicalEnd()); } -void GlyphIterator::adjustCursiveLastGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust, - float xAdvanceAdjust, float yAdvanceAdjust) +void GlyphIterator::setCursiveExitPoint(LEPoint &exitPoint) { 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->setExitPoint(position, exitPoint, baselineIsLogicalEnd()); } -le_bool GlyphIterator::filterGlyph(le_uint32 index) const +void GlyphIterator::setCursiveGlyph() { - LEGlyphID glyphID = glyphs[index]; - le_int32 glyphClass = gcdNoGlyphClass; - - if (LE_GET_GLYPH(glyphID) >= 0xFFFE) { - return true; + if (direction < 0) { + if (position <= nextLimit || position >= prevLimit) { + return; + } + } else { + if (position <= prevLimit || position >= nextLimit) { + return; + } } - if (glyphClassDefinitionTable != NULL) { - glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID); - } + glyphPositionAdjustments->setCursiveGlyph(position, baselineIsLogicalEnd()); +} - switch (glyphClass) - { - case gcdNoGlyphClass: - return false; +void GlyphIterator::filterResetCache(void) { + filterCacheValid = FALSE; +} - case gcdSimpleGlyph: - return (lookupFlags & lfIgnoreBaseGlyphs) != 0; +le_bool GlyphIterator::filterGlyph(le_uint32 index) +{ + LEGlyphID glyphID = glyphStorage[index]; - case gcdLigatureGlyph: - return (lookupFlags & lfIgnoreLigatures) != 0; + if (!filterCacheValid || filterCache.id != glyphID) { + filterCache.id = glyphID; - case gcdMarkGlyph: - { - if ((lookupFlags & lfIgnoreMarks) != 0) { - return true; + 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; } -const LETag emptyTag = 0; -const LETag defaultTag = 0xFFFFFFFF; - -le_bool GlyphIterator::hasFeatureTag() const +le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup) const { - if (featureTag == defaultTag || featureTag == emptyTag) { - return true; + if (featureMask == 0) { + return TRUE; } - if (glyphTags != NULL) { - const LETag *tagList = glyphTags[position]; + LEErrorCode success = LE_NO_ERROR; + FeatureMask fm = glyphStorage.getAuxData(position, success); - for (le_int32 tag = 0; tagList[tag] != emptyTag; tag += 1) { - if (tagList[tag] == featureTag) { - return true; - } - } - } - - 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(); - return true; + if (hasFeatureTag(FALSE)) { + LEErrorCode success = LE_NO_ERROR; + + glyphGroup = (glyphStorage.getAuxData(position, success) & LE_GLYPH_GROUP_MASK); + return TRUE; } } - return false; + return FALSE; } @@ -463,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; @@ -470,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) @@ -485,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; @@ -492,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 @@ -506,7 +508,7 @@ le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const le_int32 posn; for (posn = position; posn != markPosition; posn += direction) { - if (glyphs[posn] == 0xFFFE) { + if (glyphStorage[posn] == 0xFFFE) { component += 1; } } @@ -523,7 +525,7 @@ le_bool GlyphIterator::findMark2Glyph() do { newPosition -= direction; - } while (newPosition != prevLimit && glyphs[newPosition] != 0xFFFE && filterGlyph(newPosition)); + } while (newPosition != prevLimit && glyphStorage[newPosition] != 0xFFFE && filterGlyph(newPosition)); position = newPosition;