1 /*
2  *
3  * (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved
4  *
5  */
6 
7 #ifndef __GLYPHPOSITIONADJUSTMENTS_H
8 #define __GLYPHPOSITIONADJUSTMENTS_H
9 
10 /**
11  * \file
12  * \internal
13  */
14 
15 #include "LETypes.h"
16 #include "OpenTypeTables.h"
17 
18 U_NAMESPACE_BEGIN
19 
20 class LEGlyphStorage;
21 class LEFontInstance;
22 
23 class GlyphPositionAdjustments : public UMemory
24 {
25 private:
26     class Adjustment : public UMemory {
27     public:
28 
29         inline Adjustment();
30         inline Adjustment(float xPlace, float yPlace, float xAdv, float yAdv, le_int32 baseOff = -1);
31         inline ~Adjustment();
32 
33         inline float    getXPlacement() const;
34         inline float    getYPlacement() const;
35         inline float    getXAdvance() const;
36         inline float    getYAdvance() const;
37 
38         inline le_int32 getBaseOffset() const;
39 
40         inline void     setXPlacement(float newXPlacement);
41         inline void     setYPlacement(float newYPlacement);
42         inline void     setXAdvance(float newXAdvance);
43         inline void     setYAdvance(float newYAdvance);
44 
45         inline void     setBaseOffset(le_int32 newBaseOffset);
46 
47         inline void    adjustXPlacement(float xAdjustment);
48         inline void    adjustYPlacement(float yAdjustment);
49         inline void    adjustXAdvance(float xAdjustment);
50         inline void    adjustYAdvance(float yAdjustment);
51 
52     private:
53         float xPlacement;
54         float yPlacement;
55         float xAdvance;
56         float yAdvance;
57 
58         le_int32 baseOffset;
59 
60         // allow copying of this class because all of its fields are simple types
61     };
62 
63     class EntryExitPoint : public UMemory
64     {
65     public:
66         inline EntryExitPoint();
67         inline ~EntryExitPoint();
68 
69         inline le_bool isCursiveGlyph() const;
70         inline le_bool baselineIsLogicalEnd() const;
71 
72         LEPoint *getEntryPoint(LEPoint &entryPoint) const;
73         LEPoint *getExitPoint(LEPoint &exitPoint) const;
74 
75         inline void clearEntryPoint();
76         inline void clearExitPoint();
77         inline void setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
78         inline void setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
79         inline void setCursiveGlyph(le_bool baselineIsLogicalEnd);
80 
81     private:
82         enum EntryExitFlags
83         {
84             EEF_HAS_ENTRY_POINT         = 0x80000000L,
85             EEF_HAS_EXIT_POINT          = 0x40000000L,
86             EEF_IS_CURSIVE_GLYPH        = 0x20000000L,
87             EEF_BASELINE_IS_LOGICAL_END = 0x10000000L
88         };
89 
90         le_uint32 fFlags;
91         LEPoint fEntryPoint;
92         LEPoint fExitPoint;
93     };
94 
95     le_int32 fGlyphCount;
96     EntryExitPoint *fEntryExitPoints;
97     Adjustment *fAdjustments;
98 
99     GlyphPositionAdjustments();
100 
101 public:
102     GlyphPositionAdjustments(le_int32 glyphCount);
103     ~GlyphPositionAdjustments();
104 
105     inline le_bool hasCursiveGlyphs() const;
106     inline le_bool isCursiveGlyph(le_int32 index) const;
107     inline le_bool baselineIsLogicalEnd(le_int32 index) const;
108 
109     const LEPoint *getEntryPoint(le_int32 index, LEPoint &entryPoint) const;
110     const LEPoint *getExitPoint(le_int32 index, LEPoint &exitPoint) const;
111 
112     inline float getXPlacement(le_int32 index) const;
113     inline float getYPlacement(le_int32 index) const;
114     inline float getXAdvance(le_int32 index) const;
115     inline float getYAdvance(le_int32 index) const;
116 
117     inline le_int32 getBaseOffset(le_int32 index) const;
118 
119     inline void setXPlacement(le_int32 index, float newXPlacement);
120     inline void setYPlacement(le_int32 index, float newYPlacement);
121     inline void setXAdvance(le_int32 index, float newXAdvance);
122     inline void setYAdvance(le_int32 index, float newYAdvance);
123 
124     inline void setBaseOffset(le_int32 index, le_int32 newBaseOffset);
125 
126     inline void adjustXPlacement(le_int32 index, float xAdjustment);
127     inline void adjustYPlacement(le_int32 index, float yAdjustment);
128     inline void adjustXAdvance(le_int32 index, float xAdjustment);
129     inline void adjustYAdvance(le_int32 index, float yAdjustment);
130 
131     void clearEntryPoint(le_int32 index);
132     void clearExitPoint(le_int32 index);
133     void setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
134     void setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
135     void setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd);
136 
137     void applyCursiveAdjustments(LEGlyphStorage &glyphStorage, le_bool rightToLeft, const LEFontInstance *fontInstance);
138 };
139 
Adjustment()140 inline GlyphPositionAdjustments::Adjustment::Adjustment()
141   : xPlacement(0), yPlacement(0), xAdvance(0), yAdvance(0), baseOffset(-1)
142 {
143     // nothing else to do!
144 }
145 
Adjustment(float xPlace,float yPlace,float xAdv,float yAdv,le_int32 baseOff)146 inline GlyphPositionAdjustments::Adjustment::Adjustment(float xPlace, float yPlace, float xAdv, float yAdv, le_int32 baseOff)
147   : xPlacement(xPlace), yPlacement(yPlace), xAdvance(xAdv), yAdvance(yAdv), baseOffset(baseOff)
148 {
149     // nothing else to do!
150 }
151 
~Adjustment()152 inline GlyphPositionAdjustments::Adjustment::~Adjustment()
153 {
154     // nothing to do!
155 }
156 
getXPlacement()157 inline float GlyphPositionAdjustments::Adjustment::getXPlacement() const
158 {
159     return xPlacement;
160 }
161 
getYPlacement()162 inline float GlyphPositionAdjustments::Adjustment::getYPlacement() const
163 {
164     return yPlacement;
165 }
166 
getXAdvance()167 inline float GlyphPositionAdjustments::Adjustment::getXAdvance() const
168 {
169     return xAdvance;
170 }
171 
getYAdvance()172 inline float GlyphPositionAdjustments::Adjustment::getYAdvance() const
173 {
174     return yAdvance;
175 }
176 
getBaseOffset()177 inline le_int32 GlyphPositionAdjustments::Adjustment::getBaseOffset() const
178 {
179     return baseOffset;
180 }
181 
setXPlacement(float newXPlacement)182 inline void GlyphPositionAdjustments::Adjustment::setXPlacement(float newXPlacement)
183 {
184     xPlacement = newXPlacement;
185 }
186 
setYPlacement(float newYPlacement)187 inline void GlyphPositionAdjustments::Adjustment::setYPlacement(float newYPlacement)
188 {
189     yPlacement = newYPlacement;
190 }
191 
setXAdvance(float newXAdvance)192 inline void GlyphPositionAdjustments::Adjustment::setXAdvance(float newXAdvance)
193 {
194     xAdvance = newXAdvance;
195 }
196 
setYAdvance(float newYAdvance)197 inline void GlyphPositionAdjustments::Adjustment::setYAdvance(float newYAdvance)
198 {
199     yAdvance = newYAdvance;
200 }
201 
setBaseOffset(le_int32 newBaseOffset)202 inline void GlyphPositionAdjustments::Adjustment::setBaseOffset(le_int32 newBaseOffset)
203 {
204     baseOffset = newBaseOffset;
205 }
206 
adjustXPlacement(float xAdjustment)207 inline void GlyphPositionAdjustments::Adjustment::adjustXPlacement(float xAdjustment)
208 {
209     xPlacement += xAdjustment;
210 }
211 
adjustYPlacement(float yAdjustment)212 inline void GlyphPositionAdjustments::Adjustment::adjustYPlacement(float yAdjustment)
213 {
214     yPlacement += yAdjustment;
215 }
216 
adjustXAdvance(float xAdjustment)217 inline void GlyphPositionAdjustments::Adjustment::adjustXAdvance(float xAdjustment)
218 {
219     xAdvance += xAdjustment;
220 }
221 
adjustYAdvance(float yAdjustment)222 inline void GlyphPositionAdjustments::Adjustment::adjustYAdvance(float yAdjustment)
223 {
224     yAdvance += yAdjustment;
225 }
226 
EntryExitPoint()227 inline GlyphPositionAdjustments::EntryExitPoint::EntryExitPoint()
228     : fFlags(0)
229 {
230     fEntryPoint.fX = fEntryPoint.fY = fExitPoint.fX = fExitPoint.fY = 0;
231 }
232 
~EntryExitPoint()233 inline GlyphPositionAdjustments::EntryExitPoint::~EntryExitPoint()
234 {
235     // nothing special to do
236 }
237 
isCursiveGlyph()238 inline le_bool GlyphPositionAdjustments::EntryExitPoint::isCursiveGlyph() const
239 {
240     return (fFlags & EEF_IS_CURSIVE_GLYPH) != 0;
241 }
242 
baselineIsLogicalEnd()243 inline le_bool GlyphPositionAdjustments::EntryExitPoint::baselineIsLogicalEnd() const
244 {
245     return (fFlags & EEF_BASELINE_IS_LOGICAL_END) != 0;
246 }
247 
clearEntryPoint()248 inline void GlyphPositionAdjustments::EntryExitPoint::clearEntryPoint()
249 {
250     fFlags &= ~EEF_HAS_ENTRY_POINT;
251 }
252 
clearExitPoint()253 inline void GlyphPositionAdjustments::EntryExitPoint::clearExitPoint()
254 {
255     fFlags &= ~EEF_HAS_EXIT_POINT;
256 }
257 
setEntryPoint(LEPoint & newEntryPoint,le_bool baselineIsLogicalEnd)258 inline void GlyphPositionAdjustments::EntryExitPoint::setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
259 {
260     if (baselineIsLogicalEnd) {
261         fFlags |= (EEF_HAS_ENTRY_POINT | EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
262     } else {
263         fFlags |= (EEF_HAS_ENTRY_POINT | EEF_IS_CURSIVE_GLYPH);
264     }
265 
266     fEntryPoint = newEntryPoint;
267 }
268 
setExitPoint(LEPoint & newExitPoint,le_bool baselineIsLogicalEnd)269 inline void GlyphPositionAdjustments::EntryExitPoint::setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd)
270 {
271     if (baselineIsLogicalEnd) {
272         fFlags |= (EEF_HAS_EXIT_POINT | EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
273     } else {
274         fFlags |= (EEF_HAS_EXIT_POINT | EEF_IS_CURSIVE_GLYPH);
275     }
276 
277     fExitPoint  = newExitPoint;
278 }
279 
setCursiveGlyph(le_bool baselineIsLogicalEnd)280 inline void GlyphPositionAdjustments::EntryExitPoint::setCursiveGlyph(le_bool baselineIsLogicalEnd)
281 {
282     if (baselineIsLogicalEnd) {
283         fFlags |= (EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
284     } else {
285         fFlags |= EEF_IS_CURSIVE_GLYPH;
286     }
287 }
288 
isCursiveGlyph(le_int32 index)289 inline le_bool GlyphPositionAdjustments::isCursiveGlyph(le_int32 index) const
290 {
291     return fEntryExitPoints != NULL && fEntryExitPoints[index].isCursiveGlyph();
292 }
293 
baselineIsLogicalEnd(le_int32 index)294 inline le_bool GlyphPositionAdjustments::baselineIsLogicalEnd(le_int32 index) const
295 {
296     return fEntryExitPoints != NULL && fEntryExitPoints[index].baselineIsLogicalEnd();
297 }
298 
getXPlacement(le_int32 index)299 inline float GlyphPositionAdjustments::getXPlacement(le_int32 index) const
300 {
301     return fAdjustments[index].getXPlacement();
302 }
303 
getYPlacement(le_int32 index)304 inline float GlyphPositionAdjustments::getYPlacement(le_int32 index) const
305 {
306     return fAdjustments[index].getYPlacement();
307 }
308 
getXAdvance(le_int32 index)309 inline float GlyphPositionAdjustments::getXAdvance(le_int32 index) const
310 {
311     return fAdjustments[index].getXAdvance();
312 }
313 
getYAdvance(le_int32 index)314 inline float GlyphPositionAdjustments::getYAdvance(le_int32 index) const
315 {
316     return fAdjustments[index].getYAdvance();
317 }
318 
319 
getBaseOffset(le_int32 index)320 inline le_int32 GlyphPositionAdjustments::getBaseOffset(le_int32 index) const
321 {
322     return fAdjustments[index].getBaseOffset();
323 }
324 
setXPlacement(le_int32 index,float newXPlacement)325 inline void GlyphPositionAdjustments::setXPlacement(le_int32 index, float newXPlacement)
326 {
327     fAdjustments[index].setXPlacement(newXPlacement);
328 }
329 
setYPlacement(le_int32 index,float newYPlacement)330 inline void GlyphPositionAdjustments::setYPlacement(le_int32 index, float newYPlacement)
331 {
332     fAdjustments[index].setYPlacement(newYPlacement);
333 }
334 
setXAdvance(le_int32 index,float newXAdvance)335 inline void GlyphPositionAdjustments::setXAdvance(le_int32 index, float newXAdvance)
336 {
337     fAdjustments[index].setXAdvance(newXAdvance);
338 }
339 
setYAdvance(le_int32 index,float newYAdvance)340 inline void GlyphPositionAdjustments::setYAdvance(le_int32 index, float newYAdvance)
341 {
342     fAdjustments[index].setYAdvance(newYAdvance);
343 }
344 
setBaseOffset(le_int32 index,le_int32 newBaseOffset)345 inline void GlyphPositionAdjustments::setBaseOffset(le_int32 index, le_int32 newBaseOffset)
346 {
347     fAdjustments[index].setBaseOffset(newBaseOffset);
348 }
349 
adjustXPlacement(le_int32 index,float xAdjustment)350 inline void GlyphPositionAdjustments::adjustXPlacement(le_int32 index, float xAdjustment)
351 {
352     fAdjustments[index].adjustXPlacement(xAdjustment);
353 }
354 
adjustYPlacement(le_int32 index,float yAdjustment)355 inline void GlyphPositionAdjustments::adjustYPlacement(le_int32 index, float yAdjustment)
356 {
357     fAdjustments[index].adjustYPlacement(yAdjustment);
358 }
359 
adjustXAdvance(le_int32 index,float xAdjustment)360 inline void GlyphPositionAdjustments::adjustXAdvance(le_int32 index, float xAdjustment)
361 {
362     fAdjustments[index].adjustXAdvance(xAdjustment);
363 }
364 
adjustYAdvance(le_int32 index,float yAdjustment)365 inline void GlyphPositionAdjustments::adjustYAdvance(le_int32 index, float yAdjustment)
366 {
367     fAdjustments[index].adjustYAdvance(yAdjustment);
368 }
369 
hasCursiveGlyphs()370 inline le_bool GlyphPositionAdjustments::hasCursiveGlyphs() const
371 {
372     return fEntryExitPoints != NULL;
373 }
374 
375 U_NAMESPACE_END
376 #endif
377