]>
git.saurik.com Git - apple/icu.git/blob - icuSources/layout/ValueRecords.cpp
3 * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
8 #include "LEFontInstance.h"
9 #include "OpenTypeTables.h"
10 #include "ValueRecords.h"
11 #include "DeviceTables.h"
12 #include "GlyphIterator.h"
13 #include "GlyphPositionAdjustments.h"
18 #define Nibble(value, nibble) ((value >> (nibble * 4)) & 0xF)
19 #define NibbleBits(value, nibble) (bitsInNibble[Nibble(value, nibble)])
21 le_int16
ValueRecord::getFieldValue(ValueFormat valueFormat
, ValueRecordField field
) const
23 le_int16 valueIndex
= getFieldIndex(valueFormat
, field
);
24 le_int16 value
= values
[valueIndex
];
29 le_int16
ValueRecord::getFieldValue(le_int16 index
, ValueFormat valueFormat
, ValueRecordField field
) const
31 le_int16 baseIndex
= getFieldCount(valueFormat
) * index
;
32 le_int16 valueIndex
= getFieldIndex(valueFormat
, field
);
33 le_int16 value
= values
[baseIndex
+ valueIndex
];
38 void ValueRecord::adjustPosition(ValueFormat valueFormat
, const char *base
, GlyphPositionAdjustment
&positionAdjustment
,
39 const LEFontInstance
*fontInstance
) const
41 if ((valueFormat
& vfbXPlacement
) != 0) {
42 le_int16 value
= getFieldValue(valueFormat
, vrfXPlacement
);
45 fontInstance
->transformFunits(value
, 0, pixels
);
47 positionAdjustment
.adjustXPlacement(fontInstance
->xPixelsToUnits(pixels
.fX
));
48 positionAdjustment
.adjustYPlacement(fontInstance
->yPixelsToUnits(pixels
.fY
));
51 if ((valueFormat
& vfbYPlacement
) != 0) {
52 le_int16 value
= getFieldValue(valueFormat
, vrfYPlacement
);
55 fontInstance
->transformFunits(0, value
, pixels
);
57 positionAdjustment
.adjustXPlacement(fontInstance
->xPixelsToUnits(pixels
.fX
));
58 positionAdjustment
.adjustYPlacement(fontInstance
->yPixelsToUnits(pixels
.fY
));
61 if ((valueFormat
& vfbXAdvance
) != 0) {
62 le_int16 value
= getFieldValue(valueFormat
, vrfXAdvance
);
65 fontInstance
->transformFunits(value
, 0, pixels
);
67 positionAdjustment
.adjustXAdvance(fontInstance
->xPixelsToUnits(pixels
.fX
));
68 positionAdjustment
.adjustYAdvance(fontInstance
->yPixelsToUnits(pixels
.fY
));
71 if ((valueFormat
& vfbYAdvance
) != 0) {
72 le_int16 value
= getFieldValue(valueFormat
, vrfYAdvance
);
75 fontInstance
->transformFunits(0, value
, pixels
);
77 positionAdjustment
.adjustXAdvance(fontInstance
->xPixelsToUnits(pixels
.fX
));
78 positionAdjustment
.adjustYAdvance(fontInstance
->yPixelsToUnits(pixels
.fY
));
81 // FIXME: The device adjustments should really be transformed, but
82 // the only way I know how to do that is to convert them to le_int16 units,
83 // transform them, and then convert them back to pixels. Sigh...
84 if ((valueFormat
& vfbAnyDevice
) != 0) {
85 le_int16 xppem
= (le_int16
) fontInstance
->getXPixelsPerEm();
86 le_int16 yppem
= (le_int16
) fontInstance
->getYPixelsPerEm();
88 if ((valueFormat
& vfbXPlaDevice
) != 0) {
89 Offset dtOffset
= getFieldValue(valueFormat
, vrfXPlaDevice
);
92 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
93 le_int16 xAdj
= dt
->getAdjustment(xppem
);
95 positionAdjustment
.adjustXPlacement(fontInstance
->xPixelsToUnits(xAdj
));
99 if ((valueFormat
& vfbYPlaDevice
) != 0) {
100 Offset dtOffset
= getFieldValue(valueFormat
, vrfYPlaDevice
);
103 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
104 le_int16 yAdj
= dt
->getAdjustment(yppem
);
106 positionAdjustment
.adjustYPlacement(fontInstance
->yPixelsToUnits(yAdj
));
110 if ((valueFormat
& vfbXAdvDevice
) != 0) {
111 Offset dtOffset
= getFieldValue(valueFormat
, vrfXAdvDevice
);
114 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
115 le_int16 xAdj
= dt
->getAdjustment(xppem
);
117 positionAdjustment
.adjustXAdvance(fontInstance
->xPixelsToUnits(xAdj
));
121 if ((valueFormat
& vfbYAdvDevice
) != 0) {
122 Offset dtOffset
= getFieldValue(valueFormat
, vrfYAdvDevice
);
125 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
126 le_int16 yAdj
= dt
->getAdjustment(yppem
);
128 positionAdjustment
.adjustYAdvance(fontInstance
->yPixelsToUnits(yAdj
));
134 void ValueRecord::adjustPosition(le_int16 index
, ValueFormat valueFormat
, const char *base
, GlyphPositionAdjustment
&positionAdjustment
,
135 const LEFontInstance
*fontInstance
) const
137 if ((valueFormat
& vfbXPlacement
) != 0) {
138 le_int16 value
= getFieldValue(index
, valueFormat
, vrfXPlacement
);
141 fontInstance
->transformFunits(value
, 0, pixels
);
143 positionAdjustment
.adjustXPlacement(fontInstance
->xPixelsToUnits(pixels
.fX
));
144 positionAdjustment
.adjustYPlacement(fontInstance
->yPixelsToUnits(pixels
.fY
));
147 if ((valueFormat
& vfbYPlacement
) != 0) {
148 le_int16 value
= getFieldValue(index
, valueFormat
, vrfYPlacement
);
151 fontInstance
->transformFunits(0, value
, pixels
);
153 positionAdjustment
.adjustXPlacement(fontInstance
->xPixelsToUnits(pixels
.fX
));
154 positionAdjustment
.adjustYPlacement(fontInstance
->yPixelsToUnits(pixels
.fY
));
157 if ((valueFormat
& vfbXAdvance
) != 0) {
158 le_int16 value
= getFieldValue(index
, valueFormat
, vrfXAdvance
);
161 fontInstance
->transformFunits(value
, 0, pixels
);
163 positionAdjustment
.adjustXAdvance(fontInstance
->xPixelsToUnits(pixels
.fX
));
164 positionAdjustment
.adjustYAdvance(fontInstance
->yPixelsToUnits(pixels
.fY
));
167 if ((valueFormat
& vfbYAdvance
) != 0) {
168 le_int16 value
= getFieldValue(index
, valueFormat
, vrfYAdvance
);
171 fontInstance
->transformFunits(0, value
, pixels
);
173 positionAdjustment
.adjustXAdvance(fontInstance
->xPixelsToUnits(pixels
.fX
));
174 positionAdjustment
.adjustYAdvance(fontInstance
->yPixelsToUnits(pixels
.fY
));
177 // FIXME: The device adjustments should really be transformed, but
178 // the only way I know how to do that is to convert them to le_int16 units,
179 // transform them, and then convert them back to pixels. Sigh...
180 if ((valueFormat
& vfbAnyDevice
) != 0) {
181 le_int16 xppem
= (le_int16
) fontInstance
->getXPixelsPerEm();
182 le_int16 yppem
= (le_int16
) fontInstance
->getYPixelsPerEm();
184 if ((valueFormat
& vfbXPlaDevice
) != 0) {
185 Offset dtOffset
= getFieldValue(index
, valueFormat
, vrfXPlaDevice
);
188 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
189 le_int16 xAdj
= dt
->getAdjustment(xppem
);
191 positionAdjustment
.adjustXAdvance(fontInstance
->xPixelsToUnits(xAdj
));
195 if ((valueFormat
& vfbYPlaDevice
) != 0) {
196 Offset dtOffset
= getFieldValue(index
, valueFormat
, vrfYPlaDevice
);
199 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
200 le_int16 yAdj
= dt
->getAdjustment(yppem
);
202 positionAdjustment
.adjustYAdvance(fontInstance
->yPixelsToUnits(yAdj
));
206 if ((valueFormat
& vfbXAdvDevice
) != 0) {
207 Offset dtOffset
= getFieldValue(index
, valueFormat
, vrfXAdvDevice
);
210 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
211 le_int16 xAdj
= dt
->getAdjustment(xppem
);
213 positionAdjustment
.adjustXAdvance(fontInstance
->xPixelsToUnits(xAdj
));
217 if ((valueFormat
& vfbYAdvDevice
) != 0) {
218 Offset dtOffset
= getFieldValue(index
, valueFormat
, vrfYAdvDevice
);
221 const DeviceTable
*dt
= (const DeviceTable
*) (base
+ dtOffset
);
222 le_int16 yAdj
= dt
->getAdjustment(yppem
);
224 positionAdjustment
.adjustYAdvance(fontInstance
->yPixelsToUnits(yAdj
));
230 le_int16
ValueRecord::getSize(ValueFormat valueFormat
)
232 return getFieldCount(valueFormat
) * sizeof(le_int16
);
235 le_int16
ValueRecord::getFieldCount(ValueFormat valueFormat
)
237 static const le_int16 bitsInNibble
[] =
257 valueFormat
&= ~vfbReserved
;
259 return NibbleBits(valueFormat
, 0) + NibbleBits(valueFormat
, 1) +
260 NibbleBits(valueFormat
, 2) + NibbleBits(valueFormat
, 3);
263 le_int16
ValueRecord::getFieldIndex(ValueFormat valueFormat
, ValueRecordField field
)
265 static const le_uint16 beforeMasks
[] =
286 return getFieldCount(valueFormat
& beforeMasks
[field
]);