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