Remove packaging direcotry
[platform/upstream/icu.git] / source / layout / IndicRearrangementProcessor2.cpp
1 /*
2  *
3  * (C) Copyright IBM Corp.  and others 1998-2015 - 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
17 U_NAMESPACE_BEGIN
18
19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
20
21 IndicRearrangementProcessor2::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
28 IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
29 {
30 }
31
32 void IndicRearrangementProcessor2::beginStateTable()
33 {
34     firstGlyph = 0;
35     lastGlyph = 0;
36 }
37
38 le_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 = (le_uint32)currGlyph;
48     }
49
50     if (flags & irfMarkLast) {
51         lastGlyph = (le_uint32)currGlyph;
52     }
53
54     doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask), success);
55
56     if (!(flags & irfDontAdvance)) {
57         currGlyph += dir;
58     }
59     
60     return newState; // index to new state
61 }
62
63 void IndicRearrangementProcessor2::endStateTable()
64 {
65 }
66
67 void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb, LEErrorCode &success) const
68 {
69     LEGlyphID a, b, c, d;
70     le_int32 ia, ib, ic, id, ix, x;
71
72     if (LE_FAILURE(success)) return;
73
74     if (verb == irvNoAction) {
75         return;
76     }
77     if (firstGlyph > lastGlyph) {
78         success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
79         return;
80     }
81
82     switch(verb)
83     {
84     case irvxA:
85         if (firstGlyph == lastGlyph) break;
86         if (firstGlyph + 1 < firstGlyph) {
87             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
88         break;
89         }
90         a = glyphStorage[firstGlyph];
91         ia = glyphStorage.getCharIndex(firstGlyph, success);
92         x = firstGlyph + 1;
93
94         while (x <= lastGlyph) {
95             glyphStorage[x - 1] = glyphStorage[x];
96             ix = glyphStorage.getCharIndex(x, success);
97             glyphStorage.setCharIndex(x - 1, ix, success);
98             x += 1;
99         }
100
101         glyphStorage[lastGlyph] = a;
102         glyphStorage.setCharIndex(lastGlyph, ia, success);
103         break;
104
105     case irvDx:
106         if (firstGlyph == lastGlyph) break;
107         if (lastGlyph - 1 > lastGlyph) {
108             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
109             break;
110         }
111         d = glyphStorage[lastGlyph];
112         id = glyphStorage.getCharIndex(lastGlyph, success);
113         x = lastGlyph - 1;
114
115         while (x >= firstGlyph) {
116             glyphStorage[x + 1] = glyphStorage[x];
117             ix = glyphStorage.getCharIndex(x, success);
118             glyphStorage.setCharIndex(x + 1, ix, success);
119             x -= 1;
120         }
121
122         glyphStorage[firstGlyph] = d;
123         glyphStorage.setCharIndex(firstGlyph, id, success);
124         break;
125
126     case irvDxA:
127         a = glyphStorage[firstGlyph];
128         ia = glyphStorage.getCharIndex(firstGlyph, success);
129         id = glyphStorage.getCharIndex(lastGlyph,  success);
130
131         glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
132         glyphStorage[lastGlyph] = a;
133
134         glyphStorage.setCharIndex(firstGlyph, id, success);
135         glyphStorage.setCharIndex(lastGlyph,  ia, success);
136         break;
137         
138     case irvxAB:
139         if ((firstGlyph + 2 < firstGlyph) ||
140             (lastGlyph - firstGlyph < 1)) { // difference == 1 is a no-op, < 1 is an error.
141             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
142             break;
143         }
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] = a;
158         glyphStorage[lastGlyph] = b;
159
160         glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
161         glyphStorage.setCharIndex(lastGlyph, ib, success);
162         break;
163
164     case irvxBA:
165         if ((firstGlyph + 2 < firstGlyph) ||
166             (lastGlyph - firstGlyph < 1)) {
167             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
168             break;
169         }
170         a = glyphStorage[firstGlyph];
171         b = glyphStorage[firstGlyph + 1];
172         ia = glyphStorage.getCharIndex(firstGlyph, success);
173         ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
174         x = firstGlyph + 2;
175
176         while (x <= lastGlyph) {
177             glyphStorage[x - 2] = glyphStorage[x];
178             ix = glyphStorage.getCharIndex(x, success);
179             glyphStorage.setCharIndex(x - 2, ix, success);
180             x += 1;
181         }
182
183         glyphStorage[lastGlyph - 1] = b;
184         glyphStorage[lastGlyph] = a;
185
186         glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
187         glyphStorage.setCharIndex(lastGlyph, ia, success);
188         break;
189
190     case irvCDx:
191         if ((lastGlyph - 2 > lastGlyph) ||
192             (lastGlyph - firstGlyph < 1)) {
193             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
194             break;
195         }
196         c = glyphStorage[lastGlyph - 1];
197         d = glyphStorage[lastGlyph];
198         ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
199         id = glyphStorage.getCharIndex(lastGlyph, success);
200         x = lastGlyph - 2;
201
202         while (x >= firstGlyph) {
203             glyphStorage[x + 2] = glyphStorage[x];
204             ix = glyphStorage.getCharIndex(x, success);
205             glyphStorage.setCharIndex(x + 2, ix, success);
206             x -= 1;
207         }
208         
209         glyphStorage[firstGlyph] = c;
210         glyphStorage[firstGlyph + 1] = d;
211
212         glyphStorage.setCharIndex(firstGlyph, ic, success);
213         glyphStorage.setCharIndex(firstGlyph + 1, id, success);
214         break; 
215
216     case irvDCx:
217         if ((lastGlyph - 2 > lastGlyph) ||
218             (lastGlyph - firstGlyph < 1)) {
219             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
220             break;
221         }
222         c = glyphStorage[lastGlyph - 1];
223         d = glyphStorage[lastGlyph];
224         ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
225         id = glyphStorage.getCharIndex(lastGlyph, success);
226         x = lastGlyph - 2;
227
228         while (x >= firstGlyph) {
229             glyphStorage[x + 2] = glyphStorage[x];
230             ix = glyphStorage.getCharIndex(x, success);
231             glyphStorage.setCharIndex(x + 2, ix, success);
232             x -= 1;
233         }
234         
235         glyphStorage[firstGlyph] = d;
236         glyphStorage[firstGlyph + 1] = c;
237
238         glyphStorage.setCharIndex(firstGlyph, id, success);
239         glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
240         break; 
241
242     case irvCDxA:
243         if ((lastGlyph - 2 > lastGlyph) ||
244             (lastGlyph - firstGlyph < 2)) {
245             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
246             break;
247         }
248         a = glyphStorage[firstGlyph];
249         c = glyphStorage[lastGlyph - 1];
250         d = glyphStorage[lastGlyph];
251         ia = glyphStorage.getCharIndex(firstGlyph, success);
252         ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
253         id = glyphStorage.getCharIndex(lastGlyph, success);
254         x = lastGlyph - 2;
255
256         while (x > firstGlyph) {
257             glyphStorage[x + 1] = glyphStorage[x];
258             ix = glyphStorage.getCharIndex(x, success);
259             glyphStorage.setCharIndex(x + 1, ix, success);
260             x -= 1;
261         }
262         
263         glyphStorage[firstGlyph] = c;
264         glyphStorage[firstGlyph + 1] = d;
265         glyphStorage[lastGlyph] = a;
266
267         glyphStorage.setCharIndex(firstGlyph, ic, success);
268         glyphStorage.setCharIndex(firstGlyph + 1, id, success);
269         glyphStorage.setCharIndex(lastGlyph, ia, success);
270         break; 
271
272     case irvDCxA:
273         if ((lastGlyph - 2 > lastGlyph) ||
274             (lastGlyph - firstGlyph < 2)) {
275             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
276             break;
277         }
278         a = glyphStorage[firstGlyph];
279         c = glyphStorage[lastGlyph - 1];
280         d = glyphStorage[lastGlyph];
281         ia = glyphStorage.getCharIndex(firstGlyph, success);
282         ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
283         id = glyphStorage.getCharIndex(lastGlyph, success);
284         x = lastGlyph - 2;
285
286         while (x > firstGlyph) {
287             glyphStorage[x + 1] = glyphStorage[x];
288             ix = glyphStorage.getCharIndex(x, success);
289             glyphStorage.setCharIndex(x + 1, ix, success);
290             x -= 1;
291         }
292         
293         glyphStorage[firstGlyph] = d;
294         glyphStorage[firstGlyph + 1] = c;
295         glyphStorage[lastGlyph] = a;
296
297         glyphStorage.setCharIndex(firstGlyph, id, success);
298         glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
299         glyphStorage.setCharIndex(lastGlyph, ia, success);
300         break; 
301
302     case irvDxAB:
303         if ((firstGlyph + 2 < firstGlyph) ||
304             (lastGlyph - firstGlyph < 2)) {
305             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
306             break;
307         }
308         a = glyphStorage[firstGlyph];
309         b = glyphStorage[firstGlyph + 1];
310         d = glyphStorage[lastGlyph];
311         ia = glyphStorage.getCharIndex(firstGlyph, success);
312         ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
313         id = glyphStorage.getCharIndex(lastGlyph, success);
314         x = firstGlyph + 2;
315
316         while (x < lastGlyph) {
317             glyphStorage[x - 2] = glyphStorage[x];
318             ix = glyphStorage.getCharIndex(x, success);
319             glyphStorage.setCharIndex(x - 2, ix, success);
320             x += 1;
321         }
322
323         glyphStorage[firstGlyph] = d;
324         glyphStorage[lastGlyph - 1] = a;
325         glyphStorage[lastGlyph] = b;
326
327         glyphStorage.setCharIndex(firstGlyph, id, success);
328         glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
329         glyphStorage.setCharIndex(lastGlyph, ib, success);
330         break;
331
332     case irvDxBA:
333         if ((firstGlyph + 2 < firstGlyph) ||
334             (lastGlyph - firstGlyph < 2)) {
335             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
336             break;
337         }
338         a = glyphStorage[firstGlyph];
339         b = glyphStorage[firstGlyph + 1];
340         d = glyphStorage[lastGlyph];
341         ia = glyphStorage.getCharIndex(firstGlyph, success);
342         ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
343         id = glyphStorage.getCharIndex(lastGlyph, success);
344         x = firstGlyph + 2;
345
346         while (x < lastGlyph) {
347             glyphStorage[x - 2] = glyphStorage[x];
348             ix = glyphStorage.getCharIndex(x, success);
349             glyphStorage.setCharIndex(x - 2, ix, success);
350             x += 1;
351         }
352
353         glyphStorage[firstGlyph] = d;
354         glyphStorage[lastGlyph - 1] = b;
355         glyphStorage[lastGlyph] = a;
356
357         glyphStorage.setCharIndex(firstGlyph, id, success);
358         glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
359         glyphStorage.setCharIndex(lastGlyph, ia, success);
360         break;
361
362     case irvCDxAB:
363         if (lastGlyph - firstGlyph < 3) {
364             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
365             break;
366         }
367         a = glyphStorage[firstGlyph];
368         b = glyphStorage[firstGlyph + 1];
369
370         glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
371         glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
372
373         glyphStorage[lastGlyph - 1] = a;
374         glyphStorage[lastGlyph] = b;
375
376         ia = glyphStorage.getCharIndex(firstGlyph, success);
377         ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
378         ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
379         id = glyphStorage.getCharIndex(lastGlyph, success);
380
381         glyphStorage.setCharIndex(firstGlyph, ic, success);
382         glyphStorage.setCharIndex(firstGlyph + 1, id, success);
383
384         glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
385         glyphStorage.setCharIndex(lastGlyph, ib, success);
386         break;
387
388     case irvCDxBA:
389         if (lastGlyph - firstGlyph < 3) {
390             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
391             break;
392         }
393         a = glyphStorage[firstGlyph];
394         b = glyphStorage[firstGlyph + 1];
395
396         glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
397         glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
398
399         glyphStorage[lastGlyph - 1] = b;
400         glyphStorage[lastGlyph] = a;
401
402         ia = glyphStorage.getCharIndex(firstGlyph, success);
403         ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
404         ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
405         id = glyphStorage.getCharIndex(lastGlyph, success);
406
407         glyphStorage.setCharIndex(firstGlyph, ic, success);
408         glyphStorage.setCharIndex(firstGlyph + 1, id, success);
409
410         glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
411         glyphStorage.setCharIndex(lastGlyph, ia, success);
412         break;
413
414     case irvDCxAB:
415         if (lastGlyph - firstGlyph < 3) {
416             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
417             break;
418         }
419         a = glyphStorage[firstGlyph];
420         b = glyphStorage[firstGlyph + 1];
421
422         glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
423         glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
424
425         glyphStorage[lastGlyph - 1] = a;
426         glyphStorage[lastGlyph] = b;
427
428         ia = glyphStorage.getCharIndex(firstGlyph, success);
429         ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
430         ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
431         id = glyphStorage.getCharIndex(lastGlyph, success);
432
433         glyphStorage.setCharIndex(firstGlyph, id, success);
434         glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
435
436         glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
437         glyphStorage.setCharIndex(lastGlyph, ib, success);
438         break;
439
440     case irvDCxBA:
441         if (lastGlyph - firstGlyph < 3) {
442             success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
443             break;
444         }
445         a = glyphStorage[firstGlyph];
446         b = glyphStorage[firstGlyph + 1];
447
448         glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
449         glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
450
451         glyphStorage[lastGlyph - 1] = b;
452         glyphStorage[lastGlyph] = a;
453
454         ia = glyphStorage.getCharIndex(firstGlyph, success);
455         ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
456         ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
457         id = glyphStorage.getCharIndex(lastGlyph, success);
458
459         glyphStorage.setCharIndex(firstGlyph, id, success);
460         glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
461
462         glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
463         glyphStorage.setCharIndex(lastGlyph, ia, success);
464         break;
465     
466     default:
467         break;
468     }
469
470 }
471
472 U_NAMESPACE_END