]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/layout/GlyphIterator.cpp
ICU-59180.0.1.tar.gz
[apple/icu.git] / icuSources / layout / GlyphIterator.cpp
index b612e58e6a67a23dbc34af1b6e23f51c168a1c4c..72d2dd13156d8273269010d93575e30d76de63f2 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * %W% %E%
  *
- * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
 #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<GlyphDefinitionTableHeader> &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;