3 * (C) Copyright IBM Corp. and others 1998-2015 - All Rights Reserved
8 #include "MorphTables.h"
9 #include "StateTables.h"
10 #include "MorphStateTables.h"
11 #include "SubtableProcessor2.h"
12 #include "StateTableProcessor2.h"
13 #include "IndicRearrangementProcessor2.h"
14 #include "LEGlyphStorage.h"
19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
21 IndicRearrangementProcessor2::IndicRearrangementProcessor2(
22 const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
23 : StateTableProcessor2(morphSubtableHeader, success), entryTable(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY),
24 indicRearrangementSubtableHeader(morphSubtableHeader, success)
28 IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
32 void IndicRearrangementProcessor2::beginStateTable()
38 le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
39 EntryTableIndex2 index, LEErrorCode &success)
41 const IndicRearrangementStateEntry2 *entry = entryTable.getAlias(index, success);
42 if (LE_FAILURE(success)) return 0; // TODO - what to return in bad state?
43 le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
44 IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
46 if (flags & irfMarkFirst) {
47 firstGlyph = (le_uint32)currGlyph;
50 if (flags & irfMarkLast) {
51 lastGlyph = (le_uint32)currGlyph;
54 doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask), success);
56 if (!(flags & irfDontAdvance)) {
60 return newState; // index to new state
63 void IndicRearrangementProcessor2::endStateTable()
67 void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb, LEErrorCode &success) const
70 le_int32 ia, ib, ic, id, ix, x;
72 if (LE_FAILURE(success)) return;
74 if (verb == irvNoAction) {
77 if (firstGlyph > lastGlyph) {
78 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
85 if (firstGlyph == lastGlyph) break;
86 if (firstGlyph + 1 < firstGlyph) {
87 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
90 a = glyphStorage[firstGlyph];
91 ia = glyphStorage.getCharIndex(firstGlyph, success);
94 while (x <= lastGlyph) {
95 glyphStorage[x - 1] = glyphStorage[x];
96 ix = glyphStorage.getCharIndex(x, success);
97 glyphStorage.setCharIndex(x - 1, ix, success);
101 glyphStorage[lastGlyph] = a;
102 glyphStorage.setCharIndex(lastGlyph, ia, success);
106 if (firstGlyph == lastGlyph) break;
107 if (lastGlyph - 1 > lastGlyph) {
108 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
111 d = glyphStorage[lastGlyph];
112 id = glyphStorage.getCharIndex(lastGlyph, success);
115 while (x >= firstGlyph) {
116 glyphStorage[x + 1] = glyphStorage[x];
117 ix = glyphStorage.getCharIndex(x, success);
118 glyphStorage.setCharIndex(x + 1, ix, success);
122 glyphStorage[firstGlyph] = d;
123 glyphStorage.setCharIndex(firstGlyph, id, success);
127 a = glyphStorage[firstGlyph];
128 ia = glyphStorage.getCharIndex(firstGlyph, success);
129 id = glyphStorage.getCharIndex(lastGlyph, success);
131 glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
132 glyphStorage[lastGlyph] = a;
134 glyphStorage.setCharIndex(firstGlyph, id, success);
135 glyphStorage.setCharIndex(lastGlyph, ia, success);
139 if ((firstGlyph + 2 < firstGlyph) ||
140 (lastGlyph - firstGlyph < 1)) { // difference == 1 is a no-op, < 1 is an error.
141 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
144 a = glyphStorage[firstGlyph];
145 b = glyphStorage[firstGlyph + 1];
146 ia = glyphStorage.getCharIndex(firstGlyph, success);
147 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
150 while (x <= lastGlyph) {
151 glyphStorage[x - 2] = glyphStorage[x];
152 ix = glyphStorage.getCharIndex(x, success);
153 glyphStorage.setCharIndex(x - 2, ix, success);
157 glyphStorage[lastGlyph - 1] = a;
158 glyphStorage[lastGlyph] = b;
160 glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
161 glyphStorage.setCharIndex(lastGlyph, ib, success);
165 if ((firstGlyph + 2 < firstGlyph) ||
166 (lastGlyph - firstGlyph < 1)) {
167 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
170 a = glyphStorage[firstGlyph];
171 b = glyphStorage[firstGlyph + 1];
172 ia = glyphStorage.getCharIndex(firstGlyph, success);
173 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
176 while (x <= lastGlyph) {
177 glyphStorage[x - 2] = glyphStorage[x];
178 ix = glyphStorage.getCharIndex(x, success);
179 glyphStorage.setCharIndex(x - 2, ix, success);
183 glyphStorage[lastGlyph - 1] = b;
184 glyphStorage[lastGlyph] = a;
186 glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
187 glyphStorage.setCharIndex(lastGlyph, ia, success);
191 if ((lastGlyph - 2 > lastGlyph) ||
192 (lastGlyph - firstGlyph < 1)) {
193 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
196 c = glyphStorage[lastGlyph - 1];
197 d = glyphStorage[lastGlyph];
198 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
199 id = glyphStorage.getCharIndex(lastGlyph, success);
202 while (x >= firstGlyph) {
203 glyphStorage[x + 2] = glyphStorage[x];
204 ix = glyphStorage.getCharIndex(x, success);
205 glyphStorage.setCharIndex(x + 2, ix, success);
209 glyphStorage[firstGlyph] = c;
210 glyphStorage[firstGlyph + 1] = d;
212 glyphStorage.setCharIndex(firstGlyph, ic, success);
213 glyphStorage.setCharIndex(firstGlyph + 1, id, success);
217 if ((lastGlyph - 2 > lastGlyph) ||
218 (lastGlyph - firstGlyph < 1)) {
219 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
222 c = glyphStorage[lastGlyph - 1];
223 d = glyphStorage[lastGlyph];
224 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
225 id = glyphStorage.getCharIndex(lastGlyph, success);
228 while (x >= firstGlyph) {
229 glyphStorage[x + 2] = glyphStorage[x];
230 ix = glyphStorage.getCharIndex(x, success);
231 glyphStorage.setCharIndex(x + 2, ix, success);
235 glyphStorage[firstGlyph] = d;
236 glyphStorage[firstGlyph + 1] = c;
238 glyphStorage.setCharIndex(firstGlyph, id, success);
239 glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
243 if ((lastGlyph - 2 > lastGlyph) ||
244 (lastGlyph - firstGlyph < 2)) {
245 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
248 a = glyphStorage[firstGlyph];
249 c = glyphStorage[lastGlyph - 1];
250 d = glyphStorage[lastGlyph];
251 ia = glyphStorage.getCharIndex(firstGlyph, success);
252 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
253 id = glyphStorage.getCharIndex(lastGlyph, success);
256 while (x > firstGlyph) {
257 glyphStorage[x + 1] = glyphStorage[x];
258 ix = glyphStorage.getCharIndex(x, success);
259 glyphStorage.setCharIndex(x + 1, ix, success);
263 glyphStorage[firstGlyph] = c;
264 glyphStorage[firstGlyph + 1] = d;
265 glyphStorage[lastGlyph] = a;
267 glyphStorage.setCharIndex(firstGlyph, ic, success);
268 glyphStorage.setCharIndex(firstGlyph + 1, id, success);
269 glyphStorage.setCharIndex(lastGlyph, ia, success);
273 if ((lastGlyph - 2 > lastGlyph) ||
274 (lastGlyph - firstGlyph < 2)) {
275 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
278 a = glyphStorage[firstGlyph];
279 c = glyphStorage[lastGlyph - 1];
280 d = glyphStorage[lastGlyph];
281 ia = glyphStorage.getCharIndex(firstGlyph, success);
282 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
283 id = glyphStorage.getCharIndex(lastGlyph, success);
286 while (x > firstGlyph) {
287 glyphStorage[x + 1] = glyphStorage[x];
288 ix = glyphStorage.getCharIndex(x, success);
289 glyphStorage.setCharIndex(x + 1, ix, success);
293 glyphStorage[firstGlyph] = d;
294 glyphStorage[firstGlyph + 1] = c;
295 glyphStorage[lastGlyph] = a;
297 glyphStorage.setCharIndex(firstGlyph, id, success);
298 glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
299 glyphStorage.setCharIndex(lastGlyph, ia, success);
303 if ((firstGlyph + 2 < firstGlyph) ||
304 (lastGlyph - firstGlyph < 2)) {
305 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
308 a = glyphStorage[firstGlyph];
309 b = glyphStorage[firstGlyph + 1];
310 d = glyphStorage[lastGlyph];
311 ia = glyphStorage.getCharIndex(firstGlyph, success);
312 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
313 id = glyphStorage.getCharIndex(lastGlyph, success);
316 while (x < lastGlyph) {
317 glyphStorage[x - 2] = glyphStorage[x];
318 ix = glyphStorage.getCharIndex(x, success);
319 glyphStorage.setCharIndex(x - 2, ix, success);
323 glyphStorage[firstGlyph] = d;
324 glyphStorage[lastGlyph - 1] = a;
325 glyphStorage[lastGlyph] = b;
327 glyphStorage.setCharIndex(firstGlyph, id, success);
328 glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
329 glyphStorage.setCharIndex(lastGlyph, ib, success);
333 if ((firstGlyph + 2 < firstGlyph) ||
334 (lastGlyph - firstGlyph < 2)) {
335 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
338 a = glyphStorage[firstGlyph];
339 b = glyphStorage[firstGlyph + 1];
340 d = glyphStorage[lastGlyph];
341 ia = glyphStorage.getCharIndex(firstGlyph, success);
342 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
343 id = glyphStorage.getCharIndex(lastGlyph, success);
346 while (x < lastGlyph) {
347 glyphStorage[x - 2] = glyphStorage[x];
348 ix = glyphStorage.getCharIndex(x, success);
349 glyphStorage.setCharIndex(x - 2, ix, success);
353 glyphStorage[firstGlyph] = d;
354 glyphStorage[lastGlyph - 1] = b;
355 glyphStorage[lastGlyph] = a;
357 glyphStorage.setCharIndex(firstGlyph, id, success);
358 glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
359 glyphStorage.setCharIndex(lastGlyph, ia, success);
363 if (lastGlyph - firstGlyph < 3) {
364 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
367 a = glyphStorage[firstGlyph];
368 b = glyphStorage[firstGlyph + 1];
370 glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
371 glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
373 glyphStorage[lastGlyph - 1] = a;
374 glyphStorage[lastGlyph] = b;
376 ia = glyphStorage.getCharIndex(firstGlyph, success);
377 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
378 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
379 id = glyphStorage.getCharIndex(lastGlyph, success);
381 glyphStorage.setCharIndex(firstGlyph, ic, success);
382 glyphStorage.setCharIndex(firstGlyph + 1, id, success);
384 glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
385 glyphStorage.setCharIndex(lastGlyph, ib, success);
389 if (lastGlyph - firstGlyph < 3) {
390 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
393 a = glyphStorage[firstGlyph];
394 b = glyphStorage[firstGlyph + 1];
396 glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
397 glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
399 glyphStorage[lastGlyph - 1] = b;
400 glyphStorage[lastGlyph] = a;
402 ia = glyphStorage.getCharIndex(firstGlyph, success);
403 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
404 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
405 id = glyphStorage.getCharIndex(lastGlyph, success);
407 glyphStorage.setCharIndex(firstGlyph, ic, success);
408 glyphStorage.setCharIndex(firstGlyph + 1, id, success);
410 glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
411 glyphStorage.setCharIndex(lastGlyph, ia, success);
415 if (lastGlyph - firstGlyph < 3) {
416 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
419 a = glyphStorage[firstGlyph];
420 b = glyphStorage[firstGlyph + 1];
422 glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
423 glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
425 glyphStorage[lastGlyph - 1] = a;
426 glyphStorage[lastGlyph] = b;
428 ia = glyphStorage.getCharIndex(firstGlyph, success);
429 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
430 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
431 id = glyphStorage.getCharIndex(lastGlyph, success);
433 glyphStorage.setCharIndex(firstGlyph, id, success);
434 glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
436 glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
437 glyphStorage.setCharIndex(lastGlyph, ib, success);
441 if (lastGlyph - firstGlyph < 3) {
442 success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
445 a = glyphStorage[firstGlyph];
446 b = glyphStorage[firstGlyph + 1];
448 glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
449 glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
451 glyphStorage[lastGlyph - 1] = b;
452 glyphStorage[lastGlyph] = a;
454 ia = glyphStorage.getCharIndex(firstGlyph, success);
455 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
456 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
457 id = glyphStorage.getCharIndex(lastGlyph, success);
459 glyphStorage.setCharIndex(firstGlyph, id, success);
460 glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
462 glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
463 glyphStorage.setCharIndex(lastGlyph, ia, success);