3 * (C) Copyright IBM Corp. 1998-2008 - 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
,
19 FeatureMask theFeatureMask
, const GlyphDefinitionTableHeader
*theGlyphDefinitionTableHeader
)
20 : direction(1), position(-1), nextLimit(-1), prevLimit(-1),
21 glyphStorage(theGlyphStorage
), glyphPositionAdjustments(theGlyphPositionAdjustments
),
22 srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags
), featureMask(theFeatureMask
), glyphGroup(0),
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 featureMask
= that
.featureMask
;
56 glyphGroup
= that
.glyphGroup
;
57 glyphClassDefinitionTable
= that
.glyphClassDefinitionTable
;
58 markAttachClassDefinitionTable
= that
.markAttachClassDefinitionTable
;
61 GlyphIterator::GlyphIterator(GlyphIterator
&that
, FeatureMask newFeatureMask
)
62 : glyphStorage(that
.glyphStorage
)
64 direction
= that
.direction
;
65 position
= that
.position
;
66 nextLimit
= that
.nextLimit
;
67 prevLimit
= that
.prevLimit
;
69 glyphPositionAdjustments
= that
.glyphPositionAdjustments
;
70 srcIndex
= that
.srcIndex
;
71 destIndex
= that
.destIndex
;
72 lookupFlags
= that
.lookupFlags
;
73 featureMask
= newFeatureMask
;
75 glyphClassDefinitionTable
= that
.glyphClassDefinitionTable
;
76 markAttachClassDefinitionTable
= that
.markAttachClassDefinitionTable
;
79 GlyphIterator::GlyphIterator(GlyphIterator
&that
, le_uint16 newLookupFlags
)
80 : glyphStorage(that
.glyphStorage
)
82 direction
= that
.direction
;
83 position
= that
.position
;
84 nextLimit
= that
.nextLimit
;
85 prevLimit
= that
.prevLimit
;
87 glyphPositionAdjustments
= that
.glyphPositionAdjustments
;
88 srcIndex
= that
.srcIndex
;
89 destIndex
= that
.destIndex
;
90 lookupFlags
= newLookupFlags
;
91 featureMask
= that
.featureMask
;
92 glyphGroup
= that
.glyphGroup
;
93 glyphClassDefinitionTable
= that
.glyphClassDefinitionTable
;
94 markAttachClassDefinitionTable
= that
.markAttachClassDefinitionTable
;
97 GlyphIterator::~GlyphIterator()
99 // nothing to do, right?
102 void GlyphIterator::reset(le_uint16 newLookupFlags
, FeatureMask newFeatureMask
)
104 position
= prevLimit
;
105 featureMask
= newFeatureMask
;
107 lookupFlags
= newLookupFlags
;
110 LEGlyphID
*GlyphIterator::insertGlyphs(le_int32 count
, LEErrorCode
& success
)
112 return glyphStorage
.insertGlyphs(position
, count
, success
);
115 le_int32
GlyphIterator::applyInsertions()
117 le_int32 newGlyphCount
= glyphStorage
.applyInsertions();
120 prevLimit
= newGlyphCount
;
122 nextLimit
= newGlyphCount
;
125 return newGlyphCount
;
128 le_int32
GlyphIterator::getCurrStreamPosition() const
133 le_bool
GlyphIterator::isRightToLeft() const
135 return direction
< 0;
138 le_bool
GlyphIterator::ignoresMarks() const
140 return (lookupFlags
& lfIgnoreMarks
) != 0;
143 le_bool
GlyphIterator::baselineIsLogicalEnd() const
145 return (lookupFlags
& lfBaselineIsLogicalEnd
) != 0;
148 LEGlyphID
GlyphIterator::getCurrGlyphID() const
151 if (position
<= nextLimit
|| position
>= prevLimit
) {
155 if (position
<= prevLimit
|| position
>= nextLimit
) {
160 return glyphStorage
[position
];
163 void GlyphIterator::getCursiveEntryPoint(LEPoint
&entryPoint
) const
166 if (position
<= nextLimit
|| position
>= prevLimit
) {
170 if (position
<= prevLimit
|| position
>= nextLimit
) {
175 glyphPositionAdjustments
->getEntryPoint(position
, entryPoint
);
178 void GlyphIterator::getCursiveExitPoint(LEPoint
&exitPoint
) const
181 if (position
<= nextLimit
|| position
>= prevLimit
) {
185 if (position
<= prevLimit
|| position
>= nextLimit
) {
190 glyphPositionAdjustments
->getExitPoint(position
, exitPoint
);
193 void GlyphIterator::setCurrGlyphID(TTGlyphID glyphID
)
195 LEGlyphID glyph
= glyphStorage
[position
];
197 glyphStorage
[position
] = LE_SET_GLYPH(glyph
, glyphID
);
200 void GlyphIterator::setCurrStreamPosition(le_int32 newPosition
)
203 if (newPosition
>= prevLimit
) {
204 position
= prevLimit
;
208 if (newPosition
<= nextLimit
) {
209 position
= nextLimit
;
213 if (newPosition
<= prevLimit
) {
214 position
= prevLimit
;
218 if (newPosition
>= nextLimit
) {
219 position
= nextLimit
;
224 position
= newPosition
- direction
;
228 void GlyphIterator::setCurrGlyphBaseOffset(le_int32 baseOffset
)
231 if (position
<= nextLimit
|| position
>= prevLimit
) {
235 if (position
<= prevLimit
|| position
>= nextLimit
) {
240 glyphPositionAdjustments
->setBaseOffset(position
, baseOffset
);
243 void GlyphIterator::adjustCurrGlyphPositionAdjustment(float xPlacementAdjust
, float yPlacementAdjust
,
244 float xAdvanceAdjust
, float yAdvanceAdjust
)
247 if (position
<= nextLimit
|| position
>= prevLimit
) {
251 if (position
<= prevLimit
|| position
>= nextLimit
) {
256 glyphPositionAdjustments
->adjustXPlacement(position
, xPlacementAdjust
);
257 glyphPositionAdjustments
->adjustYPlacement(position
, yPlacementAdjust
);
258 glyphPositionAdjustments
->adjustXAdvance(position
, xAdvanceAdjust
);
259 glyphPositionAdjustments
->adjustYAdvance(position
, yAdvanceAdjust
);
262 void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust
, float yPlacementAdjust
,
263 float xAdvanceAdjust
, float yAdvanceAdjust
)
266 if (position
<= nextLimit
|| position
>= prevLimit
) {
270 if (position
<= prevLimit
|| position
>= nextLimit
) {
275 glyphPositionAdjustments
->setXPlacement(position
, xPlacementAdjust
);
276 glyphPositionAdjustments
->setYPlacement(position
, yPlacementAdjust
);
277 glyphPositionAdjustments
->setXAdvance(position
, xAdvanceAdjust
);
278 glyphPositionAdjustments
->setYAdvance(position
, yAdvanceAdjust
);
281 void GlyphIterator::clearCursiveEntryPoint()
284 if (position
<= nextLimit
|| position
>= prevLimit
) {
288 if (position
<= prevLimit
|| position
>= nextLimit
) {
293 glyphPositionAdjustments
->clearEntryPoint(position
);
296 void GlyphIterator::clearCursiveExitPoint()
299 if (position
<= nextLimit
|| position
>= prevLimit
) {
303 if (position
<= prevLimit
|| position
>= nextLimit
) {
308 glyphPositionAdjustments
->clearExitPoint(position
);
311 void GlyphIterator::setCursiveEntryPoint(LEPoint
&entryPoint
)
314 if (position
<= nextLimit
|| position
>= prevLimit
) {
318 if (position
<= prevLimit
|| position
>= nextLimit
) {
323 glyphPositionAdjustments
->setEntryPoint(position
, entryPoint
, baselineIsLogicalEnd());
326 void GlyphIterator::setCursiveExitPoint(LEPoint
&exitPoint
)
329 if (position
<= nextLimit
|| position
>= prevLimit
) {
333 if (position
<= prevLimit
|| position
>= nextLimit
) {
338 glyphPositionAdjustments
->setExitPoint(position
, exitPoint
, baselineIsLogicalEnd());
341 void GlyphIterator::setCursiveGlyph()
344 if (position
<= nextLimit
|| position
>= prevLimit
) {
348 if (position
<= prevLimit
|| position
>= nextLimit
) {
353 glyphPositionAdjustments
->setCursiveGlyph(position
, baselineIsLogicalEnd());
356 le_bool
GlyphIterator::filterGlyph(le_uint32 index
) const
358 LEGlyphID glyphID
= glyphStorage
[index
];
359 le_int32 glyphClass
= gcdNoGlyphClass
;
361 if (LE_GET_GLYPH(glyphID
) >= 0xFFFE) {
365 if (glyphClassDefinitionTable
!= NULL
) {
366 glyphClass
= glyphClassDefinitionTable
->getGlyphClass(glyphID
);
371 case gcdNoGlyphClass
:
375 return (lookupFlags
& lfIgnoreBaseGlyphs
) != 0;
377 case gcdLigatureGlyph
:
378 return (lookupFlags
& lfIgnoreLigatures
) != 0;
382 if ((lookupFlags
& lfIgnoreMarks
) != 0) {
386 le_uint16 markAttachType
= (lookupFlags
& lfMarkAttachTypeMask
) >> lfMarkAttachTypeShift
;
388 if ((markAttachType
!= 0) && (markAttachClassDefinitionTable
!= NULL
)) {
389 return markAttachClassDefinitionTable
->getGlyphClass(glyphID
) != markAttachType
;
395 case gcdComponentGlyph
:
396 return (lookupFlags
& lfIgnoreBaseGlyphs
) != 0;
403 le_bool
GlyphIterator::hasFeatureTag(le_bool matchGroup
) const
405 if (featureMask
== 0) {
409 LEErrorCode success
= LE_NO_ERROR
;
410 FeatureMask fm
= glyphStorage
.getAuxData(position
, success
);
412 return ((fm
& featureMask
) == featureMask
) && (!matchGroup
|| (le_int32
)(fm
& LE_GLYPH_GROUP_MASK
) == glyphGroup
);
415 le_bool
GlyphIterator::findFeatureTag()
419 while (nextInternal()) {
420 if (hasFeatureTag(FALSE
)) {
421 LEErrorCode success
= LE_NO_ERROR
;
423 glyphGroup
= (glyphStorage
.getAuxData(position
, success
) & LE_GLYPH_GROUP_MASK
);
432 le_bool
GlyphIterator::nextInternal(le_uint32 delta
)
434 le_int32 newPosition
= position
;
436 while (newPosition
!= nextLimit
&& delta
> 0) {
438 newPosition
+= direction
;
439 } while (newPosition
!= nextLimit
&& filterGlyph(newPosition
));
444 position
= newPosition
;
446 return position
!= nextLimit
;
449 le_bool
GlyphIterator::next(le_uint32 delta
)
451 return nextInternal(delta
) && hasFeatureTag(TRUE
);
454 le_bool
GlyphIterator::prevInternal(le_uint32 delta
)
456 le_int32 newPosition
= position
;
458 while (newPosition
!= prevLimit
&& delta
> 0) {
460 newPosition
-= direction
;
461 } while (newPosition
!= prevLimit
&& filterGlyph(newPosition
));
466 position
= newPosition
;
468 return position
!= prevLimit
;
471 le_bool
GlyphIterator::prev(le_uint32 delta
)
473 return prevInternal(delta
) && hasFeatureTag(TRUE
);
476 le_int32
GlyphIterator::getMarkComponent(le_int32 markPosition
) const
478 le_int32 component
= 0;
481 for (posn
= position
; posn
!= markPosition
; posn
+= direction
) {
482 if (glyphStorage
[posn
] == 0xFFFE) {
490 // This is basically prevInternal except that it
491 // doesn't take a delta argument, and it doesn't
492 // filter out 0xFFFE glyphs.
493 le_bool
GlyphIterator::findMark2Glyph()
495 le_int32 newPosition
= position
;
498 newPosition
-= direction
;
499 } while (newPosition
!= prevLimit
&& glyphStorage
[newPosition
] != 0xFFFE && filterGlyph(newPosition
));
501 position
= newPosition
;
503 return position
!= prevLimit
;