• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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