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