1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/fontservices/textshaperplugin/IcuSource/layout/ValueRecords.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,304 @@
1.4 +/*
1.5 + *
1.6 + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
1.7 + *
1.8 + */
1.9 +
1.10 +#include "LETypes.h"
1.11 +#include "LEFontInstance.h"
1.12 +#include "OpenTypeTables.h"
1.13 +#include "ValueRecords.h"
1.14 +#include "DeviceTables.h"
1.15 +#include "GlyphIterator.h"
1.16 +#include "LESwaps.h"
1.17 +
1.18 +U_NAMESPACE_BEGIN
1.19 +
1.20 +#define Nibble(value, nibble) ((value >> (nibble * 4)) & 0xF)
1.21 +#define NibbleBits(value, nibble) (bitsInNibble[Nibble(value, nibble)])
1.22 +
1.23 +le_int16 ValueRecord::getFieldValue(ValueFormat valueFormat, ValueRecordField field) const
1.24 +{
1.25 + le_int16 valueIndex = getFieldIndex(valueFormat, field);
1.26 + le_int16 value = values[valueIndex];
1.27 +
1.28 + return SWAPW(value);
1.29 +}
1.30 +
1.31 +le_int16 ValueRecord::getFieldValue(le_int16 index, ValueFormat valueFormat, ValueRecordField field) const
1.32 +{
1.33 + le_int16 baseIndex = getFieldCount(valueFormat) * index;
1.34 + le_int16 valueIndex = getFieldIndex(valueFormat, field);
1.35 + le_int16 value = values[baseIndex + valueIndex];
1.36 +
1.37 + return SWAPW(value);
1.38 +}
1.39 +
1.40 +void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
1.41 + const LEFontInstance *fontInstance) const
1.42 +{
1.43 + float xPlacementAdjustment = 0;
1.44 + float yPlacementAdjustment = 0;
1.45 + float xAdvanceAdjustment = 0;
1.46 + float yAdvanceAdjustment = 0;
1.47 +
1.48 + if ((valueFormat & vfbXPlacement) != 0) {
1.49 + le_int16 value = getFieldValue(valueFormat, vrfXPlacement);
1.50 + LEPoint pixels;
1.51 +
1.52 + fontInstance->transformFunits(value, 0, pixels);
1.53 +
1.54 + xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
1.55 + yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
1.56 + }
1.57 +
1.58 + if ((valueFormat & vfbYPlacement) != 0) {
1.59 + le_int16 value = getFieldValue(valueFormat, vrfYPlacement);
1.60 + LEPoint pixels;
1.61 +
1.62 + fontInstance->transformFunits(0, value, pixels);
1.63 +
1.64 + xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
1.65 + yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
1.66 + }
1.67 +
1.68 + if ((valueFormat & vfbXAdvance) != 0) {
1.69 + le_int16 value = getFieldValue(valueFormat, vrfXAdvance);
1.70 + LEPoint pixels;
1.71 +
1.72 + fontInstance->transformFunits(value, 0, pixels);
1.73 +
1.74 + xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
1.75 + yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
1.76 + }
1.77 +
1.78 + if ((valueFormat & vfbYAdvance) != 0) {
1.79 + le_int16 value = getFieldValue(valueFormat, vrfYAdvance);
1.80 + LEPoint pixels;
1.81 +
1.82 + fontInstance->transformFunits(0, value, pixels);
1.83 +
1.84 + xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
1.85 + yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
1.86 + }
1.87 +
1.88 + // FIXME: The device adjustments should really be transformed, but
1.89 + // the only way I know how to do that is to convert them to le_int16 units,
1.90 + // transform them, and then convert them back to pixels. Sigh...
1.91 + if ((valueFormat & vfbAnyDevice) != 0) {
1.92 + le_int16 xppem = (le_int16) fontInstance->getXPixelsPerEm();
1.93 + le_int16 yppem = (le_int16) fontInstance->getYPixelsPerEm();
1.94 +
1.95 + if ((valueFormat & vfbXPlaDevice) != 0) {
1.96 + Offset dtOffset = getFieldValue(valueFormat, vrfXPlaDevice);
1.97 +
1.98 + if (dtOffset != 0) {
1.99 + const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
1.100 + le_int16 xAdj = dt->getAdjustment(xppem);
1.101 +
1.102 + xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
1.103 + }
1.104 + }
1.105 +
1.106 + if ((valueFormat & vfbYPlaDevice) != 0) {
1.107 + Offset dtOffset = getFieldValue(valueFormat, vrfYPlaDevice);
1.108 +
1.109 + if (dtOffset != 0) {
1.110 + const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
1.111 + le_int16 yAdj = dt->getAdjustment(yppem);
1.112 +
1.113 + yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
1.114 + }
1.115 + }
1.116 +
1.117 + if ((valueFormat & vfbXAdvDevice) != 0) {
1.118 + Offset dtOffset = getFieldValue(valueFormat, vrfXAdvDevice);
1.119 +
1.120 + if (dtOffset != 0) {
1.121 + const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
1.122 + le_int16 xAdj = dt->getAdjustment(xppem);
1.123 +
1.124 + xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
1.125 + }
1.126 + }
1.127 +
1.128 + if ((valueFormat & vfbYAdvDevice) != 0) {
1.129 + Offset dtOffset = getFieldValue(valueFormat, vrfYAdvDevice);
1.130 +
1.131 + if (dtOffset != 0) {
1.132 + const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
1.133 + le_int16 yAdj = dt->getAdjustment(yppem);
1.134 +
1.135 + yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
1.136 + }
1.137 + }
1.138 + }
1.139 +
1.140 + glyphIterator.adjustCurrGlyphPositionAdjustment(
1.141 + xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
1.142 +}
1.143 +
1.144 +void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
1.145 + const LEFontInstance *fontInstance) const
1.146 +{
1.147 + float xPlacementAdjustment = 0;
1.148 + float yPlacementAdjustment = 0;
1.149 + float xAdvanceAdjustment = 0;
1.150 + float yAdvanceAdjustment = 0;
1.151 +
1.152 + if ((valueFormat & vfbXPlacement) != 0) {
1.153 + le_int16 value = getFieldValue(index, valueFormat, vrfXPlacement);
1.154 + LEPoint pixels;
1.155 +
1.156 + fontInstance->transformFunits(value, 0, pixels);
1.157 +
1.158 + xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
1.159 + yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
1.160 + }
1.161 +
1.162 + if ((valueFormat & vfbYPlacement) != 0) {
1.163 + le_int16 value = getFieldValue(index, valueFormat, vrfYPlacement);
1.164 + LEPoint pixels;
1.165 +
1.166 + fontInstance->transformFunits(0, value, pixels);
1.167 +
1.168 + xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
1.169 + yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
1.170 + }
1.171 +
1.172 + if ((valueFormat & vfbXAdvance) != 0) {
1.173 + le_int16 value = getFieldValue(index, valueFormat, vrfXAdvance);
1.174 + LEPoint pixels;
1.175 +
1.176 + fontInstance->transformFunits(value, 0, pixels);
1.177 +
1.178 + xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
1.179 + yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
1.180 + }
1.181 +
1.182 + if ((valueFormat & vfbYAdvance) != 0) {
1.183 + le_int16 value = getFieldValue(index, valueFormat, vrfYAdvance);
1.184 + LEPoint pixels;
1.185 +
1.186 + fontInstance->transformFunits(0, value, pixels);
1.187 +
1.188 + xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
1.189 + yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
1.190 + }
1.191 +
1.192 + // FIXME: The device adjustments should really be transformed, but
1.193 + // the only way I know how to do that is to convert them to le_int16 units,
1.194 + // transform them, and then convert them back to pixels. Sigh...
1.195 + if ((valueFormat & vfbAnyDevice) != 0) {
1.196 + le_int16 xppem = (le_int16) fontInstance->getXPixelsPerEm();
1.197 + le_int16 yppem = (le_int16) fontInstance->getYPixelsPerEm();
1.198 +
1.199 + if ((valueFormat & vfbXPlaDevice) != 0) {
1.200 + Offset dtOffset = getFieldValue(index, valueFormat, vrfXPlaDevice);
1.201 +
1.202 + if (dtOffset != 0) {
1.203 + const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
1.204 + le_int16 xAdj = dt->getAdjustment(xppem);
1.205 +
1.206 + xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
1.207 + }
1.208 + }
1.209 +
1.210 + if ((valueFormat & vfbYPlaDevice) != 0) {
1.211 + Offset dtOffset = getFieldValue(index, valueFormat, vrfYPlaDevice);
1.212 +
1.213 + if (dtOffset != 0) {
1.214 + const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
1.215 + le_int16 yAdj = dt->getAdjustment(yppem);
1.216 +
1.217 + yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
1.218 + }
1.219 + }
1.220 +
1.221 + if ((valueFormat & vfbXAdvDevice) != 0) {
1.222 + Offset dtOffset = getFieldValue(index, valueFormat, vrfXAdvDevice);
1.223 +
1.224 + if (dtOffset != 0) {
1.225 + const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
1.226 + le_int16 xAdj = dt->getAdjustment(xppem);
1.227 +
1.228 + xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
1.229 + }
1.230 + }
1.231 +
1.232 + if ((valueFormat & vfbYAdvDevice) != 0) {
1.233 + Offset dtOffset = getFieldValue(index, valueFormat, vrfYAdvDevice);
1.234 +
1.235 + if (dtOffset != 0) {
1.236 + const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
1.237 + le_int16 yAdj = dt->getAdjustment(yppem);
1.238 +
1.239 + yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
1.240 + }
1.241 + }
1.242 + }
1.243 +
1.244 + glyphIterator.adjustCurrGlyphPositionAdjustment(
1.245 + xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
1.246 +}
1.247 +
1.248 +le_int16 ValueRecord::getSize(ValueFormat valueFormat)
1.249 +{
1.250 + return getFieldCount(valueFormat) * sizeof(le_int16);
1.251 +}
1.252 +
1.253 +le_int16 ValueRecord::getFieldCount(ValueFormat valueFormat)
1.254 +{
1.255 + static const le_int16 bitsInNibble[] =
1.256 + {
1.257 + 0 + 0 + 0 + 0,
1.258 + 0 + 0 + 0 + 1,
1.259 + 0 + 0 + 1 + 0,
1.260 + 0 + 0 + 1 + 1,
1.261 + 0 + 1 + 0 + 0,
1.262 + 0 + 1 + 0 + 1,
1.263 + 0 + 1 + 1 + 0,
1.264 + 0 + 1 + 1 + 1,
1.265 + 1 + 0 + 0 + 0,
1.266 + 1 + 0 + 0 + 1,
1.267 + 1 + 0 + 1 + 0,
1.268 + 1 + 0 + 1 + 1,
1.269 + 1 + 1 + 0 + 0,
1.270 + 1 + 1 + 0 + 1,
1.271 + 1 + 1 + 1 + 0,
1.272 + 1 + 1 + 1 + 1
1.273 + };
1.274 +
1.275 + valueFormat &= ~vfbReserved;
1.276 +
1.277 + return NibbleBits(valueFormat, 0) + NibbleBits(valueFormat, 1) +
1.278 + NibbleBits(valueFormat, 2) + NibbleBits(valueFormat, 3);
1.279 +}
1.280 +
1.281 +le_int16 ValueRecord::getFieldIndex(ValueFormat valueFormat, ValueRecordField field)
1.282 +{
1.283 + static const le_uint16 beforeMasks[] =
1.284 + {
1.285 + 0x0000,
1.286 + 0x0001,
1.287 + 0x0003,
1.288 + 0x0007,
1.289 + 0x000F,
1.290 + 0x001F,
1.291 + 0x003F,
1.292 + 0x007F,
1.293 + 0x00FF,
1.294 + 0x01FF,
1.295 + 0x03FF,
1.296 + 0x07FF,
1.297 + 0x0FFF,
1.298 + 0x1FFF,
1.299 + 0x3FFF,
1.300 + 0x7FFF,
1.301 + 0xFFFF
1.302 + };
1.303 +
1.304 + return getFieldCount(valueFormat & beforeMasks[field]);
1.305 +}
1.306 +
1.307 +U_NAMESPACE_END