blob: e592be018954dad07d42179800c0c922e4526c0e [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Sun designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Sun in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
22 * have any questions.
23 *
24 */
25
26/*
27 *
28 * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
29 *
30 */
31
32#include "LETypes.h"
33#include "LEFontInstance.h"
34#include "OpenTypeTables.h"
35#include "ValueRecords.h"
36#include "DeviceTables.h"
37#include "GlyphIterator.h"
38#include "LESwaps.h"
39
40#define Nibble(value, nibble) ((value >> (nibble * 4)) & 0xF)
41#define NibbleBits(value, nibble) (bitsInNibble[Nibble(value, nibble)])
42
43le_int16 ValueRecord::getFieldValue(ValueFormat valueFormat, ValueRecordField field) const
44{
45 le_int16 valueIndex = getFieldIndex(valueFormat, field);
46 le_int16 value = values[valueIndex];
47
48 return SWAPW(value);
49}
50
51le_int16 ValueRecord::getFieldValue(le_int16 index, ValueFormat valueFormat, ValueRecordField field) const
52{
53 le_int16 baseIndex = getFieldCount(valueFormat) * index;
54 le_int16 valueIndex = getFieldIndex(valueFormat, field);
55 le_int16 value = values[baseIndex + valueIndex];
56
57 return SWAPW(value);
58}
59
60void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
61 const LEFontInstance *fontInstance) const
62{
63 float xPlacementAdjustment = 0;
64 float yPlacementAdjustment = 0;
65 float xAdvanceAdjustment = 0;
66 float yAdvanceAdjustment = 0;
67
68 if ((valueFormat & vfbXPlacement) != 0) {
69 le_int16 value = getFieldValue(valueFormat, vrfXPlacement);
70 LEPoint pixels;
71
72 fontInstance->transformFunits(value, 0, pixels);
73
74 xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
75 yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
76 }
77
78 if ((valueFormat & vfbYPlacement) != 0) {
79 le_int16 value = getFieldValue(valueFormat, vrfYPlacement);
80 LEPoint pixels;
81
82 fontInstance->transformFunits(0, value, pixels);
83
84 xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
85 yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
86 }
87
88 if ((valueFormat & vfbXAdvance) != 0) {
89 le_int16 value = getFieldValue(valueFormat, vrfXAdvance);
90 LEPoint pixels;
91
92 fontInstance->transformFunits(value, 0, pixels);
93
94 xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
95 yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
96 }
97
98 if ((valueFormat & vfbYAdvance) != 0) {
99 le_int16 value = getFieldValue(valueFormat, vrfYAdvance);
100 LEPoint pixels;
101
102 fontInstance->transformFunits(0, value, pixels);
103
104 xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
105 yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
106 }
107
108 // FIXME: The device adjustments should really be transformed, but
109 // the only way I know how to do that is to convert them to le_int16 units,
110 // transform them, and then convert them back to pixels. Sigh...
111 if ((valueFormat & vfbAnyDevice) != 0) {
112 le_int16 xppem = (le_int16) fontInstance->getXPixelsPerEm();
113 le_int16 yppem = (le_int16) fontInstance->getYPixelsPerEm();
114
115 if ((valueFormat & vfbXPlaDevice) != 0) {
116 Offset dtOffset = getFieldValue(valueFormat, vrfXPlaDevice);
117
118 if (dtOffset != 0) {
119 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
120 le_int16 xAdj = dt->getAdjustment(xppem);
121
122 xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
123 }
124 }
125
126 if ((valueFormat & vfbYPlaDevice) != 0) {
127 Offset dtOffset = getFieldValue(valueFormat, vrfYPlaDevice);
128
129 if (dtOffset != 0) {
130 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
131 le_int16 yAdj = dt->getAdjustment(yppem);
132
133 yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
134 }
135 }
136
137 if ((valueFormat & vfbXAdvDevice) != 0) {
138 Offset dtOffset = getFieldValue(valueFormat, vrfXAdvDevice);
139
140 if (dtOffset != 0) {
141 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
142 le_int16 xAdj = dt->getAdjustment(xppem);
143
144 xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
145 }
146 }
147
148 if ((valueFormat & vfbYAdvDevice) != 0) {
149 Offset dtOffset = getFieldValue(valueFormat, vrfYAdvDevice);
150
151 if (dtOffset != 0) {
152 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
153 le_int16 yAdj = dt->getAdjustment(yppem);
154
155 yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
156 }
157 }
158 }
159
160 glyphIterator.adjustCurrGlyphPositionAdjustment(
161 xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
162}
163
164void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base,
165 GlyphIterator &glyphIterator, const LEFontInstance *fontInstance) const
166{
167 float xPlacementAdjustment = 0;
168 float yPlacementAdjustment = 0;
169 float xAdvanceAdjustment = 0;
170 float yAdvanceAdjustment = 0;
171
172 if ((valueFormat & vfbXPlacement) != 0) {
173 le_int16 value = getFieldValue(index, valueFormat, vrfXPlacement);
174 LEPoint pixels;
175
176 fontInstance->transformFunits(value, 0, pixels);
177
178 xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
179 yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
180 }
181
182 if ((valueFormat & vfbYPlacement) != 0) {
183 le_int16 value = getFieldValue(index, valueFormat, vrfYPlacement);
184 LEPoint pixels;
185
186 fontInstance->transformFunits(0, value, pixels);
187
188 xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
189 yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
190 }
191
192 if ((valueFormat & vfbXAdvance) != 0) {
193 le_int16 value = getFieldValue(index, valueFormat, vrfXAdvance);
194 LEPoint pixels;
195
196 fontInstance->transformFunits(value, 0, pixels);
197
198 xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
199 yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
200 }
201
202 if ((valueFormat & vfbYAdvance) != 0) {
203 le_int16 value = getFieldValue(index, valueFormat, vrfYAdvance);
204 LEPoint pixels;
205
206 fontInstance->transformFunits(0, value, pixels);
207
208 xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
209 yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
210 }
211
212 // FIXME: The device adjustments should really be transformed, but
213 // the only way I know how to do that is to convert them to le_int16 units,
214 // transform them, and then convert them back to pixels. Sigh...
215 if ((valueFormat & vfbAnyDevice) != 0) {
216 le_int16 xppem = (le_int16) fontInstance->getXPixelsPerEm();
217 le_int16 yppem = (le_int16) fontInstance->getYPixelsPerEm();
218
219 if ((valueFormat & vfbXPlaDevice) != 0) {
220 Offset dtOffset = getFieldValue(index, valueFormat, vrfXPlaDevice);
221
222 if (dtOffset != 0) {
223 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
224 le_int16 xAdj = dt->getAdjustment(xppem);
225
226 xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
227 }
228 }
229
230 if ((valueFormat & vfbYPlaDevice) != 0) {
231 Offset dtOffset = getFieldValue(index, valueFormat, vrfYPlaDevice);
232
233 if (dtOffset != 0) {
234 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
235 le_int16 yAdj = dt->getAdjustment(yppem);
236
237 yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
238 }
239 }
240
241 if ((valueFormat & vfbXAdvDevice) != 0) {
242 Offset dtOffset = getFieldValue(index, valueFormat, vrfXAdvDevice);
243
244 if (dtOffset != 0) {
245 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
246 le_int16 xAdj = dt->getAdjustment(xppem);
247
248 xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
249 }
250 }
251
252 if ((valueFormat & vfbYAdvDevice) != 0) {
253 Offset dtOffset = getFieldValue(index, valueFormat, vrfYAdvDevice);
254
255 if (dtOffset != 0) {
256 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
257 le_int16 yAdj = dt->getAdjustment(yppem);
258
259 yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
260 }
261 }
262 }
263
264 glyphIterator.adjustCurrGlyphPositionAdjustment(
265 xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
266}
267
268le_int16 ValueRecord::getSize(ValueFormat valueFormat)
269{
270 return getFieldCount(valueFormat) * sizeof(le_int16);
271}
272
273le_int16 ValueRecord::getFieldCount(ValueFormat valueFormat)
274{
275 static const le_int16 bitsInNibble[] =
276 {
277 0 + 0 + 0 + 0,
278 0 + 0 + 0 + 1,
279 0 + 0 + 1 + 0,
280 0 + 0 + 1 + 1,
281 0 + 1 + 0 + 0,
282 0 + 1 + 0 + 1,
283 0 + 1 + 1 + 0,
284 0 + 1 + 1 + 1,
285 1 + 0 + 0 + 0,
286 1 + 0 + 0 + 1,
287 1 + 0 + 1 + 0,
288 1 + 0 + 1 + 1,
289 1 + 1 + 0 + 0,
290 1 + 1 + 0 + 1,
291 1 + 1 + 1 + 0,
292 1 + 1 + 1 + 1
293 };
294
295 valueFormat &= ~vfbReserved;
296
297 return NibbleBits(valueFormat, 0) + NibbleBits(valueFormat, 1) +
298 NibbleBits(valueFormat, 2) + NibbleBits(valueFormat, 3);
299}
300
301le_int16 ValueRecord::getFieldIndex(ValueFormat valueFormat, ValueRecordField field)
302{
303 static const le_uint16 beforeMasks[] =
304 {
305 0x0000,
306 0x0001,
307 0x0003,
308 0x0007,
309 0x000F,
310 0x001F,
311 0x003F,
312 0x007F,
313 0x00FF,
314 0x01FF,
315 0x03FF,
316 0x07FF,
317 0x0FFF,
318 0x1FFF,
319 0x3FFF,
320 0x7FFF,
321 0xFFFF
322 };
323
324 return getFieldCount(valueFormat & beforeMasks[field]);
325}