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