os/textandloc/fontservices/textshaperplugin/IcuSource/layout/IndicRearrangementProcessor.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
 *
sl@0
     3
 * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
sl@0
     4
 *
sl@0
     5
 */
sl@0
     6
sl@0
     7
#include "LETypes.h"
sl@0
     8
#include "MorphTables.h"
sl@0
     9
#include "StateTables.h"
sl@0
    10
#include "MorphStateTables.h"
sl@0
    11
#include "SubtableProcessor.h"
sl@0
    12
#include "StateTableProcessor.h"
sl@0
    13
#include "IndicRearrangementProcessor.h"
sl@0
    14
#include "LEGlyphStorage.h"
sl@0
    15
#include "LESwaps.h"
sl@0
    16
sl@0
    17
U_NAMESPACE_BEGIN
sl@0
    18
sl@0
    19
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor)
sl@0
    20
sl@0
    21
IndicRearrangementProcessor::IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader)
sl@0
    22
  : StateTableProcessor(morphSubtableHeader)
sl@0
    23
{
sl@0
    24
    indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader *) morphSubtableHeader;
sl@0
    25
    entryTable = (const IndicRearrangementStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
sl@0
    26
}
sl@0
    27
sl@0
    28
IndicRearrangementProcessor::~IndicRearrangementProcessor()
sl@0
    29
{
sl@0
    30
}
sl@0
    31
sl@0
    32
void IndicRearrangementProcessor::beginStateTable()
sl@0
    33
{
sl@0
    34
    firstGlyph = 0;
sl@0
    35
    lastGlyph = 0;
sl@0
    36
}
sl@0
    37
sl@0
    38
ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
sl@0
    39
{
sl@0
    40
    const IndicRearrangementStateEntry *entry = &entryTable[index];
sl@0
    41
    ByteOffset newState = SWAPW(entry->newStateOffset);
sl@0
    42
    IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
sl@0
    43
sl@0
    44
    if (flags & irfMarkFirst) {
sl@0
    45
        firstGlyph = currGlyph;
sl@0
    46
    }
sl@0
    47
sl@0
    48
    if (flags & irfMarkLast) {
sl@0
    49
        lastGlyph = currGlyph;
sl@0
    50
    }
sl@0
    51
sl@0
    52
    doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask));
sl@0
    53
sl@0
    54
    if (!(flags & irfDontAdvance)) {
sl@0
    55
        // XXX: Should handle reverse too...
sl@0
    56
        currGlyph += 1;
sl@0
    57
    }
sl@0
    58
sl@0
    59
    return newState;
sl@0
    60
}
sl@0
    61
sl@0
    62
void IndicRearrangementProcessor::endStateTable()
sl@0
    63
{
sl@0
    64
}
sl@0
    65
sl@0
    66
