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
17U_NAMESPACE_BEGIN
18
19UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
20
21IndicRearrangementProcessor2::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
28IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
29{
30}
31
32void IndicRearrangementProcessor2::beginStateTable()
33{
34    firstGlyph = 0;
35    lastGlyph = 0;
36}
37
38le_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
63void IndicRearrangementProcessor2::endStateTable()
64{
65}
66
67void 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
400U_NAMESPACE_END
401