blob: a1c23319e9ecb1d399b873984edb45e0aafc97d8 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Sun designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Sun in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
22 * have any questions.
23 *
24 */
25
26/*
27 *
28 * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
29 *
30 */
31
32#include "LETypes.h"
33#include "MorphTables.h"
34#include "StateTables.h"
35#include "MorphStateTables.h"
36#include "SubtableProcessor.h"
37#include "StateTableProcessor.h"
38#include "IndicRearrangementProcessor.h"
39#include "LEGlyphStorage.h"
40#include "LESwaps.h"
41
42IndicRearrangementProcessor::IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader)
43 : StateTableProcessor(morphSubtableHeader)
44{
45 indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader *) morphSubtableHeader;
46 entryTable = (const IndicRearrangementStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
47}
48
49IndicRearrangementProcessor::~IndicRearrangementProcessor()
50{
51}
52
53void IndicRearrangementProcessor::beginStateTable()
54{
55 firstGlyph = 0;
56 lastGlyph = 0;
57}
58
59ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage,
60 le_int32 &currGlyph, EntryTableIndex index)
61{
62 const IndicRearrangementStateEntry *entry = &entryTable[index];
63 ByteOffset newState = SWAPW(entry->newStateOffset);
64 IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
65
66 if (flags & irfMarkFirst) {
67 firstGlyph = currGlyph;
68 }
69
70 if (flags & irfMarkLast) {
71 lastGlyph = currGlyph;
72 }
73
74 doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask));
75
76 if (!(flags & irfDontAdvance)) {
77 // XXX: Should handle reverse too...
78 currGlyph += 1;
79 }
80
81 return newState;
82}
83
84void IndicRearrangementProcessor::endStateTable()
85{
86}
87
88void IndicRearrangementProcessor::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const
89{
90 LEGlyphID a, b, c, d;
91 le_int32 ia, ib, ic, id, ix, x;
92 LEErrorCode success = LE_NO_ERROR;
93
94 switch(verb)
95 {
96 case irvNoAction:
97 break;
98
99 case irvxA:
100 a = glyphStorage[firstGlyph];
101 ia = glyphStorage.getCharIndex(firstGlyph, success);
102 x = firstGlyph + 1;
103
104 while (x <= lastGlyph) {
105 glyphStorage[x - 1] = glyphStorage[x];
106 ix = glyphStorage.getCharIndex(x, success);
107 glyphStorage.setCharIndex(x - 1, ix, success);
108 x += 1;
109 }
110
111 glyphStorage[lastGlyph] = a;
112 glyphStorage.setCharIndex(lastGlyph, ia, success);
113 break;
114
115 case irvDx:
116 d = glyphStorage[lastGlyph];
117 id = glyphStorage.getCharIndex(lastGlyph, success);
118 x = lastGlyph - 1;
119
120 while (x >= firstGlyph) {
121 glyphStorage[x + 1] = glyphStorage[x];
122 ix = glyphStorage.getCharIndex(x, success);
123 glyphStorage.setCharIndex(x + 1, ix, success);
124 x -= 1;
125 }
126
127 glyphStorage[firstGlyph] = d;
128 glyphStorage.setCharIndex(firstGlyph, id, success);
129 break;
130
131 case irvDxA:
132 a = glyphStorage[firstGlyph];
133 ia = glyphStorage.getCharIndex(firstGlyph, success);
134 id = glyphStorage.getCharIndex(lastGlyph, success);
135
136 glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
137 glyphStorage[lastGlyph] = a;
138
139 glyphStorage.setCharIndex(firstGlyph, id, success);
140 glyphStorage.setCharIndex(lastGlyph, ia, success);
141 break;
142
143 case irvxAB:
144 a = glyphStorage[firstGlyph];
145 b = glyphStorage[firstGlyph + 1];
146 ia = glyphStorage.getCharIndex(firstGlyph, success);
147 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
148 x = firstGlyph + 2;
149
150 while (x <= lastGlyph) {
151 glyphStorage[x - 2] = glyphStorage[x];
152 ix = glyphStorage.getCharIndex(x, success);
153 glyphStorage.setCharIndex(x - 2, ix, success);
154 x += 1;
155 }
156
157 glyphStorage[lastGlyph - 1] = a;
158 glyphStorage[lastGlyph] = b;
159
160 glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
161 glyphStorage.setCharIndex(lastGlyph, ib, success);
162 break;
163
164 case irvxBA:
165 a = glyphStorage[firstGlyph];
166 b = glyphStorage[firstGlyph + 1];
167 ia = glyphStorage.getCharIndex(firstGlyph, success);
168 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
169 x = firstGlyph + 2;
170
171 while (x <= lastGlyph) {
172 glyphStorage[x - 2] = glyphStorage[x];
173 ix = glyphStorage.getCharIndex(x, success);
174 glyphStorage.setCharIndex(x - 2, ix, success);
175 x += 1;
176 }
177
178 glyphStorage[lastGlyph - 1] = b;
179 glyphStorage[lastGlyph] = a;
180
181 glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
182 glyphStorage.setCharIndex(lastGlyph, ia, success);
183 break;
184
185 case irvCDx:
186 c = glyphStorage[lastGlyph - 1];
187 d = glyphStorage[lastGlyph];
188 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
189 id = glyphStorage.getCharIndex(lastGlyph, success);
190 x = lastGlyph - 2;
191
192 while (x >= firstGlyph) {
193 glyphStorage[x + 2] = glyphStorage[x];
194 ix = glyphStorage.getCharIndex(x, success);
195 glyphStorage.setCharIndex(x + 2, ix, success);
196 x -= 1;
197 }
198
199 glyphStorage[firstGlyph] = c;
200 glyphStorage[firstGlyph + 1] = d;
201
202 glyphStorage.setCharIndex(firstGlyph, ic, success);
203 glyphStorage.setCharIndex(firstGlyph + 1, id, success);
204 break;
205
206 case irvDCx:
207 c = glyphStorage[lastGlyph - 1];
208 d = glyphStorage[lastGlyph];
209 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
210 id = glyphStorage.getCharIndex(lastGlyph, success);
211 x = lastGlyph - 2;
212
213 while (x >= firstGlyph) {
214 glyphStorage[x + 2] = glyphStorage[x];
215 ix = glyphStorage.getCharIndex(x, success);
216 glyphStorage.setCharIndex(x + 2, ix, success);
217 x -= 1;
218 }
219
220 glyphStorage[firstGlyph] = d;
221 glyphStorage[firstGlyph + 1] = c;
222
223 glyphStorage.setCharIndex(firstGlyph, id, success);
224 glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
225 break;
226
227 case irvCDxA:
228 a = glyphStorage[firstGlyph];
229 c = glyphStorage[lastGlyph - 1];
230 d = glyphStorage[lastGlyph];
231 ia = glyphStorage.getCharIndex(firstGlyph, success);
232 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
233 id = glyphStorage.getCharIndex(lastGlyph, success);
234 x = lastGlyph - 2;
235
236 while (x > firstGlyph) {
237 glyphStorage[x + 1] = glyphStorage[x];
238 ix = glyphStorage.getCharIndex(x, success);
239 glyphStorage.setCharIndex(x + 1, ix, success);
240 x -= 1;
241 }
242
243 glyphStorage[firstGlyph] = c;
244 glyphStorage[firstGlyph + 1] = d;
245 glyphStorage[lastGlyph] = a;
246
247 glyphStorage.setCharIndex(firstGlyph, ic, success);
248 glyphStorage.setCharIndex(firstGlyph + 1, id, success);
249 glyphStorage.setCharIndex(lastGlyph, ia, success);
250 break;
251
252 case irvDCxA:
253 a = glyphStorage[firstGlyph];
254 c = glyphStorage[lastGlyph - 1];
255 d = glyphStorage[lastGlyph];
256 ia = glyphStorage.getCharIndex(firstGlyph, success);
257 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
258 id = glyphStorage.getCharIndex(lastGlyph, success);
259 x = lastGlyph - 2;
260
261 while (x > firstGlyph) {
262 glyphStorage[x + 1] = glyphStorage[x];
263 ix = glyphStorage.getCharIndex(x, success);
264 glyphStorage.setCharIndex(x + 1, ix, success);
265 x -= 1;
266 }
267
268 glyphStorage[firstGlyph] = d;
269 glyphStorage[firstGlyph + 1] = c;
270 glyphStorage[lastGlyph] = a;
271
272 glyphStorage.setCharIndex(firstGlyph, id, success);
273 glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
274 glyphStorage.setCharIndex(lastGlyph, ia, success);
275 break;
276
277 case irvDxAB:
278 a = glyphStorage[firstGlyph];
279 b = glyphStorage[firstGlyph + 1];
280 d = glyphStorage[lastGlyph];
281 ia = glyphStorage.getCharIndex(firstGlyph, success);
282 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
283 id = glyphStorage.getCharIndex(lastGlyph, success);
284 x = firstGlyph + 2;
285
286 while (x < lastGlyph) {
287 glyphStorage[x - 2] = glyphStorage[x];
288 ix = glyphStorage.getCharIndex(x, success);
289 glyphStorage.setCharIndex(x - 2, ix, success);
290 x += 1;
291 }
292
293 glyphStorage[firstGlyph] = d;
294 glyphStorage[lastGlyph - 1] = a;
295 glyphStorage[lastGlyph] = b;
296
297 glyphStorage.setCharIndex(firstGlyph, id, success);
298 glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
299 glyphStorage.setCharIndex(lastGlyph, ib, success);
300 break;
301
302 case irvDxBA:
303 a = glyphStorage[firstGlyph];
304 b = glyphStorage[firstGlyph + 1];
305 d = glyphStorage[lastGlyph];
306 ia = glyphStorage.getCharIndex(firstGlyph, success);
307 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
308 id = glyphStorage.getCharIndex(lastGlyph, success);
309 x = firstGlyph + 2;
310
311 while (x < lastGlyph) {
312 glyphStorage[x - 2] = glyphStorage[x];
313 ix = glyphStorage.getCharIndex(x, success);
314 glyphStorage.setCharIndex(x - 2, ix, success);
315 x += 1;
316 }
317
318 glyphStorage[firstGlyph] = d;
319 glyphStorage[lastGlyph - 1] = b;
320 glyphStorage[lastGlyph] = a;
321
322 glyphStorage.setCharIndex(firstGlyph, id, success);
323 glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
324 glyphStorage.setCharIndex(lastGlyph, ia, success);
325 break;
326
327 case irvCDxAB:
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] = a;
335 glyphStorage[lastGlyph] = b;
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, ia, success);
346 glyphStorage.setCharIndex(lastGlyph, ib, success);
347 break;
348
349 case irvCDxBA:
350 a = glyphStorage[firstGlyph];
351 b = glyphStorage[firstGlyph + 1];
352
353 glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
354 glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
355
356 glyphStorage[lastGlyph - 1] = b;
357 glyphStorage[lastGlyph] = a;
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, ic, success);
365 glyphStorage.setCharIndex(firstGlyph + 1, id, success);
366
367 glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
368 glyphStorage.setCharIndex(lastGlyph, ia, success);
369 break;
370
371 case irvDCxAB:
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] = a;
379 glyphStorage[lastGlyph] = b;
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, ia, success);
390 glyphStorage.setCharIndex(lastGlyph, ib, success);
391 break;
392
393 case irvDCxBA:
394 a = glyphStorage[firstGlyph];
395 b = glyphStorage[firstGlyph + 1];
396
397 glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
398 glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
399
400 glyphStorage[lastGlyph - 1] = b;
401 glyphStorage[lastGlyph] = a;
402
403 ia = glyphStorage.getCharIndex(firstGlyph, success);
404 ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
405 ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
406 id = glyphStorage.getCharIndex(lastGlyph, success);
407
408 glyphStorage.setCharIndex(firstGlyph, id, success);
409 glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
410
411 glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
412 glyphStorage.setCharIndex(lastGlyph, ia, success);
413 break;
414
415 default:
416 break;
417 }
418}