3 * (C) Copyright IBM Corp. 1998-2015 - All Rights Reserved
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"
19 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor
)
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
)
31 IndicRearrangementProcessor::~IndicRearrangementProcessor()
35 void IndicRearrangementProcessor::beginStateTable()
41 ByteOffset
IndicRearrangementProcessor::processStateEntry(LEGlyphStorage
&glyphStorage
, le_int32
&currGlyph
, EntryTableIndex index
)
43 LEErrorCode success
= LE_NO_ERROR
; // todo- make a param?
44 const IndicRearrangementStateEntry
*entry
= entryTable
.getAlias(index
,success
);
45 ByteOffset newState
= SWAPW(entry
->newStateOffset
);
46 IndicRearrangementFlags flags
= (IndicRearrangementFlags
) SWAPW(entry
->flags
);
48 if (flags
& irfMarkFirst
) {
49 firstGlyph
= (le_uint32
)currGlyph
;
52 if (flags
& irfMarkLast
) {
53 lastGlyph
= (le_uint32
)currGlyph
;
56 doRearrangementAction(glyphStorage
, (IndicRearrangementVerb
) (flags
& irfVerbMask
), success
);
58 if (!(flags
& irfDontAdvance
)) {
59 // XXX: Should handle reverse too...
66 void IndicRearrangementProcessor::endStateTable()
70 void IndicRearrangementProcessor::doRearrangementAction(LEGlyphStorage
&glyphStorage
, IndicRearrangementVerb verb
, LEErrorCode
&success
) const
73 le_int32 ia
, ib
, ic
, id
, ix
, x
;
75 if (LE_FAILURE(success
)) return;
77 if (verb
== irvNoAction
) {
80 if (firstGlyph
> lastGlyph
) {
81 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
88 if (firstGlyph
== lastGlyph
) break;
89 if (firstGlyph
+ 1 < firstGlyph
) {
90 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
93 a
= glyphStorage
[firstGlyph
];
94 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
97 while (x
<= lastGlyph
) {
98 glyphStorage
[x
- 1] = glyphStorage
[x
];
99 ix
= glyphStorage
.getCharIndex(x
, success
);
100 glyphStorage
.setCharIndex(x
- 1, ix
, success
);
104 glyphStorage
[lastGlyph
] = a
;
105 glyphStorage
.setCharIndex(lastGlyph
, ia
, success
);
109 if (firstGlyph
== lastGlyph
) break;
110 if (lastGlyph
- 1 > lastGlyph
) {
111 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
114 d
= glyphStorage
[lastGlyph
];
115 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
118 while (x
>= firstGlyph
) {
119 glyphStorage
[x
+ 1] = glyphStorage
[x
];
120 ix
= glyphStorage
.getCharIndex(x
, success
);
121 glyphStorage
.setCharIndex(x
+ 1, ix
, success
);
125 glyphStorage
[firstGlyph
] = d
;
126 glyphStorage
.setCharIndex(firstGlyph
, id
, success
);
130 a
= glyphStorage
[firstGlyph
];
131 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
132 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
134 glyphStorage
[firstGlyph
] = glyphStorage
[lastGlyph
];
135 glyphStorage
[lastGlyph
] = a
;
137 glyphStorage
.setCharIndex(firstGlyph
, id
, success
);
138 glyphStorage
.setCharIndex(lastGlyph
, ia
, success
);
142 if ((firstGlyph
+ 2 < firstGlyph
) ||
143 (lastGlyph
- firstGlyph
< 1)) { // difference == 1 is a no-op, < 1 is an error.
144 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
147 a
= glyphStorage
[firstGlyph
];
148 b
= glyphStorage
[firstGlyph
+ 1];
149 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
150 ib
= glyphStorage
.getCharIndex(firstGlyph
+ 1, success
);
153 while (x
<= lastGlyph
) {
154 glyphStorage
[x
- 2] = glyphStorage
[x
];
155 ix
= glyphStorage
.getCharIndex(x
, success
);
156 glyphStorage
.setCharIndex(x
- 2, ix
, success
);
160 glyphStorage
[lastGlyph
- 1] = a
;
161 glyphStorage
[lastGlyph
] = b
;
163 glyphStorage
.setCharIndex(lastGlyph
- 1, ia
, success
);
164 glyphStorage
.setCharIndex(lastGlyph
, ib
, success
);
168 if ((firstGlyph
+ 2 < firstGlyph
) ||
169 (lastGlyph
- firstGlyph
< 1)) {
170 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
173 a
= glyphStorage
[firstGlyph
];
174 b
= glyphStorage
[firstGlyph
+ 1];
175 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
176 ib
= glyphStorage
.getCharIndex(firstGlyph
+ 1, success
);
179 while (x
<= lastGlyph
) {
180 glyphStorage
[x
- 2] = glyphStorage
[x
];
181 ix
= glyphStorage
.getCharIndex(x
, success
);
182 glyphStorage
.setCharIndex(x
- 2, ix
, success
);
186 glyphStorage
[lastGlyph
- 1] = b
;
187 glyphStorage
[lastGlyph
] = a
;
189 glyphStorage
.setCharIndex(lastGlyph
- 1, ib
, success
);
190 glyphStorage
.setCharIndex(lastGlyph
, ia
, success
);
194 if ((lastGlyph
- 2 > lastGlyph
) ||
195 (lastGlyph
- firstGlyph
< 1)) {
196 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
199 c
= glyphStorage
[lastGlyph
- 1];
200 d
= glyphStorage
[lastGlyph
];
201 ic
= glyphStorage
.getCharIndex(lastGlyph
- 1, success
);
202 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
205 while (x
>= firstGlyph
) {
206 glyphStorage
[x
+ 2] = glyphStorage
[x
];
207 ix
= glyphStorage
.getCharIndex(x
, success
);
208 glyphStorage
.setCharIndex(x
+ 2, ix
, success
);
212 glyphStorage
[firstGlyph
] = c
;
213 glyphStorage
[firstGlyph
+ 1] = d
;
215 glyphStorage
.setCharIndex(firstGlyph
, ic
, success
);
216 glyphStorage
.setCharIndex(firstGlyph
+ 1, id
, success
);
220 if ((lastGlyph
- 2 > lastGlyph
) ||
221 (lastGlyph
- firstGlyph
< 1)) {
222 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
225 c
= glyphStorage
[lastGlyph
- 1];
226 d
= glyphStorage
[lastGlyph
];
227 ic
= glyphStorage
.getCharIndex(lastGlyph
- 1, success
);
228 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
231 while (x
>= firstGlyph
) {
232 glyphStorage
[x
+ 2] = glyphStorage
[x
];
233 ix
= glyphStorage
.getCharIndex(x
, success
);
234 glyphStorage
.setCharIndex(x
+ 2, ix
, success
);
238 glyphStorage
[firstGlyph
] = d
;
239 glyphStorage
[firstGlyph
+ 1] = c
;
241 glyphStorage
.setCharIndex(firstGlyph
, id
, success
);
242 glyphStorage
.setCharIndex(firstGlyph
+ 1, ic
, success
);
246 if ((lastGlyph
- 2 > lastGlyph
) ||
247 (lastGlyph
- firstGlyph
< 2)) {
248 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
251 a
= glyphStorage
[firstGlyph
];
252 c
= glyphStorage
[lastGlyph
- 1];
253 d
= glyphStorage
[lastGlyph
];
254 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
255 ic
= glyphStorage
.getCharIndex(lastGlyph
- 1, success
);
256 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
259 while (x
> firstGlyph
) {
260 glyphStorage
[x
+ 1] = glyphStorage
[x
];
261 ix
= glyphStorage
.getCharIndex(x
, success
);
262 glyphStorage
.setCharIndex(x
+ 1, ix
, success
);
266 glyphStorage
[firstGlyph
] = c
;
267 glyphStorage
[firstGlyph
+ 1] = d
;
268 glyphStorage
[lastGlyph
] = a
;
270 glyphStorage
.setCharIndex(firstGlyph
, ic
, success
);
271 glyphStorage
.setCharIndex(firstGlyph
+ 1, id
, success
);
272 glyphStorage
.setCharIndex(lastGlyph
, ia
, success
);
276 if ((lastGlyph
- 2 > lastGlyph
) ||
277 (lastGlyph
- firstGlyph
< 2)) {
278 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
281 a
= glyphStorage
[firstGlyph
];
282 c
= glyphStorage
[lastGlyph
- 1];
283 d
= glyphStorage
[lastGlyph
];
284 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
285 ic
= glyphStorage
.getCharIndex(lastGlyph
- 1, success
);
286 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
289 while (x
> firstGlyph
) {
290 glyphStorage
[x
+ 1] = glyphStorage
[x
];
291 ix
= glyphStorage
.getCharIndex(x
, success
);
292 glyphStorage
.setCharIndex(x
+ 1, ix
, success
);
296 glyphStorage
[firstGlyph
] = d
;
297 glyphStorage
[firstGlyph
+ 1] = c
;
298 glyphStorage
[lastGlyph
] = a
;
300 glyphStorage
.setCharIndex(firstGlyph
, id
, success
);
301 glyphStorage
.setCharIndex(firstGlyph
+ 1, ic
, success
);
302 glyphStorage
.setCharIndex(lastGlyph
, ia
, success
);
306 if ((firstGlyph
+ 2 < firstGlyph
) ||
307 (lastGlyph
- firstGlyph
< 2)) {
308 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
311 a
= glyphStorage
[firstGlyph
];
312 b
= glyphStorage
[firstGlyph
+ 1];
313 d
= glyphStorage
[lastGlyph
];
314 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
315 ib
= glyphStorage
.getCharIndex(firstGlyph
+ 1, success
);
316 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
319 while (x
< lastGlyph
) {
320 glyphStorage
[x
- 2] = glyphStorage
[x
];
321 ix
= glyphStorage
.getCharIndex(x
, success
);
322 glyphStorage
.setCharIndex(x
- 2, ix
, success
);
326 glyphStorage
[firstGlyph
] = d
;
327 glyphStorage
[lastGlyph
- 1] = a
;
328 glyphStorage
[lastGlyph
] = b
;
330 glyphStorage
.setCharIndex(firstGlyph
, id
, success
);
331 glyphStorage
.setCharIndex(lastGlyph
- 1, ia
, success
);
332 glyphStorage
.setCharIndex(lastGlyph
, ib
, success
);
336 if ((firstGlyph
+ 2 < firstGlyph
) ||
337 (lastGlyph
- firstGlyph
< 2)) {
338 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
341 a
= glyphStorage
[firstGlyph
];
342 b
= glyphStorage
[firstGlyph
+ 1];
343 d
= glyphStorage
[lastGlyph
];
344 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
345 ib
= glyphStorage
.getCharIndex(firstGlyph
+ 1, success
);
346 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
349 while (x
< lastGlyph
) {
350 glyphStorage
[x
- 2] = glyphStorage
[x
];
351 ix
= glyphStorage
.getCharIndex(x
, success
);
352 glyphStorage
.setCharIndex(x
- 2, ix
, success
);
356 glyphStorage
[firstGlyph
] = d
;
357 glyphStorage
[lastGlyph
- 1] = b
;
358 glyphStorage
[lastGlyph
] = a
;
360 glyphStorage
.setCharIndex(firstGlyph
, id
, success
);
361 glyphStorage
.setCharIndex(lastGlyph
- 1, ib
, success
);
362 glyphStorage
.setCharIndex(lastGlyph
, ia
, success
);
366 if (lastGlyph
- firstGlyph
< 3) {
367 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
370 a
= glyphStorage
[firstGlyph
];
371 b
= glyphStorage
[firstGlyph
+ 1];
373 glyphStorage
[firstGlyph
] = glyphStorage
[lastGlyph
- 1];
374 glyphStorage
[firstGlyph
+ 1] = glyphStorage
[lastGlyph
];
376 glyphStorage
[lastGlyph
- 1] = a
;
377 glyphStorage
[lastGlyph
] = b
;
379 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
380 ib
= glyphStorage
.getCharIndex(firstGlyph
+ 1, success
);
381 ic
= glyphStorage
.getCharIndex(lastGlyph
- 1, success
);
382 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
384 glyphStorage
.setCharIndex(firstGlyph
, ic
, success
);
385 glyphStorage
.setCharIndex(firstGlyph
+ 1, id
, success
);
387 glyphStorage
.setCharIndex(lastGlyph
- 1, ia
, success
);
388 glyphStorage
.setCharIndex(lastGlyph
, ib
, success
);
392 if (lastGlyph
- firstGlyph
< 3) {
393 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
396 a
= glyphStorage
[firstGlyph
];
397 b
= glyphStorage
[firstGlyph
+ 1];
399 glyphStorage
[firstGlyph
] = glyphStorage
[lastGlyph
- 1];
400 glyphStorage
[firstGlyph
+ 1] = glyphStorage
[lastGlyph
];
402 glyphStorage
[lastGlyph
- 1] = b
;
403 glyphStorage
[lastGlyph
] = a
;
405 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
406 ib
= glyphStorage
.getCharIndex(firstGlyph
+ 1, success
);
407 ic
= glyphStorage
.getCharIndex(lastGlyph
- 1, success
);
408 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
410 glyphStorage
.setCharIndex(firstGlyph
, ic
, success
);
411 glyphStorage
.setCharIndex(firstGlyph
+ 1, id
, success
);
413 glyphStorage
.setCharIndex(lastGlyph
- 1, ib
, success
);
414 glyphStorage
.setCharIndex(lastGlyph
, ia
, success
);
418 if (lastGlyph
- firstGlyph
< 3) {
419 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
422 a
= glyphStorage
[firstGlyph
];
423 b
= glyphStorage
[firstGlyph
+ 1];
425 glyphStorage
[firstGlyph
] = glyphStorage
[lastGlyph
];
426 glyphStorage
[firstGlyph
+ 1] = glyphStorage
[lastGlyph
- 1];
428 glyphStorage
[lastGlyph
- 1] = a
;
429 glyphStorage
[lastGlyph
] = b
;
431 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
432 ib
= glyphStorage
.getCharIndex(firstGlyph
+ 1, success
);
433 ic
= glyphStorage
.getCharIndex(lastGlyph
- 1, success
);
434 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
436 glyphStorage
.setCharIndex(firstGlyph
, id
, success
);
437 glyphStorage
.setCharIndex(firstGlyph
+ 1, ic
, success
);
439 glyphStorage
.setCharIndex(lastGlyph
- 1, ia
, success
);
440 glyphStorage
.setCharIndex(lastGlyph
, ib
, success
);
444 if (lastGlyph
- firstGlyph
< 3) {
445 success
= LE_INDEX_OUT_OF_BOUNDS_ERROR
;
448 a
= glyphStorage
[firstGlyph
];
449 b
= glyphStorage
[firstGlyph
+ 1];
451 glyphStorage
[firstGlyph
] = glyphStorage
[lastGlyph
];
452 glyphStorage
[firstGlyph
+ 1] = glyphStorage
[lastGlyph
- 1];
454 glyphStorage
[lastGlyph
- 1] = b
;
455 glyphStorage
[lastGlyph
] = a
;
457 ia
= glyphStorage
.getCharIndex(firstGlyph
, success
);
458 ib
= glyphStorage
.getCharIndex(firstGlyph
+ 1, success
);
459 ic
= glyphStorage
.getCharIndex(lastGlyph
- 1, success
);
460 id
= glyphStorage
.getCharIndex(lastGlyph
, success
);
462 glyphStorage
.setCharIndex(firstGlyph
, id
, success
);
463 glyphStorage
.setCharIndex(firstGlyph
+ 1, ic
, success
);
465 glyphStorage
.setCharIndex(lastGlyph
- 1, ib
, success
);
466 glyphStorage
.setCharIndex(lastGlyph
, ia
, success
);