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.
sl@0
     1
/*
sl@0
     2
 *
sl@0
     3
 * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
sl@0
     4
 *
sl@0
     5
 */
sl@0
     6
sl@0
     7
#include "LETypes.h"
sl@0
     8
#include "LEFontInstance.h"
sl@0
     9
#include "OpenTypeTables.h"
sl@0
    10
#include "ValueRecords.h"
sl@0
    11
#include "DeviceTables.h"
sl@0
    12
#include "GlyphIterator.h"
sl@0
    13
#include "LESwaps.h"
sl@0
    14
sl@0
    15
U_NAMESPACE_BEGIN
sl@0
    16
sl@0
    17
#define Nibble(value, nibble) ((value >> (nibble * 4)) & 0xF)
sl@0
    18
#define NibbleBits(value, nibble) (bitsInNibble[Nibble(value, nibble)])
sl@0
    19
sl@0
    20
le_int16 ValueRecord::getFieldValue(ValueFormat valueFormat, ValueRecordField field) const
sl@0
    21
{
sl@0
    22
    le_int16 valueIndex = getFieldIndex(valueFormat, field);
sl@0
    23
    le_int16 value = values[valueIndex];
sl@0
    24
sl@0
    25
    return SWAPW(value);
sl@0
    26
}
sl@0
    27
sl@0
    28
le_int16 ValueRecord::getFieldValue(le_int16 index, ValueFormat valueFormat, ValueRecordField field) const
sl@0
    29
{
sl@0
    30
    le_int16 baseIndex = getFieldCount(valueFormat) * index;
sl@0
    31
    le_int16 valueIndex = getFieldIndex(valueFormat, field);
sl@0
    32
    le_int16 value = values[baseIndex + valueIndex];
sl@0
    33
sl@0
    34
    return SWAPW(value);
sl@0
    35
}
sl@0
    36
sl@0
    37
void ValueRecord::adjustPosition(ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
sl@0
    38
                                 const LEFontInstance *fontInstance) const
