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