|
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 |
|
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 |
|
28 IndicRearrangementProcessor::~IndicRearrangementProcessor() |
|
29 { |
|
30 } |
|
31 |
|
32 void IndicRearrangementProcessor::beginStateTable() |
|
33 { |
|
34 firstGlyph = 0; |
|
35 lastGlyph = 0; |
|
36 } |
|
37 |
|
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 |
|
62 void IndicRearrangementProcessor::endStateTable() |
|
63 { |
|
64 } |
|
65 |
|
66 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 |