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
18U_NAMESPACE_BEGIN
19
20class LEGlyphStorage;
21class LEFontInstance;
22
23class GlyphPositionAdjustments : public UMemory
24{
25private:
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
101public:
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
140inline GlyphPositionAdjustments::Adjustment::Adjustment()
141  : xPlacement(0), yPlacement(0), xAdvance(0), yAdvance(0), baseOffset(-1)
142{
143    // nothing else to do!
144}
145
146inline 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
152inline GlyphPositionAdjustments::Adjustment::~Adjustment()
153{
154    // nothing to do!
155}
156
157inline float GlyphPositionAdjustments::Adjustment::getXPlacement() const
158{
159    return xPlacement;
160}
161
162inline float GlyphPositionAdjustments::Adjustment::getYPlacement() const
163{
164    return yPlacement;
165}
166
167inline float GlyphPositionAdjustments::Adjustment::getXAdvance() const
168{
169    return xAdvance;
170}
171
172inline float GlyphPositionAdjustments::Adjustment::getYAdvance() const
173{
174    return yAdvance;
175}
176
177inline le_int32 GlyphPositionAdjustments::Adjustment::getBaseOffset() const
178{
179    return baseOffset;
180}
181
182inline void GlyphPositionAdjustments::Adjustment::setXPlacement(float newXPlacement)
183{
184    xPlacement = newXPlacement;
185}
186
187inline void GlyphPositionAdjustments::Adjustment::setYPlacement(float newYPlacement)
188{
189    yPlacement = newYPlacement;
190}
191
192inline void GlyphPositionAdjustments::Adjustment::setXAdvance(float newXAdvance)
193{
194    xAdvance = newXAdvance;
195}
196
197inline void GlyphPositionAdjustments::Adjustment::setYAdvance(float newYAdvance)
198{
199    yAdvance = newYAdvance;
200}
201
202inline void GlyphPositionAdjustments::Adjustment::setBaseOffset(le_int32 newBaseOffset)
203{
204    baseOffset = newBaseOffset;
205}
206
207inline void GlyphPositionAdjustments::Adjustment::adjustXPlacement(float xAdjustment)
208{
209    xPlacement += xAdjustment;
210}
211
212inline void GlyphPositionAdjustments::Adjustment::adjustYPlacement(float yAdjustment)
213{
214    yPlacement += yAdjustment;
215}
216
217inline void GlyphPositionAdjustments::Adjustment::adjustXAdvance(float xAdjustment)
218{
219    xAdvance += xAdjustment;
220}
221
222inline void GlyphPositionAdjustments::Adjustment::adjustYAdvance(float yAdjustment)
223{
224    yAdvance += yAdjustment;
225}
226
227inline GlyphPositionAdjustments::EntryExitPoint::EntryExitPoint()
228    : fFlags(0)
229{
230    fEntryPoint.fX = fEntryPoint.fY = fExitPoint.fX = fExitPoint.fY = 0;
231}
232
233inline GlyphPositionAdjustments::EntryExitPoint::~EntryExitPoint()
234{
235    // nothing special to do
236}
237
238inline le_bool GlyphPositionAdjustments::EntryExitPoint::isCursiveGlyph() const
239{
240    return (fFlags & EEF_IS_CURSIVE_GLYPH) != 0;
241}
242
243inline le_bool GlyphPositionAdjustments::EntryExitPoint::baselineIsLogicalEnd() const
244{
245    return (fFlags & EEF_BASELINE_IS_LOGICAL_END) != 0;
246}
247
248inline void GlyphPositionAdjustments::EntryExitPoint::clearEntryPoint()
249{
250    fFlags &= ~EEF_HAS_ENTRY_POINT;
251}
252
253inline void GlyphPositionAdjustments::EntryExitPoint::clearExitPoint()
254{
255    fFlags &= ~EEF_HAS_EXIT_POINT;
256}
257
258inline 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
269inline 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
280inline 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
289inline le_bool GlyphPositionAdjustments::isCursiveGlyph(le_int32 index) const
290{
291    return fEntryExitPoints != NULL && fEntryExitPoints[index].isCursiveGlyph();
292}
293
294inline le_bool GlyphPositionAdjustments::baselineIsLogicalEnd(le_int32 index) const
295{
296    return fEntryExitPoints != NULL && fEntryExitPoints[index].baselineIsLogicalEnd();
297}
298
299inline float GlyphPositionAdjustments::getXPlacement(le_int32 index) const
300{
301    return fAdjustments[index].getXPlacement();
302}
303
304inline float GlyphPositionAdjustments::getYPlacement(le_int32 index) const
305{
306    return fAdjustments[index].getYPlacement();
307}
308
309inline float GlyphPositionAdjustments::getXAdvance(le_int32 index) const
310{
311    return fAdjustments[index].getXAdvance();
312}
313
314inline float GlyphPositionAdjustments::getYAdvance(le_int32 index) const
315{
316    return fAdjustments[index].getYAdvance();
317}
318
319
320inline le_int32 GlyphPositionAdjustments::getBaseOffset(le_int32 index) const
321{
322    return fAdjustments[index].getBaseOffset();
323}
324
325inline void GlyphPositionAdjustments::setXPlacement(le_int32 index, float newXPlacement)
326{
327    fAdjustments[index].setXPlacement(newXPlacement);
328}
329
330inline void GlyphPositionAdjustments::setYPlacement(le_int32 index, float newYPlacement)
331{
332    fAdjustments[index].setYPlacement(newYPlacement);
333}
334
335inline void GlyphPositionAdjustments::setXAdvance(le_int32 index, float newXAdvance)
336{
337    fAdjustments[index].setXAdvance(newXAdvance);
338}
339
340inline void GlyphPositionAdjustments::setYAdvance(le_int32 index, float newYAdvance)
341{
342    fAdjustments[index].setYAdvance(newYAdvance);
343}
344
345inline void GlyphPositionAdjustments::setBaseOffset(le_int32 index, le_int32 newBaseOffset)
346{
347    fAdjustments[index].setBaseOffset(newBaseOffset);
348}
349
350inline void GlyphPositionAdjustments::adjustXPlacement(le_int32 index, float xAdjustment)
351{
352    fAdjustments[index].adjustXPlacement(xAdjustment);
353}
354
355inline void GlyphPositionAdjustments::adjustYPlacement(le_int32 index, float yAdjustment)
356{
357    fAdjustments[index].adjustYPlacement(yAdjustment);
358}
359
360inline void GlyphPositionAdjustments::adjustXAdvance(le_int32 index, float xAdjustment)
361{
362    fAdjustments[index].adjustXAdvance(xAdjustment);
363}
364
365inline void GlyphPositionAdjustments::adjustYAdvance(le_int32 index, float yAdjustment)
366{
367    fAdjustments[index].adjustYAdvance(yAdjustment);
368}
369
370inline le_bool GlyphPositionAdjustments::hasCursiveGlyphs() const
371{
372    return fEntryExitPoints != NULL;
373}
374
375U_NAMESPACE_END
376#endif
377