• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getFieldValue(ValueFormat valueFormat,ValueRecordField field) const20 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 
getFieldValue(le_int16 index,ValueFormat valueFormat,ValueRecordField field) const28 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 
adjustPosition(ValueFormat valueFormat,const char * base,GlyphIterator & glyphIterator,const LEFontInstance * fontInstance) const37 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 
adjustPosition(le_int16 index,ValueFormat valueFormat,const char * base,GlyphIterator & glyphIterator,const LEFontInstance * fontInstance) const141 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 
getSize(ValueFormat valueFormat)245 le_int16 ValueRecord::getSize(ValueFormat valueFormat)
246 {
247     return getFieldCount(valueFormat) * sizeof(le_int16);
248 }
249 
getFieldCount(ValueFormat valueFormat)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 
getFieldIndex(ValueFormat valueFormat,ValueRecordField field)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
305