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 399