3 * (C) Copyright IBM Corp. 1998-2005 - 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::setEntryPoint(le_int32 index
, LEPoint
&newEntryPoint
, le_bool baselineIsLogicalEnd
)
51 CHECK_ALLOCATE_ARRAY(fEntryExitPoints
, EntryExitPoint
, fGlyphCount
);
53 fEntryExitPoints
[index
].setEntryPoint(newEntryPoint
, baselineIsLogicalEnd
);
56 void GlyphPositionAdjustments::setExitPoint(le_int32 index
, LEPoint
&newExitPoint
, le_bool baselineIsLogicalEnd
)
58 CHECK_ALLOCATE_ARRAY(fEntryExitPoints
, EntryExitPoint
, fGlyphCount
);
60 fEntryExitPoints
[index
].setExitPoint(newExitPoint
, baselineIsLogicalEnd
);
63 void GlyphPositionAdjustments::setCursiveGlyph(le_int32 index
, le_bool baselineIsLogicalEnd
)
65 CHECK_ALLOCATE_ARRAY(fEntryExitPoints
, EntryExitPoint
, fGlyphCount
);
67 fEntryExitPoints
[index
].setCursiveGlyph(baselineIsLogicalEnd
);
70 void GlyphPositionAdjustments::applyCursiveAdjustments(LEGlyphStorage
&glyphStorage
, le_bool rightToLeft
, const LEFontInstance
*fontInstance
)
72 if (! hasCursiveGlyphs()) {
76 le_int32 start
= 0, end
= fGlyphCount
, dir
= 1;
77 le_int32 firstExitPoint
= -1, lastExitPoint
= -1;
78 LEPoint entryAnchor
, exitAnchor
, pixels
;
79 LEGlyphID lastExitGlyphID
= 0;
80 float baselineAdjustment
= 0;
82 // This removes a possible warning about
83 // using exitAnchor before it's been initialized.
84 exitAnchor
.fX
= exitAnchor
.fY
= 0;
87 start
= fGlyphCount
- 1;
92 for (le_int32 i
= start
; i
!= end
; i
+= dir
) {
93 LEGlyphID glyphID
= glyphStorage
[i
];
95 if (isCursiveGlyph(i
)) {
96 if (lastExitPoint
>= 0 && getEntryPoint(i
, entryAnchor
) != NULL
) {
97 float anchorDiffX
= exitAnchor
.fX
- entryAnchor
.fX
;
98 float anchorDiffY
= exitAnchor
.fY
- entryAnchor
.fY
;
100 baselineAdjustment
+= anchorDiffY
;
101 adjustYPlacement(i
, baselineAdjustment
);
104 LEPoint secondAdvance
;
106 fontInstance
->getGlyphAdvance(glyphID
, pixels
);
107 fontInstance
->pixelsToUnits(pixels
, secondAdvance
);
109 adjustXAdvance(i
, -(anchorDiffX
+ secondAdvance
.fX
));
111 LEPoint firstAdvance
;
113 fontInstance
->getGlyphAdvance(lastExitGlyphID
, pixels
);
114 fontInstance
->pixelsToUnits(pixels
, firstAdvance
);
116 adjustXAdvance(lastExitPoint
, anchorDiffX
- firstAdvance
.fX
);
122 if (getExitPoint(i
, exitAnchor
) != NULL
) {
123 if (firstExitPoint
< 0) {
127 lastExitGlyphID
= glyphID
;
129 if (baselineIsLogicalEnd(i
) && firstExitPoint
>= 0 && lastExitPoint
>= 0) {
130 le_int32 limit
= lastExitPoint
+ dir
;
132 for (le_int32 j
= firstExitPoint
; j
!= limit
; j
+= dir
) {
133 if (isCursiveGlyph(j
)) {
134 adjustYPlacement(j
, -baselineAdjustment
);
139 firstExitPoint
= lastExitPoint
= -1;
140 baselineAdjustment
= 0;
146 LEPoint
*GlyphPositionAdjustments::EntryExitPoint::getEntryPoint(LEPoint
&entryPoint
) const
148 if (fFlags
& EEF_HAS_ENTRY_POINT
) {
149 entryPoint
= fEntryPoint
;
156 LEPoint
*GlyphPositionAdjustments::EntryExitPoint::getExitPoint(LEPoint
&exitPoint
) const
158 if (fFlags
& EEF_HAS_EXIT_POINT
) {
159 exitPoint
= fExitPoint
;