void IndicRearrangementProcessor::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const
sl@0
    67
{
sl@0
    68
    LEGlyphID a, b, c, d;
sl@0
    69
    le_int32 ia, ib, ic, id, ix, x;
sl@0
    70
    LEErrorCode success = LE_NO_ERROR;
sl@0
    71
sl@0
    72
    switch(verb)
sl@0
    73
    {
sl@0
    74
    case irvNoAction:
sl@0
    75
        break;
sl@0
    76
sl@0
    77
    case irvxA:
sl@0
    78
        a = glyphStorage[firstGlyph];
sl@0
    79
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
    80
        x = firstGlyph + 1;
sl@0
    81
sl@0
    82
        while (x <= lastGlyph) {
sl@0
    83
            glyphStorage[x - 1] = glyphStorage[x];
sl@0
    84
            ix = glyphStorage.getCharIndex(x, success);
sl@0
    85
            glyphStorage.setCharIndex(x - 1, ix, success);
sl@0
    86
            x += 1;
sl@0
    87
        }
sl@0
    88
sl@0
    89
        glyphStorage[lastGlyph] = a;
sl@0
    90
        glyphStorage.setCharIndex(lastGlyph, ia, success);
sl@0
    91
        break;
sl@0
    92
sl@0
    93
    case irvDx:
sl@0
    94
        d = glyphStorage[lastGlyph];
sl@0
    95
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
    96
        x = lastGlyph - 1;
sl@0
    97
sl@0
    98
        while (x >= firstGlyph) {
sl@0
    99
            glyphStorage[x + 1] = glyphStorage[x];
sl@0
   100
            ix = glyphStorage.getCharIndex(x, success);
sl@0
   101
            glyphStorage.setCharIndex(x + 1, ix, success);
sl@0
   102
            x -= 1;
sl@0
   103
        }
sl@0
   104
sl@0
   105
        glyphStorage[firstGlyph] = d;
sl@0
   106
        glyphStorage.setCharIndex(firstGlyph, id, success);
sl@0
   107
        break;
sl@0
   108
sl@0
   109
    case irvDxA:
sl@0
   110
        a = glyphStorage[firstGlyph];
sl@0
   111
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   112
        id = glyphStorage.getCharIndex(lastGlyph,  success);
sl@0
   113
sl@0
   114
        glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
sl@0
   115
        glyphStorage[lastGlyph] = a;
sl@0
   116
sl@0
   117
        glyphStorage.setCharIndex(firstGlyph, id, success);
sl@0
   118
        glyphStorage.setCharIndex(lastGlyph,  ia, success);
sl@0
   119
        break;
sl@0
   120
        
sl@0
   121
    case irvxAB:
sl@0
   122
        a = glyphStorage[firstGlyph];
sl@0
   123
        b = glyphStorage[firstGlyph + 1];
sl@0
   124
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   125
        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
sl@0
   126
        x = firstGlyph + 2;
sl@0
   127
sl@0
   128
        while (x <= lastGlyph) {
sl@0
   129
            glyphStorage[x - 2] = glyphStorage[x];
sl@0
   130
            ix = glyphStorage.getCharIndex(x, success);
sl@0
   131
            glyphStorage.setCharIndex(x - 2, ix, success);
sl@0
   132
            x += 1;
sl@0
   133
        }
sl@0
   134
sl@0
   135
        glyphStorage[lastGlyph - 1] = a;
sl@0
   136
        glyphStorage[lastGlyph] = b;
sl@0
   137
sl@0
   138
        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
sl@0
   139
        glyphStorage.setCharIndex(lastGlyph, ib, success);
sl@0
   140
        break;
sl@0
   141
sl@0
   142
    case irvxBA:
sl@0
   143
        a = glyphStorage[firstGlyph];
sl@0
   144
        b = glyphStorage[firstGlyph + 1];
sl@0
   145
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   146
        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
sl@0
   147
        x = firstGlyph + 2;
sl@0
   148
sl@0
   149
        while (x <= lastGlyph) {
sl@0
   150
            glyphStorage[x - 2] = glyphStorage[x];
sl@0
   151
            ix = glyphStorage.getCharIndex(x, success);
sl@0
   152
            glyphStorage.setCharIndex(x - 2, ix, success);
sl@0
   153
            x += 1;
sl@0
   154
        }
sl@0
   155
sl@0
   156
        glyphStorage[lastGlyph - 1] = b;
sl@0
   157
        glyphStorage[lastGlyph] = a;
sl@0
   158
sl@0
   159
        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
sl@0
   160
        glyphStorage.setCharIndex(lastGlyph, ia, success);
sl@0
   161
        break;
sl@0
   162
sl@0
   163
    case irvCDx:
sl@0
   164
        c = glyphStorage[lastGlyph - 1];
sl@0
   165
        d = glyphStorage[lastGlyph];
sl@0
   166
        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
sl@0
   167
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
   168
        x = lastGlyph - 2;
sl@0
   169
sl@0
   170
        while (x >= firstGlyph) {
sl@0
   171
            glyphStorage[x + 2] = glyphStorage[x];
sl@0
   172
            ix = glyphStorage.getCharIndex(x, success);
sl@0
   173
            glyphStorage.setCharIndex(x + 2, ix, success);
sl@0
   174
            x -= 1;
sl@0
   175
        }
sl@0
   176
        
sl@0
   177
        glyphStorage[firstGlyph] = c;
sl@0
   178
        glyphStorage[firstGlyph + 1] = d;
sl@0
   179
sl@0
   180
        glyphStorage.setCharIndex(firstGlyph, ic, success);
sl@0
   181
        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
sl@0
   182
        break; 
sl@0
   183
sl@0
   184
    case irvDCx:
sl@0
   185
        c = glyphStorage[lastGlyph - 1];
sl@0
   186
        d = glyphStorage[lastGlyph];
sl@0
   187
        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
sl@0
   188
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
   189
        x = lastGlyph - 2;
sl@0
   190
sl@0
   191
        while (x >= firstGlyph) {
sl@0
   192
            glyphStorage[x + 2] = glyphStorage[x];
sl@0
   193
            ix = glyphStorage.getCharIndex(x, success);
sl@0
   194
            glyphStorage.setCharIndex(x + 2, ix, success);
sl@0
   195
            x -= 1;
sl@0
   196
        }
sl@0
   197
        
sl@0
   198
        glyphStorage[firstGlyph] = d;
sl@0
   199
        glyphStorage[firstGlyph + 1] = c;
sl@0
   200
sl@0
   201
        glyphStorage.setCharIndex(firstGlyph, id, success);
sl@0
   202
        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
sl@0
   203
        break; 
sl@0
   204
sl@0
   205
    case irvCDxA:
sl@0
   206
        a = glyphStorage[firstGlyph];
sl@0
   207
        c = glyphStorage[lastGlyph - 1];
sl@0
   208
        d = glyphStorage[lastGlyph];
sl@0
   209
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   210
        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
sl@0
   211
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
   212
        x = lastGlyph - 2;
sl@0
   213
sl@0
   214
        while (x > firstGlyph) {
sl@0
   215
            glyphStorage[x + 1] = glyphStorage[x];
sl@0
   216
            ix = glyphStorage.getCharIndex(x, success);
sl@0
   217
            glyphStorage.setCharIndex(x + 1, ix, success);
sl@0
   218
            x -= 1;
sl@0
   219
        }
sl@0
   220
        
sl@0
   221
        glyphStorage[firstGlyph] = c;
sl@0
   222
        glyphStorage[firstGlyph + 1] = d;
sl@0
   223
        glyphStorage[lastGlyph] = a;
sl@0
   224
sl@0
   225
        glyphStorage.setCharIndex(firstGlyph, ic, success);
sl@0
   226
        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
sl@0
   227
        glyphStorage.setCharIndex(lastGlyph, ia, success);
sl@0
   228
        break; 
sl@0
   229
sl@0
   230
    case irvDCxA:
sl@0
   231
        a = glyphStorage[firstGlyph];
sl@0
   232
        c = glyphStorage[lastGlyph - 1];
sl@0
   233
        d = glyphStorage[lastGlyph];
sl@0
   234
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   235
        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
sl@0
   236
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
   237
        x = lastGlyph - 2;
sl@0
   238
sl@0
   239
        while (x > firstGlyph) {
sl@0
   240
            glyphStorage[x + 1] = glyphStorage[x];
sl@0
   241
            ix = glyphStorage.getCharIndex(x, success);
sl@0
   242
            glyphStorage.setCharIndex(x + 1, ix, success);
sl@0
   243
            x -= 1;
sl@0
   244
        }
sl@0
   245
        
sl@0
   246
        glyphStorage[firstGlyph] = d;
sl@0
   247
        glyphStorage[firstGlyph + 1] = c;
sl@0
   248
        glyphStorage[lastGlyph] = a;
sl@0
   249
sl@0
   250
        glyphStorage.setCharIndex(firstGlyph, id, success);
sl@0
   251
        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
sl@0
   252
        glyphStorage.setCharIndex(lastGlyph, ia, success);
sl@0
   253
        break; 
sl@0
   254
sl@0
   255
    case irvDxAB:
sl@0
   256
        a = glyphStorage[firstGlyph];
sl@0
   257
        b = glyphStorage[firstGlyph + 1];
sl@0
   258
        d = glyphStorage[lastGlyph];
sl@0
   259
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   260
        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
sl@0
   261
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
   262
        x = firstGlyph + 2;
sl@0
   263
sl@0
   264
        while (x < lastGlyph) {
sl@0
   265
            glyphStorage[x - 2] = glyphStorage[x];
sl@0
   266
            ix = glyphStorage.getCharIndex(x, success);
sl@0
   267
            glyphStorage.setCharIndex(x - 2, ix, success);
sl@0
   268
            x += 1;
sl@0
   269
        }
sl@0
   270
sl@0
   271
        glyphStorage[firstGlyph] = d;
sl@0
   272
        glyphStorage[lastGlyph - 1] = a;
sl@0
   273
        glyphStorage[lastGlyph] = b;
sl@0
   274
sl@0
   275
        glyphStorage.setCharIndex(firstGlyph, id, success);
sl@0
   276
        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
sl@0
   277
        glyphStorage.setCharIndex(lastGlyph, ib, success);
sl@0
   278
        break;
sl@0
   279
sl@0
   280
    case irvDxBA:
sl@0
   281
        a = glyphStorage[firstGlyph];
sl@0
   282
        b = glyphStorage[firstGlyph + 1];
sl@0
   283
        d = glyphStorage[lastGlyph];
sl@0
   284
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   285
        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
sl@0
   286
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
   287
        x = firstGlyph + 2;
sl@0
   288
sl@0
   289
        while (x < lastGlyph) {
sl@0
   290
            glyphStorage[x - 2] = glyphStorage[x];
sl@0
   291
            ix = glyphStorage.getCharIndex(x, success);
sl@0
   292
            glyphStorage.setCharIndex(x - 2, ix, success);
sl@0
   293
            x += 1;
sl@0
   294
        }
sl@0
   295
sl@0
   296
        glyphStorage[firstGlyph] = d;
sl@0
   297
        glyphStorage[lastGlyph - 1] = b;
sl@0
   298
        glyphStorage[lastGlyph] = a;
sl@0
   299
sl@0
   300
        glyphStorage.setCharIndex(firstGlyph, id, success);
sl@0
   301
        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
sl@0
   302
        glyphStorage.setCharIndex(lastGlyph, ia, success);
sl@0
   303
        break;
sl@0
   304
sl@0
   305
    case irvCDxAB:
sl@0
   306
        a = glyphStorage[firstGlyph];
sl@0
   307
        b = glyphStorage[firstGlyph + 1];
sl@0
   308
sl@0
   309
        glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
sl@0
   310
        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
sl@0
   311
sl@0
   312
        glyphStorage[lastGlyph - 1] = a;
sl@0
   313
        glyphStorage[lastGlyph] = b;
sl@0
   314
sl@0
   315
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   316
        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
sl@0
   317
        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
sl@0
   318
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
   319
sl@0
   320
        glyphStorage.setCharIndex(firstGlyph, ic, success);
sl@0
   321
        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
sl@0
   322
sl@0
   323
        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
sl@0
   324
        glyphStorage.setCharIndex(lastGlyph, ib, success);
sl@0
   325
        break;
sl@0
   326
sl@0
   327
    case irvCDxBA:
sl@0
   328
        a = glyphStorage[firstGlyph];
sl@0
   329
        b = glyphStorage[firstGlyph + 1];
sl@0
   330
sl@0
   331
        glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
sl@0
   332
        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
sl@0
   333
sl@0
   334
        glyphStorage[lastGlyph - 1] = b;
sl@0
   335
        glyphStorage[lastGlyph] = a;
sl@0
   336
sl@0
   337
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   338
        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
sl@0
   339
        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
sl@0
   340
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
   341
sl@0
   342
        glyphStorage.setCharIndex(firstGlyph, ic, success);
sl@0
   343
        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
sl@0
   344
sl@0
   345
        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
sl@0
   346
        glyphStorage.setCharIndex(lastGlyph, ia, success);
sl@0
   347
        break;
sl@0
   348
sl@0
   349
    case irvDCxAB:
sl@0
   350
        a = glyphStorage[firstGlyph];
sl@0
   351
        b = glyphStorage[firstGlyph + 1];
sl@0
   352
sl@0
   353
        glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
sl@0
   354
        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
sl@0
   355
sl@0
   356
        glyphStorage[lastGlyph - 1] = a;
sl@0
   357
        glyphStorage[lastGlyph] = b;
sl@0
   358
sl@0
   359
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   360
        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
sl@0
   361
        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
sl@0
   362
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
   363
sl@0
   364
        glyphStorage.setCharIndex(firstGlyph, id, success);
sl@0
   365
        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
sl@0
   366
sl@0
   367
        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
sl@0
   368
        glyphStorage.setCharIndex(lastGlyph, ib, success);
sl@0
   369
        break;
sl@0
   370
sl@0
   371
    case irvDCxBA:
sl@0
   372
        a = glyphStorage[firstGlyph];
sl@0
   373
        b = glyphStorage[firstGlyph + 1];
sl@0
   374
sl@0
   375
        glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
sl@0
   376
        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
sl@0
   377
sl@0
   378
        glyphStorage[lastGlyph - 1] = b;
sl@0
   379
        glyphStorage[lastGlyph] = a;
sl@0
   380
sl@0
   381
        ia = glyphStorage.getCharIndex(firstGlyph, success);
sl@0
   382
        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
sl@0
   383
        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
sl@0
   384
        id = glyphStorage.getCharIndex(lastGlyph, success);
sl@0
   385
sl@0
   386
        glyphStorage.setCharIndex(firstGlyph, id, success);
sl@0
   387
        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
sl@0
   388
sl@0
   389
        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
sl@0
   390
        glyphStorage.setCharIndex(lastGlyph, ia, success);
sl@0
   391
        break;
sl@0
   392
    
sl@0
   393
    default:
sl@0
   394
        break;
sl@0
   395
    }
sl@0
   396
}
sl@0
   397
sl@0
   398
U_NAMESPACE_END