]> git.saurik.com Git - apple/icu.git/blob - icuSources/layout/IndicRearrangementProcessor2.cpp
ICU-511.34.tar.gz
[apple/icu.git] / icuSources / layout / IndicRearrangementProcessor2.cpp
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
17 U_NAMESPACE_BEGIN
18
19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
20
21 IndicRearrangementProcessor2::IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
22 : StateTableProcessor2(morphSubtableHeader)
23 {
24 indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader2 *) morphSubtableHeader;
25 entryTable = (const IndicRearrangementStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
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, 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
61 void IndicRearrangementProcessor2::endStateTable()
62 {
63 }
64
65 void 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
398 U_NAMESPACE_END