fontservices/textshaperplugin/IcuSource/layout/IndicRearrangementProcessor.cpp
changeset 0 1fb32624e06b
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     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