]>
git.saurik.com Git - apple/icu.git/blob - icuSources/layout/ValueRecords.cpp
3 * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
8 #include "LEFontInstance.h"
9 #include "OpenTypeTables.h"
10 #include "ValueRecords.h"
11 #include "DeviceTables.h"
12 #include "GlyphIterator.h"
17 #define Nibble(value, nibble) ((value >> (nibble * 4)) & 0xF)
18 #define NibbleBits(value, nibble) (bitsInNibble[Nibble(value, nibble)])
20 le_int16
ValueRecord::getFieldValue(ValueFormat valueFormat
, ValueRecordField field
) const
22 le_int16 valueIndex
= getFieldIndex(valueFormat
, field
);
23 le_int16 value
= values
[valueIndex
];
28 le_int16
ValueRecord::getFieldValue(le_int16 index
, ValueFormat valueFormat
, ValueRecordField field
) const
30 le_int16 baseIndex
= getFieldCount(valueFormat
) * index
;
31 le_int16 valueIndex
= getFieldIndex(valueFormat
, field
);
32 le_int16 value
= values
[baseIndex
+ valueIndex
];
37 void ValueRecord::adjustPosition(ValueFormat valueFormat
, const char *base
, GlyphIterator
&glyphIterator
,
38 const LEFontInstance
*fontInstance
) const
40 float xPlacementAdjustment
= 0;
41 float yPlacementAdjustment
= 0;
42 float xAdvanceAdjustment
= 0;
43 float yAdvanceAdjustment
= 0;
45 if ((valueFormat
& vfbXPlacement
) != 0) {
46 le_int16 value
= getFieldValue(valueFormat
, vrfXPlacement
);
49 fontInstance
->transformFunits(value
, 0, pixels
);
51 xPlacementAdjustment
+= fontInstance
->xPixelsToUnits(pixels
.fX
);
52 yPlacementAdjustment
+= fontInstance
->yPixelsToUnits(pixels
.fY
);
55 if ((valueFormat
& vfbYPlacement
) != 0) {
56 le_int16 value
= getFieldValue(valueFormat
, vrfYPlacement
);
59 fontInstance
->transformFunits(0, value
, pixels
);
61 xPlacementAdjustment
+= fontInstance
->xPixelsToUnits(pixels
.fX
);
62 yPlacementAdjustment
+= fontInstance
->yPixelsToUnits(pixels
.fY
);
65 if ((valueFormat
& vfbXAdvance
) != 0) {
66 le_int16 value
= getFieldValue(valueFormat
, vrfXAdvance
);
69 fontInstance
->transformFunits(value
, 0, pixels
);
71 xAdvanceAdjustment
+= fontInstance
->xPixelsToUnits(pixels
.fX
);
72 yAdvanceAdjustment
+= fontInstance
->yPixelsToUnits(pixels
.fY
);
75 if ((valueFormat
& vfbYAdvance
) != 0) {
76 le_int16 value
= getFieldValue(valueFormat
, vrfYAdvance
);
79 fontInstance
->transformFunits(0, value
, pixels
);
81 xAdvanceAdjustment
+= fontInstance
->xPixelsToUnits(pixels
.fX
);
82 yAdvanceAdjustment
+= fontInstance
->yPixelsToUnits(pixels
.fY
);
85 // FIXME: The device adjustments should really be transformed, but
86 // the only way I know how to do that is to convert them to le_int16 units,
87 // transform them, and then convert them back to pixels. Sigh...
88 if ((valueFormat
& vfbAnyDevice
) != 0) {
89 le_int16 xppem
= (le_int16
) fontInstance
->getXPixelsPerEm();
90 le_int16 yppem
= (le_int16
) fontInstance
->getYPixelsPerEm();
92 if ((valueFormat
& vfbXPlaDevice
) != 0) {
93 Offset dtOffset
= getFieldValue(valueFormat
, vrfXPlaDevice
);
96 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
97 le_int16 xAdj
= dt
->getAdjustment(xppem
);
99 xPlacementAdjustment
+= fontInstance
->xPixelsToUnits(xAdj
);
103 if ((valueFormat
& vfbYPlaDevice
) != 0) {
104 Offset dtOffset
= getFieldValue(valueFormat
, vrfYPlaDevice
);
107 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
108 le_int16 yAdj
= dt
->getAdjustment(yppem
);
110 yPlacementAdjustment
+= fontInstance
->yPixelsToUnits(yAdj
);
114 if ((valueFormat
& vfbXAdvDevice
) != 0) {
115 Offset dtOffset
= getFieldValue(valueFormat
, vrfXAdvDevice
);
118 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
119 le_int16 xAdj
= dt
->getAdjustment(xppem
);
121 xAdvanceAdjustment
+= fontInstance
->xPixelsToUnits(xAdj
);
125 if ((valueFormat
& vfbYAdvDevice
) != 0) {
126 Offset dtOffset
= getFieldValue(valueFormat
, vrfYAdvDevice
);
129 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
130 le_int16 yAdj
= dt
->getAdjustment(yppem
);
132 yAdvanceAdjustment
+= fontInstance
->yPixelsToUnits(yAdj
);
137 glyphIterator
.adjustCurrGlyphPositionAdjustment(
138 xPlacementAdjustment
, yPlacementAdjustment
, xAdvanceAdjustment
, yAdvanceAdjustment
);
141 void ValueRecord::adjustPosition(le_int16 index
, ValueFormat valueFormat
, const char *base
, GlyphIterator
&glyphIterator
,
142 const LEFontInstance
*fontInstance
) const
144 float xPlacementAdjustment
= 0;
145 float yPlacementAdjustment
= 0;
146 float xAdvanceAdjustment
= 0;
147 float yAdvanceAdjustment
= 0;
149 if ((valueFormat
& vfbXPlacement
) != 0) {
150 le_int16 value
= getFieldValue(index
, valueFormat
, vrfXPlacement
);
153 fontInstance
->transformFunits(value
, 0, pixels
);
155 xPlacementAdjustment
+= fontInstance
->xPixelsToUnits(pixels
.fX
);
156 yPlacementAdjustment
+= fontInstance
->yPixelsToUnits(pixels
.fY
);
159 if ((valueFormat
& vfbYPlacement
) != 0) {
160 le_int16 value
= getFieldValue(index
, valueFormat
, vrfYPlacement
);
163 fontInstance
->transformFunits(0, value
, pixels
);
165 xPlacementAdjustment
+= fontInstance
->xPixelsToUnits(pixels
.fX
);
166 yPlacementAdjustment
+= fontInstance
->yPixelsToUnits(pixels
.fY
);
169 if ((valueFormat
& vfbXAdvance
) != 0) {
170 le_int16 value
= getFieldValue(index
, valueFormat
, vrfXAdvance
);
173 fontInstance
->transformFunits(value
, 0, pixels
);
175 xAdvanceAdjustment
+= fontInstance
->xPixelsToUnits(pixels
.fX
);
176 yAdvanceAdjustment
+= fontInstance
->yPixelsToUnits(pixels
.fY
);
179 if ((valueFormat
& vfbYAdvance
) != 0) {
180 le_int16 value
= getFieldValue(index
, valueFormat
, vrfYAdvance
);
183 fontInstance
->transformFunits(0, value
, pixels
);
185 xAdvanceAdjustment
+= fontInstance
->xPixelsToUnits(pixels
.fX
);
186 yAdvanceAdjustment
+= fontInstance
->yPixelsToUnits(pixels
.fY
);
189 // FIXME: The device adjustments should really be transformed, but
190 // the only way I know how to do that is to convert them to le_int16 units,
191 // transform them, and then convert them back to pixels. Sigh...
192 if ((valueFormat
& vfbAnyDevice
) != 0) {
193 le_int16 xppem
= (le_int16
) fontInstance
->getXPixelsPerEm();
194 le_int16 yppem
= (le_int16
) fontInstance
->getYPixelsPerEm();
196 if ((valueFormat
& vfbXPlaDevice
) != 0) {
197 Offset dtOffset
= getFieldValue(index
, valueFormat
, vrfXPlaDevice
);
200 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
201 le_int16 xAdj
= dt
->getAdjustment(xppem
);
203 xPlacementAdjustment
+= fontInstance
->xPixelsToUnits(xAdj
);
207 if ((valueFormat
& vfbYPlaDevice
) != 0) {
208 Offset dtOffset
= getFieldValue(index
, valueFormat
, vrfYPlaDevice
);
211 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
212 le_int16 yAdj
= dt
->getAdjustment(yppem
);
214 yPlacementAdjustment
+= fontInstance
->yPixelsToUnits(yAdj
);
218 if ((valueFormat
& vfbXAdvDevice
) != 0) {
219 Offset dtOffset
= getFieldValue(index
, valueFormat
, vrfXAdvDevice
);
222 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
223 le_int16 xAdj
= dt
->getAdjustment(xppem
);
225 xAdvanceAdjustment
+= fontInstance
->xPixelsToUnits(xAdj
);
229 if ((valueFormat
& vfbYAdvDevice
) != 0) {
230 Offset dtOffset
= getFieldValue(index
, valueFormat
, vrfYAdvDevice
);
233 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
234 le_int16 yAdj
= dt
->getAdjustment(yppem
);
236 yAdvanceAdjustment
+= fontInstance
->yPixelsToUnits(yAdj
);
241 glyphIterator
.adjustCurrGlyphPositionAdjustment(
242 xPlacementAdjustment
, yPlacementAdjustment
, xAdvanceAdjustment
, yAdvanceAdjustment
);
245 le_int16
ValueRecord::getSize(ValueFormat valueFormat
)
247 return getFieldCount(valueFormat
) * sizeof(le_int16
);
250 le_int16
ValueRecord::getFieldCount(ValueFormat valueFormat
)
252 static const le_int16 bitsInNibble
[] =
272 valueFormat
&= ~vfbReserved
;
274 return NibbleBits(valueFormat
, 0) + NibbleBits(valueFormat
, 1) +
275 NibbleBits(valueFormat
, 2) + NibbleBits(valueFormat
, 3);
278 le_int16
ValueRecord::getFieldIndex(ValueFormat valueFormat
, ValueRecordField field
)
280 static const le_uint16 beforeMasks
[] =
301 return getFieldCount(valueFormat
& beforeMasks
[field
]);