Remove packaging direcotry
[platform/upstream/icu.git] / source / layout / ValueRecords.cpp
1 /*
2  *
3  * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
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"
13 #include "LESwaps.h"
14
15 U_NAMESPACE_BEGIN
16
17 #define Nibble(value, nibble) ((value >> (nibble * 4)) & 0xF)
18 #define NibbleBits(value, nibble) (bitsInNibble[Nibble(value, nibble)])
19
20 le_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
28 le_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
37 void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
38                                  const LEFontInstance *fontInstance) const
39 {
40     float xPlacementAdjustment = 0;
41     float yPlacementAdjustment = 0;
42     float xAdvanceAdjustment   = 0;
43     float yAdvanceAdjustment   = 0;
44
45     if ((valueFormat & vfbXPlacement) != 0) {
46         le_int16 value = getFieldValue(valueFormat, vrfXPlacement);
47         LEPoint pixels;
48
49         fontInstance->transformFunits(value, 0, pixels);
50
51         xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
52         yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
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
61         xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
62         yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
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
71         xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
72         yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
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
81         xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
82         yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
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
99                 xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
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
110                 yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
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
121                 xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
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
132                 yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
133             }
134         }
135     }
136
137     glyphIterator.adjustCurrGlyphPositionAdjustment(
138         xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
139 }
140
141 void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
142                                  const LEFontInstance *fontInstance) const
143 {
144     float xPlacementAdjustment = 0;
145     float yPlacementAdjustment = 0;
146     float xAdvanceAdjustment   = 0;
147     float yAdvanceAdjustment   = 0;
148
149     if ((valueFormat & vfbXPlacement) != 0) {
150         le_int16 value = getFieldValue(index, valueFormat, vrfXPlacement);
151         LEPoint pixels;
152
153         fontInstance->transformFunits(value, 0, pixels);
154
155         xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
156         yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
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
165         xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
166         yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
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
175         xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
176         yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
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
185         xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
186         yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
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
203                 xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
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
214                 yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
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
225                 xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
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
236                 yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
237             }
238         }
239     }
240
241     glyphIterator.adjustCurrGlyphPositionAdjustment(
242         xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
243 }
244
245 le_int16 ValueRecord::getSize(ValueFormat valueFormat)
246 {
247     return getFieldCount(valueFormat) * sizeof(le_int16);
248 }
249
250 le_int16 ValueRecord::getFieldCount(ValueFormat valueFormat)
251 {
252     static const le_int16 bitsInNibble[] =
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
278 le_int16 ValueRecord::getFieldIndex(ValueFormat valueFormat, ValueRecordField field)
279 {
280     static const le_uint16 beforeMasks[] = 
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
304 U_NAMESPACE_END