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