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