os/textandloc/fontservices/textshaperplugin/IcuSource/layout/ValueRecords.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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