]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/layout/GlyphIterator.cpp
ICU-511.31.tar.gz
[apple/icu.git] / icuSources / layout / GlyphIterator.cpp
index 20bcc8600e405af1d29c6d38b1cd7e1027f1df94..231743407c8f3907fe7ea1b1483085397b458e42 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
  *
  */
 
 
 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 GlyphDefinitionTableHeader *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),
+    srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
     glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL)
 
 {
@@ -49,19 +48,17 @@ 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;
 }
 
-GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag)
+GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask)
   : glyphStorage(that.glyphStorage)
 {
     direction    = that.direction;
@@ -69,14 +66,12 @@ 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;
 }
@@ -89,15 +84,12 @@ 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;
 }
@@ -107,16 +99,17 @@ 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;
 }
 
-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 +145,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 +160,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 +172,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 +199,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 +225,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 +237,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 +253,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 +272,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 +290,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 +305,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,33 +335,22 @@ 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
@@ -469,34 +400,27 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const
     }
 }
 
-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;
         }
     }
@@ -524,7 +448,7 @@ le_bool GlyphIterator::nextInternal(le_uint32 delta)
 
 le_bool GlyphIterator::next(le_uint32 delta)
 {
-    return nextInternal(delta) && hasFeatureTag();
+    return nextInternal(delta) && hasFeatureTag(TRUE);
 }
 
 le_bool GlyphIterator::prevInternal(le_uint32 delta)
@@ -546,7 +470,7 @@ le_bool GlyphIterator::prevInternal(le_uint32 delta)
 
 le_bool GlyphIterator::prev(le_uint32 delta)
 {
-    return prevInternal(delta) && hasFeatureTag();
+    return prevInternal(delta) && hasFeatureTag(TRUE);
 }
 
 le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const