]> git.saurik.com Git - apple/icu.git/blame - icuSources/layout/ValueRecords.cpp
ICU-511.27.tar.gz
[apple/icu.git] / icuSources / layout / ValueRecords.cpp
CommitLineData
b75a7d8f 1/*
b75a7d8f 2 *
73c04bcf 3 * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
b75a7d8f
A
4 *
5 */
6
7#include "LETypes.h"
8#include "LEFontInstance.h"
9#include "OpenTypeTables.h"
10#include "ValueRecords.h"
11#include "DeviceTables.h"
12#include "GlyphIterator.h"
b75a7d8f
A
13#include "LESwaps.h"
14
15U_NAMESPACE_BEGIN
16
17#define Nibble(value, nibble) ((value >> (nibble * 4)) & 0xF)
18#define NibbleBits(value, nibble) (bitsInNibble[Nibble(value, nibble)])
19
20le_int16 ValueRecord::getFieldValue(ValueFormat valueFormat, ValueRecordField field) const
21{
22 le_int16 valueIndex = getFieldIndex(valueFormat, field);
23 le_int16 value = values[valueIndex];
24
25 return SWAPW(value);
26}
27
28le_int16 ValueRecord::getFieldValue(le_int16 index, ValueFormat valueFormat, ValueRecordField field) const
29{
30 le_int16 baseIndex = getFieldCount(valueFormat) * index;
31 le_int16 valueIndex = getFieldIndex(valueFormat, field);
32 le_int16 value = values[baseIndex + valueIndex];
33
34 return SWAPW(value);
35}
36
73c04bcf 37void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
b75a7d8f
A
38 const LEFontInstance *fontInstance) const
39{
73c04bcf
A
40 float xPlacementAdjustment = 0;
41 float yPlacementAdjustment = 0;
42 float xAdvanceAdjustment = 0;
43 float yAdvanceAdjustment = 0;
44
b75a7d8f
A
45 if ((valueFormat & vfbXPlacement) != 0) {
46 le_int16 value = getFieldValue(valueFormat, vrfXPlacement);
47 LEPoint pixels;
48
49 fontInstance->transformFunits(value, 0, pixels);
50
73c04bcf
A
51 xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
52 yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
b75a7d8f
A
53 }
54
55 if ((valueFormat & vfbYPlacement) != 0) {
56 le_int16 value = getFieldValue(valueFormat, vrfYPlacement);
57 LEPoint pixels;
58
59 fontInstance->transformFunits(0, value, pixels);
60
73c04bcf
A
61 xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
62 yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
b75a7d8f
A
63 }
64
65 if ((valueFormat & vfbXAdvance) != 0) {
66 le_int16 value = getFieldValue(valueFormat, vrfXAdvance);
67 LEPoint pixels;
68
69 fontInstance->transformFunits(value, 0, pixels);
70
73c04bcf
A
71 xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
72 yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
b75a7d8f
A
73 }
74
75 if ((valueFormat & vfbYAdvance) != 0) {
76 le_int16 value = getFieldValue(valueFormat, vrfYAdvance);
77 LEPoint pixels;
78
79 fontInstance->transformFunits(0, value, pixels);
80
73c04bcf
A
81 xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
82 yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
b75a7d8f
A
83 }
84
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();
91
92 if ((valueFormat & vfbXPlaDevice) != 0) {
93 Offset dtOffset = getFieldValue(valueFormat, vrfXPlaDevice);
94
95 if (dtOffset != 0) {
96 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
97 le_int16 xAdj = dt->getAdjustment(xppem);
98
73c04bcf 99 xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
b75a7d8f
A
100 }
101 }
102
103 if ((valueFormat & vfbYPlaDevice) != 0) {
104 Offset dtOffset = getFieldValue(valueFormat, vrfYPlaDevice);
105
106 if (dtOffset != 0) {
107 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
108 le_int16 yAdj = dt->getAdjustment(yppem);
109
73c04bcf 110 yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
b75a7d8f
A
111 }
112 }
113
114 if ((valueFormat & vfbXAdvDevice) != 0) {
115 Offset dtOffset = getFieldValue(valueFormat, vrfXAdvDevice);
116
117 if (dtOffset != 0) {
118 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
119 le_int16 xAdj = dt->getAdjustment(xppem);
120
73c04bcf 121 xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
b75a7d8f
A
122 }
123 }
124
125 if ((valueFormat & vfbYAdvDevice) != 0) {
126 Offset dtOffset = getFieldValue(valueFormat, vrfYAdvDevice);
127
128 if (dtOffset != 0) {
129 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
130 le_int16 yAdj = dt->getAdjustment(yppem);
131
73c04bcf 132 yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
b75a7d8f
A
133 }
134 }
135 }
73c04bcf
A
136
137 glyphIterator.adjustCurrGlyphPositionAdjustment(
138 xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
b75a7d8f
A
139}
140
73c04bcf 141void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
b75a7d8f
A
142 const LEFontInstance *fontInstance) const
143{
73c04bcf
A
144 float xPlacementAdjustment = 0;
145 float yPlacementAdjustment = 0;
146 float xAdvanceAdjustment = 0;
147 float yAdvanceAdjustment = 0;
148
b75a7d8f
A
149 if ((valueFormat & vfbXPlacement) != 0) {
150 le_int16 value = getFieldValue(index, valueFormat, vrfXPlacement);
151 LEPoint pixels;
152
153 fontInstance->transformFunits(value, 0, pixels);
154
73c04bcf
A
155 xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
156 yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
b75a7d8f
A
157 }
158
159 if ((valueFormat & vfbYPlacement) != 0) {
160 le_int16 value = getFieldValue(index, valueFormat, vrfYPlacement);
161 LEPoint pixels;
162
163 fontInstance->transformFunits(0, value, pixels);
164
73c04bcf
A
165 xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
166 yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
b75a7d8f
A
167 }
168
169 if ((valueFormat & vfbXAdvance) != 0) {
170 le_int16 value = getFieldValue(index, valueFormat, vrfXAdvance);
171 LEPoint pixels;
172
173 fontInstance->transformFunits(value, 0, pixels);
174
73c04bcf
A
175 xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
176 yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
b75a7d8f
A
177 }
178
179 if ((valueFormat & vfbYAdvance) != 0) {
180 le_int16 value = getFieldValue(index, valueFormat, vrfYAdvance);
181 LEPoint pixels;
182
183 fontInstance->transformFunits(0, value, pixels);
184
73c04bcf
A
185 xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
186 yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
b75a7d8f
A
187 }
188
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();
195
196 if ((valueFormat & vfbXPlaDevice) != 0) {
197 Offset dtOffset = getFieldValue(index, valueFormat, vrfXPlaDevice);
198
199 if (dtOffset != 0) {
200 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
201 le_int16 xAdj = dt->getAdjustment(xppem);
202
73c04bcf 203 xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
b75a7d8f
A
204 }
205 }
206
207 if ((valueFormat & vfbYPlaDevice) != 0) {
208 Offset dtOffset = getFieldValue(index, valueFormat, vrfYPlaDevice);
209
210 if (dtOffset != 0) {
211 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
212 le_int16 yAdj = dt->getAdjustment(yppem);
213
73c04bcf 214 yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
b75a7d8f
A
215 }
216 }
217
218 if ((valueFormat & vfbXAdvDevice) != 0) {
219 Offset dtOffset = getFieldValue(index, valueFormat, vrfXAdvDevice);
220
221 if (dtOffset != 0) {
222 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
223 le_int16 xAdj = dt->getAdjustment(xppem);
224
73c04bcf 225 xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
b75a7d8f
A
226 }
227 }
228
229 if ((valueFormat & vfbYAdvDevice) != 0) {
230 Offset dtOffset = getFieldValue(index, valueFormat, vrfYAdvDevice);
231
232 if (dtOffset != 0) {
233 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
234 le_int16 yAdj = dt->getAdjustment(yppem);
235
73c04bcf 236 yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
b75a7d8f
A
237 }
238 }
239 }
73c04bcf
A
240
241 glyphIterator.adjustCurrGlyphPositionAdjustment(
242 xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
b75a7d8f
A
243}
244
245le_int16 ValueRecord::getSize(ValueFormat valueFormat)
246{
247 return getFieldCount(valueFormat) * sizeof(le_int16);
248}
249
250le_int16 ValueRecord::getFieldCount(ValueFormat valueFormat)
251{
374ca955 252 static const le_int16 bitsInNibble[] =
b75a7d8f
A
253 {
254 0 + 0 + 0 + 0,
255 0 + 0 + 0 + 1,
256 0 + 0 + 1 + 0,
257 0 + 0 + 1 + 1,
258 0 + 1 + 0 + 0,
259 0 + 1 + 0 + 1,
260 0 + 1 + 1 + 0,
261 0 + 1 + 1 + 1,
262 1 + 0 + 0 + 0,
263 1 + 0 + 0 + 1,
264 1 + 0 + 1 + 0,
265 1 + 0 + 1 + 1,
266 1 + 1 + 0 + 0,
267 1 + 1 + 0 + 1,
268 1 + 1 + 1 + 0,
269 1 + 1 + 1 + 1
270 };
271
272 valueFormat &= ~vfbReserved;
273
274 return NibbleBits(valueFormat, 0) + NibbleBits(valueFormat, 1) +
275 NibbleBits(valueFormat, 2) + NibbleBits(valueFormat, 3);
276}
277
278le_int16 ValueRecord::getFieldIndex(ValueFormat valueFormat, ValueRecordField field)
279{
374ca955 280 static const le_uint16 beforeMasks[] =
b75a7d8f
A
281 {
282 0x0000,
283 0x0001,
284 0x0003,
285 0x0007,
286 0x000F,
287 0x001F,
288 0x003F,
289 0x007F,
290 0x00FF,
291 0x01FF,
292 0x03FF,
293 0x07FF,
294 0x0FFF,
295 0x1FFF,
296 0x3FFF,
297 0x7FFF,
298 0xFFFF
299 };
300
301 return getFieldCount(valueFormat & beforeMasks[field]);
302}
303
304U_NAMESPACE_END