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