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
17 U_NAMESPACE_BEGIN
18
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)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
~IndicRearrangementProcessor2()28 IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
29 {
30 }
31
beginStateTable()32 void IndicRearrangementProcessor2::beginStateTable()
33 {
34 firstGlyph = 0;
35 lastGlyph = 0;
36 }
37
processStateEntry(LEGlyphStorage & glyphStorage,le_int32 & currGlyph,EntryTableIndex2 index,LEErrorCode & success)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 = 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
endStateTable()63 void IndicRearrangementProcessor2::endStateTable()
64 {
65 }
66
doRearrangementAction(LEGlyphStorage & glyphStorage,IndicRearrangementVerb verb) const67 void 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
400 U_NAMESPACE_END
401