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
,
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
),
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 glyphClassDefinitionTable
= that
.glyphClassDefinitionTable
;
57 markAttachClassDefinitionTable
= that
.markAttachClassDefinitionTable
;
60 GlyphIterator::GlyphIterator(GlyphIterator
&that
, FeatureMask newFeatureMask
)
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 featureMask
= newFeatureMask
;
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 featureMask
= that
.featureMask
;
90 glyphClassDefinitionTable
= that
.glyphClassDefinitionTable
;
91 markAttachClassDefinitionTable
= that
.markAttachClassDefinitionTable
;
94 GlyphIterator::~GlyphIterator()
96 // nothing to do, right?
99 void GlyphIterator::reset(le_uint16 newLookupFlags
, FeatureMask newFeatureMask
)
101 position
= prevLimit
;
102 featureMask
= newFeatureMask
;
103 lookupFlags
= newLookupFlags
;
106 LEGlyphID
*GlyphIterator::insertGlyphs(le_int32 count
)
108 return glyphStorage
.insertGlyphs(position
, count
);
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 le_bool
GlyphIterator::hasFeatureTag() const
371 if (featureMask
== 0) {
375 LEErrorCode success
= LE_NO_ERROR
;
376 FeatureMask fm
= glyphStorage
.getAuxData(position
, success
);
378 return (fm
& featureMask
) != 0;
381 le_bool
GlyphIterator::findFeatureTag()
383 while (nextInternal()) {
384 if (hasFeatureTag()) {
394 le_bool
GlyphIterator::nextInternal(le_uint32 delta
)
396 le_int32 newPosition
= position
;
398 while (newPosition
!= nextLimit
&& delta
> 0) {
400 newPosition
+= direction
;
401 } while (newPosition
!= nextLimit
&& filterGlyph(newPosition
));
406 position
= newPosition
;
408 return position
!= nextLimit
;
411 le_bool
GlyphIterator::next(le_uint32 delta
)
413 return nextInternal(delta
) && hasFeatureTag();
416 le_bool
GlyphIterator::prevInternal(le_uint32 delta
)
418 le_int32 newPosition
= position
;
420 while (newPosition
!= prevLimit
&& delta
> 0) {
422 newPosition
-= direction
;
423 } while (newPosition
!= prevLimit
&& filterGlyph(newPosition
));
428 position
= newPosition
;
430 return position
!= prevLimit
;
433 le_bool
GlyphIterator::prev(le_uint32 delta
)
435 return prevInternal(delta
) && hasFeatureTag();
438 le_int32
GlyphIterator::getMarkComponent(le_int32 markPosition
) const
440 le_int32 component
= 0;
443 for (posn
= position
; posn
!= markPosition
; posn
+= direction
) {
444 if (glyphStorage
[posn
] == 0xFFFE) {
452 // This is basically prevInternal except that it
453 // doesn't take a delta argument, and it doesn't
454 // filter out 0xFFFE glyphs.
455 le_bool
GlyphIterator::findMark2Glyph()
457 le_int32 newPosition
= position
;
460 newPosition
-= direction
;
461 } while (newPosition
!= prevLimit
&& glyphStorage
[newPosition
] != 0xFFFE && filterGlyph(newPosition
));
463 position
= newPosition
;
465 return position
!= prevLimit
;