sl@0
    39
{
sl@0
    40
    float xPlacementAdjustment = 0;
sl@0
    41
    float yPlacementAdjustment = 0;
sl@0
    42
    float xAdvanceAdjustment   = 0;
sl@0
    43
    float yAdvanceAdjustment   = 0;
sl@0
    44
sl@0
    45
    if ((valueFormat & vfbXPlacement) != 0) {
sl@0
    46
        le_int16 value = getFieldValue(valueFormat, vrfXPlacement);
sl@0
    47
        LEPoint pixels;
sl@0
    48
sl@0
    49
        fontInstance->transformFunits(value, 0, pixels);
sl@0
    50
sl@0
    51
        xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
sl@0
    52
        yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
sl@0
    53
    }
sl@0
    54
sl@0
    55
    if ((valueFormat & vfbYPlacement) != 0) {
sl@0
    56
        le_int16 value = getFieldValue(valueFormat, vrfYPlacement);
sl@0
    57
        LEPoint pixels;
sl@0
    58
sl@0
    59
        fontInstance->transformFunits(0, value, pixels);
sl@0
    60
sl@0
    61
        xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
sl@0
    62
        yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
sl@0
    63
    }
sl@0
    64
sl@0
    65
    if ((valueFormat & vfbXAdvance) != 0) {
sl@0
    66
        le_int16 value = getFieldValue(valueFormat, vrfXAdvance);
sl@0
    67
        LEPoint pixels;
sl@0
    68
sl@0
    69
        fontInstance->transformFunits(value, 0, pixels);
sl@0
    70
sl@0
    71
        xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
sl@0
    72
        yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
sl@0
    73
    }
sl@0
    74
sl@0
    75
    if ((valueFormat & vfbYAdvance) != 0) {
sl@0
    76
        le_int16 value = getFieldValue(valueFormat, vrfYAdvance);
sl@0
    77
        LEPoint pixels;
sl@0
    78
sl@0
    79
        fontInstance->transformFunits(0, value, pixels);
sl@0
    80
sl@0
    81
        xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
sl@0
    82
        yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
sl@0
    83
    }
sl@0
    84
sl@0
    85
    // FIXME: The device adjustments should really be transformed, but
sl@0
    86
    // the only way I know how to do that is to convert them to le_int16 units,
sl@0
    87
    // transform them, and then convert them back to pixels. Sigh...
sl@0
    88
    if ((valueFormat & vfbAnyDevice) != 0) {
sl@0
    89
        le_int16 xppem = (le_int16) fontInstance->getXPixelsPerEm();
sl@0
    90
        le_int16 yppem = (le_int16) fontInstance->getYPixelsPerEm();
sl@0
    91
sl@0
    92
        if ((valueFormat & vfbXPlaDevice) != 0) {
sl@0
    93
            Offset dtOffset = getFieldValue(valueFormat, vrfXPlaDevice);
sl@0
    94
sl@0
    95
            if (dtOffset != 0) {
sl@0
    96
                const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
sl@0
    97
                le_int16 xAdj = dt->getAdjustment(xppem);
sl@0
    98
sl@0
    99
                xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
sl@0
   100
            }
sl@0
   101
        }
sl@0
   102
sl@0
   103
        if ((valueFormat & vfbYPlaDevice) != 0) {
sl@0
   104
            Offset dtOffset = getFieldValue(valueFormat, vrfYPlaDevice);
sl@0
   105
sl@0
   106
            if (dtOffset != 0) {
sl@0
   107
                const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
sl@0
   108
                le_int16 yAdj = dt->getAdjustment(yppem);
sl@0
   109
sl@0
   110
                yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
sl@0
   111
            }
sl@0
   112
        }
sl@0
   113
sl@0
   114
        if ((valueFormat & vfbXAdvDevice) != 0) {
sl@0
   115
            Offset dtOffset = getFieldValue(valueFormat, vrfXAdvDevice);
sl@0
   116
sl@0
   117
            if (dtOffset != 0) {
sl@0
   118
                const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
sl@0
   119
                le_int16 xAdj = dt->getAdjustment(xppem);
sl@0
   120
sl@0
   121
                xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
sl@0
   122
            }
sl@0
   123
        }
sl@0
   124
sl@0
   125
        if ((valueFormat & vfbYAdvDevice) != 0) {
sl@0
   126
            Offset dtOffset = getFieldValue(valueFormat, vrfYAdvDevice);
sl@0
   127
sl@0
   128
            if (dtOffset != 0) {
sl@0
   129
                const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
sl@0
   130
                le_int16 yAdj = dt->getAdjustment(yppem);
sl@0
   131
sl@0
   132
                yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
sl@0
   133
            }
sl@0
   134
        }
sl@0
   135
    }
sl@0
   136
sl@0
   137
    glyphIterator.adjustCurrGlyphPositionAdjustment(
sl@0
   138
        xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
sl@0
   139
}
sl@0
   140
sl@0
   141
void ValueRecord::adjustPosition(le_int16 index, ValueFormat valueFormat, const char *base, GlyphIterator &glyphIterator,
sl@0
   142
                                 const LEFontInstance *fontInstance) const
sl@0
   143
{
sl@0
   144
    float xPlacementAdjustment = 0;
sl@0
   145
    float yPlacementAdjustment = 0;
sl@0
   146
    float xAdvanceAdjustment   = 0;
sl@0
   147
    float yAdvanceAdjustment   = 0;
sl@0
   148
sl@0
   149
    if ((valueFormat & vfbXPlacement) != 0) {
sl@0
   150
        le_int16 value = getFieldValue(index, valueFormat, vrfXPlacement);
sl@0
   151
        LEPoint pixels;
sl@0
   152
sl@0
   153
        fontInstance->transformFunits(value, 0, pixels);
sl@0
   154
sl@0
   155
        xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
sl@0
   156
        yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
sl@0
   157
    }
sl@0
   158
sl@0
   159
    if ((valueFormat & vfbYPlacement) != 0) {
sl@0
   160
        le_int16 value = getFieldValue(index, valueFormat, vrfYPlacement);
sl@0
   161
        LEPoint pixels;
sl@0
   162
sl@0
   163
        fontInstance->transformFunits(0, value, pixels);
sl@0
   164
sl@0
   165
        xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
sl@0
   166
        yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
sl@0
   167
    }
sl@0
   168
sl@0
   169
    if ((valueFormat & vfbXAdvance) != 0) {
sl@0
   170
        le_int16 value = getFieldValue(index, valueFormat, vrfXAdvance);
sl@0
   171
        LEPoint pixels;
sl@0
   172
sl@0
   173
        fontInstance->transformFunits(value, 0, pixels);
sl@0
   174
sl@0
   175
        xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
sl@0
   176
        yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
sl@0
   177
    }
sl@0
   178
sl@0
   179
    if ((valueFormat & vfbYAdvance) != 0) {
sl@0
   180
        le_int16 value = getFieldValue(index, valueFormat, vrfYAdvance);
sl@0
   181
        LEPoint pixels;
sl@0
   182
sl@0
   183
        fontInstance->transformFunits(0, value, pixels);
sl@0
   184
sl@0
   185
        xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
sl@0
   186
        yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
sl@0
   187
    }
sl@0
   188
sl@0
   189
    // FIXME: The device adjustments should really be transformed, but
sl@0
   190
    // the only way I know how to do that is to convert them to le_int16 units,
sl@0
   191
    // transform them, and then convert them back to pixels. Sigh...
sl@0
   192
    if ((valueFormat & vfbAnyDevice) != 0) {
sl@0
   193
        le_int16 xppem = (le_int16) fontInstance->getXPixelsPerEm();
sl@0
   194
        le_int16 yppem = (le_int16) fontInstance->getYPixelsPerEm();
sl@0
   195
sl@0
   196
        if ((valueFormat & vfbXPlaDevice) != 0) {
sl@0
   197
            Offset dtOffset = getFieldValue(index, valueFormat, vrfXPlaDevice);
sl@0
   198
sl@0
   199
            if (dtOffset != 0) {
sl@0
   200
                const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
sl@0
   201
                le_int16 xAdj = dt->getAdjustment(xppem);
sl@0
   202
sl@0
   203
                xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
sl@0
   204
            }
sl@0
   205
        }
sl@0
   206
sl@0
   207
        if ((valueFormat & vfbYPlaDevice) != 0) {
sl@0
   208
            Offset dtOffset = getFieldValue(index, valueFormat, vrfYPlaDevice);
sl@0
   209
sl@0
   210
            if (dtOffset != 0) {
sl@0
   211
                const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
sl@0
   212
                le_int16 yAdj = dt->getAdjustment(yppem);
sl@0
   213
sl@0
   214
                yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
sl@0
   215
            }
sl@0
   216
        }
sl@0
   217
sl@0
   218
        if ((valueFormat & vfbXAdvDevice) != 0) {
sl@0
   219
            Offset dtOffset = getFieldValue(index, valueFormat, vrfXAdvDevice);
sl@0
   220
sl@0
   221
            if (dtOffset != 0) {
sl@0
   222
                const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
sl@0
   223
                le_int16 xAdj = dt->getAdjustment(xppem);
sl@0
   224
sl@0
   225
                xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
sl@0
   226
            }
sl@0
   227
        }
sl@0
   228
sl@0
   229
        if ((valueFormat & vfbYAdvDevice) != 0) {
sl@0
   230
            Offset dtOffset = getFieldValue(index, valueFormat, vrfYAdvDevice);
sl@0
   231
sl@0
   232
            if (dtOffset != 0) {
sl@0
   233
                const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
sl@0
   234
                le_int16 yAdj = dt->getAdjustment(yppem);
sl@0
   235
sl@0
   236
                yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
sl@0
   237
            }
sl@0
   238
        }
sl@0
   239
    }
sl@0
   240
sl@0
   241
    glyphIterator.adjustCurrGlyphPositionAdjustment(
sl@0
   242
        xPlacementAdjustment, yPlacementAdjustment, xAdvanceAdjustment, yAdvanceAdjustment);
sl@0
   243
}
sl@0
   244
sl@0
   245
le_int16 ValueRecord::getSize(ValueFormat valueFormat)
sl@0
   246
{
sl@0
   247
    return getFieldCount(valueFormat) * sizeof(le_int16);
sl@0
   248
}
sl@0
   249
sl@0
   250
le_int16 ValueRecord::getFieldCount(ValueFormat valueFormat)
sl@0
   251
{
sl@0
   252
    static const le_int16 bitsInNibble[] =
sl@0
   253
    {
sl@0
   254
        0 + 0 + 0 + 0,
sl@0
   255
        0 + 0 + 0 + 1,
sl@0
   256
        0 + 0 + 1 + 0,
sl@0
   257
        0 + 0 + 1 + 1,
sl@0
   258
        0 + 1 + 0 + 0,
sl@0
   259
        0 + 1 + 0 + 1,
sl@0
   260
        0 + 1 + 1 + 0,
sl@0
   261
        0 + 1 + 1 + 1,
sl@0
   262
        1 + 0 + 0 + 0,
sl@0
   263
        1 + 0 + 0 + 1,
sl@0
   264
        1 + 0 + 1 + 0,
sl@0
   265
        1 + 0 + 1 + 1,
sl@0
   266
        1 + 1 + 0 + 0,
sl@0
   267
        1 + 1 + 0 + 1,
sl@0
   268
        1 + 1 + 1 + 0,
sl@0
   269
        1 + 1 + 1 + 1
sl@0
   270
    };
sl@0
   271
sl@0
   272
    valueFormat &= ~vfbReserved;
sl@0
   273
sl@0
   274
    return NibbleBits(valueFormat, 0) + NibbleBits(valueFormat, 1) +
sl@0
   275
           NibbleBits(valueFormat, 2) + NibbleBits(valueFormat, 3);
sl@0
   276
}
sl@0
   277
sl@0
   278
le_int16 ValueRecord::getFieldIndex(ValueFormat valueFormat, ValueRecordField field)
sl@0
   279
{
sl@0
   280
    static const le_uint16 beforeMasks[] = 
sl@0
   281
    {
sl@0
   282
        0x0000,
sl@0
   283
        0x0001,
sl@0
   284
        0x0003,
sl@0
   285
        0x0007,
sl@0
   286
        0x000F,
sl@0
   287
        0x001F,
sl@0
   288
        0x003F,
sl@0
   289
        0x007F,
sl@0
   290
        0x00FF,
sl@0
   291
        0x01FF,
sl@0
   292
        0x03FF,
sl@0
   293
        0x07FF,
sl@0
   294
        0x0FFF,
sl@0
   295
        0x1FFF,
sl@0
   296
        0x3FFF,
sl@0
   297
        0x7FFF,
sl@0
   298
        0xFFFF
sl@0
   299
    };
sl@0
   300
sl@0
   301
    return getFieldCount(valueFormat & beforeMasks[field]);
sl@0
   302
}
sl@0
   303
sl@0
   304
U_NAMESPACE_END