3 * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
8 #include "GlyphPositionAdjustments.h"
9 #include "LEGlyphStorage.h"
10 #include "LEFontInstance.h"
14 #define CHECK_ALLOCATE_ARRAY(array, type, size) \
15 if (array == NULL) { \
16 array = (type *) new type[size]; \
19 GlyphPositionAdjustments::GlyphPositionAdjustments(le_int32 glyphCount
)
20 : fGlyphCount(glyphCount
), fEntryExitPoints(NULL
), fAdjustments(NULL
)
22 fAdjustments
= (Adjustment
*) new Adjustment
[glyphCount
];
25 GlyphPositionAdjustments::~GlyphPositionAdjustments()
27 delete[] fEntryExitPoints
;
28 delete[] fAdjustments
;
31 const LEPoint
*GlyphPositionAdjustments::getEntryPoint(le_int32 index
, LEPoint
&entryPoint
) const
33 if (fEntryExitPoints
== NULL
) {
37 return fEntryExitPoints
[index
].getEntryPoint(entryPoint
);
40 const LEPoint
*GlyphPositionAdjustments::getExitPoint(le_int32 index
, LEPoint
&exitPoint
)const
42 if (fEntryExitPoints
== NULL
) {
46 return fEntryExitPoints
[index
].getExitPoint(exitPoint
);
49 void GlyphPositionAdjustments::clearEntryPoint(le_int32 index
)
51 CHECK_ALLOCATE_ARRAY(fEntryExitPoints
, EntryExitPoint
, fGlyphCount
);
53 fEntryExitPoints
[index
].clearEntryPoint();
56 void GlyphPositionAdjustments::clearExitPoint(le_int32 index
)
58 CHECK_ALLOCATE_ARRAY(fEntryExitPoints
, EntryExitPoint
, fGlyphCount
);
60 fEntryExitPoints
[index
].clearExitPoint();
63 void GlyphPositionAdjustments::setEntryPoint(le_int32 index
, LEPoint
&newEntryPoint
, le_bool baselineIsLogicalEnd
)
65 CHECK_ALLOCATE_ARRAY(fEntryExitPoints
, EntryExitPoint
, fGlyphCount
);
67 fEntryExitPoints
[index
].setEntryPoint(newEntryPoint
, baselineIsLogicalEnd
);
70 void GlyphPositionAdjustments::setExitPoint(le_int32 index
, LEPoint
&newExitPoint
, le_bool baselineIsLogicalEnd
)
72 CHECK_ALLOCATE_ARRAY(fEntryExitPoints
, EntryExitPoint
, fGlyphCount
);
74 fEntryExitPoints
[index
].setExitPoint(newExitPoint
, baselineIsLogicalEnd
);
77 void GlyphPositionAdjustments::setCursiveGlyph(le_int32 index
, le_bool baselineIsLogicalEnd
)
79 CHECK_ALLOCATE_ARRAY(fEntryExitPoints
, EntryExitPoint
, fGlyphCount
);
81 fEntryExitPoints
[index
].setCursiveGlyph(baselineIsLogicalEnd
);
84 void GlyphPositionAdjustments::applyCursiveAdjustments(LEGlyphStorage
&glyphStorage
, le_bool rightToLeft
, const LEFontInstance
*fontInstance
)
86 if (! hasCursiveGlyphs()) {
90 le_int32 start
= 0, end
= fGlyphCount
, dir
= 1;
91 le_int32 firstExitPoint
= -1, lastExitPoint
= -1;
92 LEPoint entryAnchor
, exitAnchor
, pixels
;
93 LEGlyphID lastExitGlyphID
= 0;
94 float baselineAdjustment
= 0;
96 // This removes a possible warning about
97 // using exitAnchor before it's been initialized.
98 exitAnchor
.fX
= exitAnchor
.fY
= 0;
101 start
= fGlyphCount
- 1;
106 for (le_int32 i
= start
; i
!= end
; i
+= dir
) {
107 LEGlyphID glyphID
= glyphStorage
[i
];
109 if (isCursiveGlyph(i
)) {
110 if (lastExitPoint
>= 0 && getEntryPoint(i
, entryAnchor
) != NULL
) {
111 float anchorDiffX
= exitAnchor
.fX
- entryAnchor
.fX
;
112 float anchorDiffY
= exitAnchor
.fY
- entryAnchor
.fY
;
114 baselineAdjustment
+= anchorDiffY
;
115 adjustYPlacement(i
, baselineAdjustment
);
118 LEPoint secondAdvance
;
120 fontInstance
->getGlyphAdvance(glyphID
, pixels
);
121 fontInstance
->pixelsToUnits(pixels
, secondAdvance
);
123 adjustXAdvance(i
, -(anchorDiffX
+ secondAdvance
.fX
));
125 LEPoint firstAdvance
;
127 fontInstance
->getGlyphAdvance(lastExitGlyphID
, pixels
);
128 fontInstance
->pixelsToUnits(pixels
, firstAdvance
);
130 adjustXAdvance(lastExitPoint
, anchorDiffX
- firstAdvance
.fX
);
136 if (getExitPoint(i
, exitAnchor
) != NULL
) {
137 if (firstExitPoint
< 0) {
141 lastExitGlyphID
= glyphID
;
143 if (baselineIsLogicalEnd(i
) && firstExitPoint
>= 0 && lastExitPoint
>= 0) {
144 le_int32 limit
= lastExitPoint
/*+ dir*/;
147 if (getEntryPoint(i
, dummyAnchor
) != NULL
) {
151 for (le_int32 j
= firstExitPoint
; j
!= limit
; j
+= dir
) {
152 if (isCursiveGlyph(j
)) {
153 adjustYPlacement(j
, -baselineAdjustment
);
158 firstExitPoint
= lastExitPoint
= -1;
159 baselineAdjustment
= 0;
165 LEPoint
*GlyphPositionAdjustments::EntryExitPoint::getEntryPoint(LEPoint
&entryPoint
) const
167 if (fFlags
& EEF_HAS_ENTRY_POINT
) {
168 entryPoint
= fEntryPoint
;
175 LEPoint
*GlyphPositionAdjustments::EntryExitPoint::getExitPoint(LEPoint
&exitPoint
) const
177 if (fFlags
& EEF_HAS_EXIT_POINT
) {
178 exitPoint
= fExitPoint
;