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