Update contrib.
3 * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
8 #include "OpenTypeTables.h"
9 #include "GlyphDefinitionTables.h"
10 #include "GlyphPositionAdjustments.h"
11 #include "GlyphIterator.h"
12 #include "LEGlyphStorage.h"
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)
26 le_int32 glyphCount = glyphStorage.getGlyphCount();
28 if (theGlyphDefinitionTableHeader != NULL) {
29 glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable();
30 markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable();
33 nextLimit = glyphCount;
37 position = glyphCount;
39 prevLimit = glyphCount;
43 GlyphIterator::GlyphIterator(GlyphIterator &that)
44 : glyphStorage(that.glyphStorage)
46 direction = that.direction;
47 position = that.position;
48 nextLimit = that.nextLimit;
49 prevLimit = that.prevLimit;
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;
60 GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag)
61 : glyphStorage(that.glyphStorage)
63 direction = that.direction;
64 position = that.position;
65 nextLimit = that.nextLimit;
66 prevLimit = that.prevLimit;
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;
77 GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags)
78 : glyphStorage(that.glyphStorage)
80 direction = that.direction;
81 position = that.position;
82 nextLimit = that.nextLimit;
83 prevLimit = that.prevLimit;
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;
94 GlyphIterator::~GlyphIterator()
96 // nothing to do, right?
99 void GlyphIterator::reset(le_uint16 newLookupFlags, LETag newFeatureTag)
101 position = prevLimit;
102 featureTag = newFeatureTag;
103 lookupFlags = newLookupFlags;
106 LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count, LEErrorCode& success)
108 return glyphStorage.insertGlyphs(position, count, success);
111 le_int32 GlyphIterator::applyInsertions()
113 le_int32 newGlyphCount = glyphStorage.applyInsertions();
116 prevLimit = newGlyphCount;
118 nextLimit = newGlyphCount;
121 return newGlyphCount;
124 le_int32 GlyphIterator::getCurrStreamPosition() const
129 le_bool GlyphIterator::isRightToLeft() const
131 return direction < 0;
134 le_bool GlyphIterator::ignoresMarks() const
136 return (lookupFlags & lfIgnoreMarks) != 0;
139 le_bool GlyphIterator::baselineIsLogicalEnd() const
141 return (lookupFlags & lfBaselineIsLogicalEnd) != 0;
144 LEGlyphID GlyphIterator::getCurrGlyphID() const
147 if (position <= nextLimit || position >= prevLimit) {
151 if (position <= prevLimit || position >= nextLimit) {
156 return glyphStorage[position];
159 void GlyphIterator::getCursiveEntryPoint(LEPoint &entryPoint) const
162 if (position <= nextLimit || position >= prevLimit) {
166 if (position <= prevLimit || position >= nextLimit) {
171 glyphPositionAdjustments->getEntryPoint(position, entryPoint);
174 void GlyphIterator::getCursiveExitPoint(LEPoint &exitPoint) const
177 if (position <= nextLimit || position >= prevLimit) {
181 if (position <= prevLimit || position >= nextLimit) {
186 glyphPositionAdjustments->getExitPoint(position, exitPoint);
189 void GlyphIterator::setCurrGlyphID(TTGlyphID glyphID)
191 LEGlyphID glyph = glyphStorage[position];
193 glyphStorage[position] = LE_SET_GLYPH(glyph, glyphID);
196 void GlyphIterator::setCurrStreamPosition(le_int32 newPosition)
199 if (newPosition >= prevLimit) {
200 position = prevLimit;
204 if (newPosition <= nextLimit) {
205 position = nextLimit;
209 if (newPosition <= prevLimit) {
210 position = prevLimit;
214 if (newPosition >= nextLimit) {
215 position = nextLimit;
220 position = newPosition - direction;
224 void GlyphIterator::setCurrGlyphBaseOffset(le_int32 baseOffset)
227 if (position <= nextLimit || position >= prevLimit) {
231 if (position <= prevLimit || position >= nextLimit) {
236 glyphPositionAdjustments->setBaseOffset(position, baseOffset);
239 void GlyphIterator::adjustCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
240 float xAdvanceAdjust, float yAdvanceAdjust)
243 if (position <= nextLimit || position >= prevLimit) {
247 if (position <= prevLimit || position >= nextLimit) {
252 glyphPositionAdjustments->adjustXPlacement(position, xPlacementAdjust);
253 glyphPositionAdjustments->adjustYPlacement(position, yPlacementAdjust);
254 glyphPositionAdjustments->adjustXAdvance(position, xAdvanceAdjust);
255 glyphPositionAdjustments->adjustYAdvance(position, yAdvanceAdjust);
258 void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
259 float xAdvanceAdjust, float yAdvanceAdjust)
262 if (position <= nextLimit || position >= prevLimit) {
266 if (position <= prevLimit || position >= nextLimit) {
271 glyphPositionAdjustments->setXPlacement(position, xPlacementAdjust);
272 glyphPositionAdjustments->setYPlacement(position, yPlacementAdjust);
273 glyphPositionAdjustments->setXAdvance(position, xAdvanceAdjust);
274 glyphPositionAdjustments->setYAdvance(position, yAdvanceAdjust);
277 void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint)
280 if (position <= nextLimit || position >= prevLimit) {
284 if (position <= prevLimit || position >= nextLimit) {
289 glyphPositionAdjustments->setEntryPoint(position, entryPoint, baselineIsLogicalEnd());
292 void GlyphIterator::setCursiveExitPoint(LEPoint &exitPoint)
295 if (position <= nextLimit || position >= prevLimit) {
299 if (position <= prevLimit || position >= nextLimit) {
304 glyphPositionAdjustments->setExitPoint(position, exitPoint, baselineIsLogicalEnd());
307 void GlyphIterator::setCursiveGlyph()
310 if (position <= nextLimit || position >= prevLimit) {
314 if (position <= prevLimit || position >= nextLimit) {
319 glyphPositionAdjustments->setCursiveGlyph(position, baselineIsLogicalEnd());
322 le_bool GlyphIterator::filterGlyph(le_uint32 index) const
324 LEGlyphID glyphID = glyphStorage[index];
325 le_int32 glyphClass = gcdNoGlyphClass;
327 if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
331 if (glyphClassDefinitionTable != NULL) {
332 glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID);
337 case gcdNoGlyphClass:
341 return (lookupFlags & lfIgnoreBaseGlyphs) != 0;
343 case gcdLigatureGlyph:
344 return (lookupFlags & lfIgnoreLigatures) != 0;
348 if ((lookupFlags & lfIgnoreMarks) != 0) {
352 le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
354 if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) {
355 return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType;
361 case gcdComponentGlyph:
362 return (lookupFlags & lfIgnoreBaseGlyphs) != 0;
369 static const LETag emptyTag = 0;
370 static const LETag defaultTag = 0xFFFFFFFF;
372 le_bool GlyphIterator::hasFeatureTag() const
374 if (featureTag == defaultTag || featureTag == emptyTag) {
378 LEErrorCode success = LE_NO_ERROR;
379 const LETag *tagList = (const LETag *) glyphStorage.getAuxData(position, success);
381 if (tagList != NULL) {
382 for (le_int32 tag = 0; tagList[tag] != emptyTag; tag += 1) {
383 if (tagList[tag] == featureTag) {
392 le_bool GlyphIterator::findFeatureTag()
394 while (nextInternal()) {
395 if (hasFeatureTag()) {
405 le_bool GlyphIterator::nextInternal(le_uint32 delta)
407 le_int32 newPosition = position;
409 while (newPosition != nextLimit && delta > 0) {
411 newPosition += direction;
412 } while (newPosition != nextLimit && filterGlyph(newPosition));
417 position = newPosition;
419 return position != nextLimit;
422 le_bool GlyphIterator::next(le_uint32 delta)
424 return nextInternal(delta) && hasFeatureTag();
427 le_bool GlyphIterator::prevInternal(le_uint32 delta)
429 le_int32 newPosition = position;
431 while (newPosition != prevLimit && delta > 0) {
433 newPosition -= direction;
434 } while (newPosition != prevLimit && filterGlyph(newPosition));
439 position = newPosition;
441 return position != prevLimit;
444 le_bool GlyphIterator::prev(le_uint32 delta)
446 return prevInternal(delta) && hasFeatureTag();
449 le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const
451 le_int32 component = 0;
454 for (posn = position; posn != markPosition; posn += direction) {
455 if (glyphStorage[posn] == 0xFFFE) {
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()
468 le_int32 newPosition = position;
471 newPosition -= direction;
472 } while (newPosition != prevLimit && glyphStorage[newPosition] != 0xFFFE && filterGlyph(newPosition));
474 position = newPosition;
476 return position != prevLimit;