fontservices/textshaperplugin/IcuSource/layout/GlyphIterator.cpp
changeset 0 1fb32624e06b
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     1 /*
       
     2  *
       
     3  * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
       
     4  *
       
     5  */
       
     6 
       
     7 #include "LETypes.h"
       
     8 #include "OpenTypeTables.h"
       
     9 #include "GlyphDefinitionTables.h"
       
    10 #include "GlyphPositionAdjustments.h"
       
    11 #include "GlyphIterator.h"
       
    12 #include "LEGlyphStorage.h"
       
    13 #include "Lookups.h"
       
    14 #include "LESwaps.h"
       
    15 
       
    16 U_NAMESPACE_BEGIN
       
    17 
       
    18 GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag,
       
    19     const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
       
    20   : direction(1), position(-1), nextLimit(-1), prevLimit(-1),
       
    21     glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
       
    22     srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureTag(theFeatureTag),
       
    23     glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL)
       
    24 
       
    25 {
       
    26     le_int32 glyphCount = glyphStorage.getGlyphCount();
       
    27 
       
    28     if (theGlyphDefinitionTableHeader != NULL) {
       
    29         glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable();
       
    30         markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable();
       
    31     }
       
    32 
       
    33     nextLimit = glyphCount;
       
    34 
       
    35     if (rightToLeft) {
       
    36         direction = -1;
       
    37         position = glyphCount;
       
    38         nextLimit = -1;
       
    39         prevLimit = glyphCount;
       
    40     }
       
    41 }
       
    42 
       
    43 GlyphIterator::GlyphIterator(GlyphIterator &that)
       
    44   : glyphStorage(that.glyphStorage)
       
    45 {
       
    46     direction    = that.direction;
       
    47     position     = that.position;
       
    48     nextLimit    = that.nextLimit;
       
    49     prevLimit    = that.prevLimit;
       
    50 
       
    51     glyphPositionAdjustments = that.glyphPositionAdjustments;
       
    52     srcIndex = that.srcIndex;
       
    53     destIndex = that.destIndex;
       
    54     lookupFlags = that.lookupFlags;
       
    55     featureTag = that.featureTag;
       
    56     glyphClassDefinitionTable = that.glyphClassDefinitionTable;
       
    57     markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
       
    58 }
       
    59 
       
    60 GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag)
       
    61   : glyphStorage(that.glyphStorage)
       
    62 {
       
    63     direction    = that.direction;
       
    64     position     = that.position;
       
    65     nextLimit    = that.nextLimit;
       
    66     prevLimit    = that.prevLimit;
       
    67 
       
    68     glyphPositionAdjustments = that.glyphPositionAdjustments;
       
    69     srcIndex = that.srcIndex;
       
    70     destIndex = that.destIndex;
       
    71     lookupFlags = that.lookupFlags;
       
    72     featureTag = newFeatureTag;
       
    73     glyphClassDefinitionTable = that.glyphClassDefinitionTable;
       
    74     markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
       
    75 }
       
    76 
       
    77 GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags)
       
    78   : glyphStorage(that.glyphStorage)
       
    79 {
       
    80     direction    = that.direction;
       
    81     position     = that.position;
       
    82     nextLimit    = that.nextLimit;
       
    83     prevLimit    = that.prevLimit;
       
    84 
       
    85     glyphPositionAdjustments = that.glyphPositionAdjustments;
       
    86     srcIndex = that.srcIndex;
       
    87     destIndex = that.destIndex;
       
    88     lookupFlags = newLookupFlags;
       
    89     featureTag = that.featureTag;
       
    90     glyphClassDefinitionTable = that.glyphClassDefinitionTable;
       
    91     markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
       
    92 }
       
    93 
       
    94 GlyphIterator::~GlyphIterator()
       
    95 {
       
    96     // nothing to do, right?
       
    97 }
       
    98 
       
    99 void GlyphIterator::reset(le_uint16 newLookupFlags, LETag newFeatureTag)
       
   100 {
       
   101     position    = prevLimit;
       
   102     featureTag  = newFeatureTag;
       
   103     lookupFlags = newLookupFlags;
       
   104 }
       
   105 
       
   106 LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count, LEErrorCode& success)
       
   107 {
       
   108     return glyphStorage.insertGlyphs(position, count, success);
       
   109 }
       
   110 
       
   111 le_int32 GlyphIterator::applyInsertions()
       
   112 {
       
   113     le_int32 newGlyphCount = glyphStorage.applyInsertions();
       
   114 
       
   115     if (direction < 0) {
       
   116         prevLimit = newGlyphCount;
       
   117     } else {
       
   118         nextLimit = newGlyphCount;
       
   119     }
       
   120 
       
   121     return newGlyphCount;
       
   122 }
       
   123 
       
   124 le_int32 GlyphIterator::getCurrStreamPosition() const
       
   125 {
       
   126     return position;
       
   127 }
       
   128 
       
   129 le_bool GlyphIterator::isRightToLeft() const
       
   130 {
       
   131     return direction < 0;
       
   132 }
       
   133 
       
   134 le_bool GlyphIterator::ignoresMarks() const
       
   135 {
       
   136     return (lookupFlags & lfIgnoreMarks) != 0;
       
   137 }
       
   138 
       
   139 le_bool GlyphIterator::baselineIsLogicalEnd() const
       
   140 {
       
   141     return (lookupFlags & lfBaselineIsLogicalEnd) != 0;
       
   142 }
       
   143 
       
   144 LEGlyphID GlyphIterator::getCurrGlyphID() const
       
   145 {
       
   146     if (direction < 0) {
       
   147         if (position <= nextLimit || position >= prevLimit) {
       
   148             return 0xFFFF;
       
   149         }
       
   150     } else {
       
   151         if (position <= prevLimit || position >= nextLimit) {
       
   152             return 0xFFFF;
       
   153         }
       
   154     }
       
   155 
       
   156     return glyphStorage[position];
       
   157 }
       
   158 
       
   159 void GlyphIterator::getCursiveEntryPoint(LEPoint &entryPoint) const
       
   160 {
       
   161     if (direction < 0) {
       
   162         if (position <= nextLimit || position >= prevLimit) {
       
   163             return;
       
   164         }
       
   165     } else {
       
   166         if (position <= prevLimit || position >= nextLimit) {
       
   167             return;
       
   168         }
       
   169     }
       
   170 
       
   171     glyphPositionAdjustments->getEntryPoint(position, entryPoint);
       
   172 }
       
   173 
       
   174 void GlyphIterator::getCursiveExitPoint(LEPoint &exitPoint) const
       
   175 {
       
   176     if (direction < 0) {
       
   177         if (position <= nextLimit || position >= prevLimit) {
       
   178             return;
       
   179         }
       
   180     } else {
       
   181         if (position <= prevLimit || position >= nextLimit) {
       
   182             return;
       
   183         }
       
   184     }
       
   185 
       
   186     glyphPositionAdjustments->getExitPoint(position, exitPoint);
       
   187 }
       
   188 
       
   189 void GlyphIterator::setCurrGlyphID(TTGlyphID glyphID)
       
   190 {
       
   191     LEGlyphID glyph = glyphStorage[position];
       
   192 
       
   193     glyphStorage[position] = LE_SET_GLYPH(glyph, glyphID);
       
   194 }
       
   195 
       
   196 void GlyphIterator::setCurrStreamPosition(le_int32 newPosition)
       
   197 {
       
   198     if (direction < 0) {
       
   199         if (newPosition >= prevLimit) {
       
   200             position = prevLimit;
       
   201             return;
       
   202         }
       
   203 
       
   204         if (newPosition <= nextLimit) {
       
   205             position = nextLimit;
       
   206             return;
       
   207         }
       
   208     } else {
       
   209         if (newPosition <= prevLimit) {
       
   210             position = prevLimit;
       
   211             return;
       
   212         }
       
   213 
       
   214         if (newPosition >= nextLimit) {
       
   215             position = nextLimit;
       
   216             return;
       
   217         }
       
   218     }
       
   219 
       
   220     position = newPosition - direction;
       
   221     next();
       
   222 }
       
   223 
       
   224 void GlyphIterator::setCurrGlyphBaseOffset(le_int32 baseOffset)
       
   225 {
       
   226     if (direction < 0) {
       
   227         if (position <= nextLimit || position >= prevLimit) {
       
   228             return;
       
   229         }
       
   230     } else {
       
   231         if (position <= prevLimit || position >= nextLimit) {
       
   232             return;
       
   233         }
       
   234     }
       
   235 
       
   236     glyphPositionAdjustments->setBaseOffset(position, baseOffset);
       
   237 }
       
   238 
       
   239 void GlyphIterator::adjustCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
       
   240                                                       float xAdvanceAdjust, float yAdvanceAdjust)
       
   241 {
       
   242     if (direction < 0) {
       
   243         if (position <= nextLimit || position >= prevLimit) {
       
   244             return;
       
   245         }
       
   246     } else {
       
   247         if (position <= prevLimit || position >= nextLimit) {
       
   248             return;
       
   249         }
       
   250     }
       
   251 
       
   252     glyphPositionAdjustments->adjustXPlacement(position, xPlacementAdjust);
       
   253     glyphPositionAdjustments->adjustYPlacement(position, yPlacementAdjust);
       
   254     glyphPositionAdjustments->adjustXAdvance(position, xAdvanceAdjust);
       
   255     glyphPositionAdjustments->adjustYAdvance(position, yAdvanceAdjust);
       
   256 }
       
   257 
       
   258 void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
       
   259                                                       float xAdvanceAdjust, float yAdvanceAdjust)
       
   260 {
       
   261     if (direction < 0) {
       
   262         if (position <= nextLimit || position >= prevLimit) {
       
   263             return;
       
   264         }
       
   265     } else {
       
   266         if (position <= prevLimit || position >= nextLimit) {
       
   267             return;
       
   268         }
       
   269     }
       
   270 
       
   271     glyphPositionAdjustments->setXPlacement(position, xPlacementAdjust);
       
   272     glyphPositionAdjustments->setYPlacement(position, yPlacementAdjust);
       
   273     glyphPositionAdjustments->setXAdvance(position, xAdvanceAdjust);
       
   274     glyphPositionAdjustments->setYAdvance(position, yAdvanceAdjust);
       
   275 }
       
   276 
       
   277 void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint)
       
   278 {
       
   279     if (direction < 0) {
       
   280         if (position <= nextLimit || position >= prevLimit) {
       
   281             return;
       
   282         }
       
   283     } else {
       
   284         if (position <= prevLimit || position >= nextLimit) {
       
   285             return;
       
   286         }
       
   287     }
       
   288 
       
   289     glyphPositionAdjustments->setEntryPoint(position, entryPoint, baselineIsLogicalEnd());
       
   290 }
       
   291 
       
   292 void GlyphIterator::setCursiveExitPoint(LEPoint &exitPoint)
       
   293 {
       
   294     if (direction < 0) {
       
   295         if (position <= nextLimit || position >= prevLimit) {
       
   296             return;
       
   297         }
       
   298     } else {
       
   299         if (position <= prevLimit || position >= nextLimit) {
       
   300             return;
       
   301         }
       
   302     }
       
   303 
       
   304     glyphPositionAdjustments->setExitPoint(position, exitPoint, baselineIsLogicalEnd());
       
   305 }
       
   306 
       
   307 void GlyphIterator::setCursiveGlyph()
       
   308 {
       
   309     if (direction < 0) {
       
   310         if (position <= nextLimit || position >= prevLimit) {
       
   311             return;
       
   312         }
       
   313     } else {
       
   314         if (position <= prevLimit || position >= nextLimit) {
       
   315             return;
       
   316         }
       
   317     }
       
   318 
       
   319     glyphPositionAdjustments->setCursiveGlyph(position, baselineIsLogicalEnd());
       
   320 }
       
   321 
       
   322 le_bool GlyphIterator::filterGlyph(le_uint32 index) const
       
   323 {
       
   324     LEGlyphID glyphID = glyphStorage[index];
       
   325     le_int32 glyphClass = gcdNoGlyphClass;
       
   326 
       
   327     if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
       
   328         return TRUE;
       
   329     }
       
   330 
       
   331     if (glyphClassDefinitionTable != NULL) {
       
   332         glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID);
       
   333     }
       
   334 
       
   335     switch (glyphClass)
       
   336     {
       
   337     case gcdNoGlyphClass:
       
   338         return FALSE;
       
   339 
       
   340     case gcdSimpleGlyph:
       
   341         return (lookupFlags & lfIgnoreBaseGlyphs) != 0;
       
   342 
       
   343     case gcdLigatureGlyph:
       
   344         return (lookupFlags & lfIgnoreLigatures) != 0;
       
   345 
       
   346     case gcdMarkGlyph:
       
   347     {
       
   348         if ((lookupFlags & lfIgnoreMarks) != 0) {
       
   349             return TRUE;
       
   350         }
       
   351 
       
   352         le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
       
   353 
       
   354         if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) {
       
   355             return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType;
       
   356         }
       
   357 
       
   358         return FALSE;
       
   359     }
       
   360 
       
   361     case gcdComponentGlyph:
       
   362         return (lookupFlags & lfIgnoreBaseGlyphs) != 0;
       
   363 
       
   364     default:
       
   365         return FALSE;
       
   366     }
       
   367 }
       
   368 
       
   369 static const LETag emptyTag = 0;
       
   370 static const LETag defaultTag = 0xFFFFFFFF;
       
   371 
       
   372 le_bool GlyphIterator::hasFeatureTag() const
       
   373 {
       
   374     if (featureTag == defaultTag || featureTag == emptyTag) {
       
   375         return TRUE;
       
   376     }
       
   377 
       
   378     LEErrorCode success = LE_NO_ERROR;
       
   379     const LETag *tagList = (const LETag *) glyphStorage.getAuxData(position, success);
       
   380 
       
   381     if (tagList != NULL) {
       
   382         for (le_int32 tag = 0; tagList[tag] != emptyTag; tag += 1) {
       
   383             if (tagList[tag] == featureTag) {
       
   384                 return TRUE;
       
   385             }
       
   386         }
       
   387     }
       
   388 
       
   389     return FALSE;
       
   390 }
       
   391 
       
   392 le_bool GlyphIterator::findFeatureTag()
       
   393 {
       
   394     while (nextInternal()) {
       
   395         if (hasFeatureTag()) {
       
   396             prevInternal();
       
   397             return TRUE;
       
   398         }
       
   399     }
       
   400 
       
   401     return FALSE;
       
   402 }
       
   403 
       
   404 
       
   405 le_bool GlyphIterator::nextInternal(le_uint32 delta)
       
   406 {
       
   407     le_int32 newPosition = position;
       
   408 
       
   409     while (newPosition != nextLimit && delta > 0) {
       
   410         do {
       
   411             newPosition += direction;
       
   412         } while (newPosition != nextLimit && filterGlyph(newPosition));
       
   413 
       
   414         delta -= 1;
       
   415     }
       
   416 
       
   417     position = newPosition;
       
   418 
       
   419     return position != nextLimit;
       
   420 }
       
   421 
       
   422 le_bool GlyphIterator::next(le_uint32 delta)
       
   423 {
       
   424     return nextInternal(delta) && hasFeatureTag();
       
   425 }
       
   426 
       
   427 le_bool GlyphIterator::prevInternal(le_uint32 delta)
       
   428 {
       
   429     le_int32 newPosition = position;
       
   430 
       
   431     while (newPosition != prevLimit && delta > 0) {
       
   432         do {
       
   433             newPosition -= direction;
       
   434         } while (newPosition != prevLimit && filterGlyph(newPosition));
       
   435 
       
   436         delta -= 1;
       
   437     }
       
   438 
       
   439     position = newPosition;
       
   440 
       
   441     return position != prevLimit;
       
   442 }
       
   443 
       
   444 le_bool GlyphIterator::prev(le_uint32 delta)
       
   445 {
       
   446     return prevInternal(delta) && hasFeatureTag();
       
   447 }
       
   448 
       
   449 le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const
       
   450 {
       
   451     le_int32 component = 0;
       
   452     le_int32 posn;
       
   453 
       
   454     for (posn = position; posn != markPosition; posn += direction) {
       
   455         if (glyphStorage[posn] == 0xFFFE) {
       
   456             component += 1;
       
   457         }
       
   458     }
       
   459 
       
   460     return component;
       
   461 }
       
   462 
       
   463 // This is basically prevInternal except that it
       
   464 // doesn't take a delta argument, and it doesn't
       
   465 // filter out 0xFFFE glyphs.
       
   466 le_bool GlyphIterator::findMark2Glyph()
       
   467 {
       
   468     le_int32 newPosition = position;
       
   469 
       
   470     do {
       
   471         newPosition -= direction;
       
   472     } while (newPosition != prevLimit && glyphStorage[newPosition] != 0xFFFE && filterGlyph(newPosition));
       
   473 
       
   474     position = newPosition;
       
   475 
       
   476     return position != prevLimit;
       
   477 }
       
   478 
       
   479 U_NAMESPACE_END