1 /* 2 * 3 * (C) Copyright IBM Corp. and others 1998-2014 - 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( 22 const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) 23 : StateTableProcessor2(morphSubtableHeader, success), entryTable(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY), 24 indicRearrangementSubtableHeader(morphSubtableHeader, success) 25 { 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, 39 EntryTableIndex2 index, LEErrorCode &success) 40 { 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); 45 46 if (flags & irfMarkFirst) { 47 firstGlyph = currGlyph; 48 } 49 50 if (flags & irfMarkLast) { 51 lastGlyph = currGlyph; 52 } 53 54 doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask)); 55 56 if (!(flags & irfDontAdvance)) { 57 currGlyph += dir; 58 } 59 60 return newState; // index to new state 61 } 62 63 void IndicRearrangementProcessor2::endStateTable() 64 { 65 } 66 67 void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const 68 { 69 LEGlyphID a, b, c, d; 70 le_int32 ia, ib, ic, id, ix, x; 71 LEErrorCode success = LE_NO_ERROR; 72 73 switch(verb) 74 { 75 case irvNoAction: 76 break; 77 78 case irvxA: 79 a = glyphStorage[firstGlyph]; 80 ia = glyphStorage.getCharIndex(firstGlyph, success); 81 x = firstGlyph + 1; 82 83 while (x <= lastGlyph) { 84 glyphStorage[x - 1] = glyphStorage[x]; 85 ix = glyphStorage.getCharIndex(x, success); 86 glyphStorage.setCharIndex(x - 1, ix, success); 87 x += 1; 88 } 89 90 glyphStorage[lastGlyph] = a; 91 glyphStorage.setCharIndex(lastGlyph, ia, success); 92 break; 93 94 case irvDx: 95 d = glyphStorage[lastGlyph]; 96 id = glyphStorage.getCharIndex(lastGlyph, success); 97 x = lastGlyph - 1; 98 99 while (x >= firstGlyph) { 100 glyphStorage[x + 1] = glyphStorage[x]; 101 ix = glyphStorage.getCharIndex(x, success); 102 glyphStorage.setCharIndex(x + 1, ix, success); 103 x -= 1; 104 } 105 106 glyphStorage[firstGlyph] = d; 107 glyphStorage.setCharIndex(firstGlyph, id, success); 108 break; 109 110 case irvDxA: 111 a = glyphStorage[firstGlyph]; 112 ia = glyphStorage.getCharIndex(firstGlyph, success); 113 id = glyphStorage.getCharIndex(lastGlyph, success); 114 115 glyphStorage[firstGlyph] = glyphStorage[lastGlyph]; 116 glyphStorage[lastGlyph] = a; 117 118 glyphStorage.setCharIndex(firstGlyph, id, success); 119 glyphStorage.setCharIndex(lastGlyph, ia, success); 120 break; 121 122 case irvxAB: 123 a = glyphStorage[firstGlyph]; 124 b = glyphStorage[firstGlyph + 1]; 125 ia = glyphStorage.getCharIndex(firstGlyph, success); 126 ib = glyphStorage.getCharIndex(firstGlyph + 1, success); 127 x = firstGlyph + 2; 128 129 while (x <= lastGlyph) { 130 glyphStorage[x - 2] = glyphStorage[x]; 131 ix = glyphStorage.getCharIndex(x, success); 132 glyphStorage.setCharIndex(x - 2, ix, success); 133 x += 1; 134 } 135 136 glyphStorage[lastGlyph - 1] = a; 137 glyphStorage[lastGlyph] = b; 138 139 glyphStorage.setCharIndex(lastGlyph - 1, ia, success); 140 glyphStorage.setCharIndex(lastGlyph, ib, success); 141 break; 142 143 case irvxBA: 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] = b; 158 glyphStorage[lastGlyph] = a; 159 160 glyphStorage.setCharIndex(lastGlyph - 1, ib, success); 161 glyphStorage.setCharIndex(lastGlyph, ia, success); 162 break; 163 164 case irvCDx: 165 c = glyphStorage[lastGlyph - 1]; 166 d = glyphStorage[lastGlyph]; 167 ic = glyphStorage.getCharIndex(lastGlyph - 1, success); 168 id = glyphStorage.getCharIndex(lastGlyph, success); 169 x = lastGlyph - 2; 170 171 while (x >= firstGlyph) { 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[firstGlyph] = c; 179 glyphStorage[firstGlyph + 1] = d; 180 181 glyphStorage.setCharIndex(firstGlyph, ic, success); 182 glyphStorage.setCharIndex(firstGlyph + 1, id, success); 183 break; 184 185 case irvDCx: 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] = d; 200 glyphStorage[firstGlyph + 1] = c; 201 202 glyphStorage.setCharIndex(firstGlyph, id, success); 203 glyphStorage.setCharIndex(firstGlyph + 1, ic, success); 204 break; 205 206 case irvCDxA: 207 a = glyphStorage[firstGlyph]; 208 c = glyphStorage[lastGlyph - 1]; 209 d = glyphStorage[lastGlyph]; 210 ia = glyphStorage.getCharIndex(firstGlyph, success); 211 ic = glyphStorage.getCharIndex(lastGlyph - 1, success); 212 id = glyphStorage.getCharIndex(lastGlyph, success); 213 x = lastGlyph - 2; 214 215 while (x > firstGlyph) { 216 glyphStorage[x + 1] = glyphStorage[x]; 217 ix = glyphStorage.getCharIndex(x, success); 218 glyphStorage.setCharIndex(x + 1, ix, success); 219 x -= 1; 220 } 221 222 glyphStorage[firstGlyph] = c; 223 glyphStorage[firstGlyph + 1] = d; 224 glyphStorage[lastGlyph] = a; 225 226 glyphStorage.setCharIndex(firstGlyph, ic, success); 227 glyphStorage.setCharIndex(firstGlyph + 1, id, success); 228 glyphStorage.setCharIndex(lastGlyph, ia, success); 229 break; 230 231 case irvDCxA: 232 a = glyphStorage[firstGlyph]; 233 c = glyphStorage[lastGlyph - 1]; 234 d = glyphStorage[lastGlyph]; 235 ia = glyphStorage.getCharIndex(firstGlyph, success); 236 ic = glyphStorage.getCharIndex(lastGlyph - 1, success); 237 id = glyphStorage.getCharIndex(lastGlyph, success); 238 x = lastGlyph - 2; 239 240 while (x > firstGlyph) { 241 glyphStorage[x + 1] = glyphStorage[x]; 242 ix = glyphStorage.getCharIndex(x, success); 243 glyphStorage.setCharIndex(x + 1, ix, success); 244 x -= 1; 245 } 246 247 glyphStorage[firstGlyph] = d; 248 glyphStorage[firstGlyph + 1] = c; 249 glyphStorage[lastGlyph] = a; 250 251 glyphStorage.setCharIndex(firstGlyph, id, success); 252 glyphStorage.setCharIndex(firstGlyph + 1, ic, success); 253 glyphStorage.setCharIndex(lastGlyph, ia, success); 254 break; 255 256 case irvDxAB: 257 a = glyphStorage[firstGlyph]; 258 b = glyphStorage[firstGlyph + 1]; 259 d = glyphStorage[lastGlyph]; 260 ia = glyphStorage.getCharIndex(firstGlyph, success); 261 ib = glyphStorage.getCharIndex(firstGlyph + 1, success); 262 id = glyphStorage.getCharIndex(lastGlyph, success); 263 x = firstGlyph + 2; 264 265 while (x < lastGlyph) { 266 glyphStorage[x - 2] = glyphStorage[x]; 267 ix = glyphStorage.getCharIndex(x, success); 268 glyphStorage.setCharIndex(x - 2, ix, success); 269 x += 1; 270 } 271 272 glyphStorage[firstGlyph] = d; 273 glyphStorage[lastGlyph - 1] = a; 274 glyphStorage[lastGlyph] = b; 275 276 glyphStorage.setCharIndex(firstGlyph, id, success); 277 glyphStorage.setCharIndex(lastGlyph - 1, ia, success); 278 glyphStorage.setCharIndex(lastGlyph, ib, success); 279 break; 280 281 case irvDxBA: 282 a = glyphStorage[firstGlyph]; 283 b = glyphStorage[firstGlyph + 1]; 284 d = glyphStorage[lastGlyph]; 285 ia = glyphStorage.getCharIndex(firstGlyph, success); 286 ib = glyphStorage.getCharIndex(firstGlyph + 1, success); 287 id = glyphStorage.getCharIndex(lastGlyph, success); 288 x = firstGlyph + 2; 289 290 while (x < lastGlyph) { 291 glyphStorage[x - 2] = glyphStorage[x]; 292 ix = glyphStorage.getCharIndex(x, success); 293 glyphStorage.setCharIndex(x - 2, ix, success); 294 x += 1; 295 } 296 297 glyphStorage[firstGlyph] = d; 298 glyphStorage[lastGlyph - 1] = b; 299 glyphStorage[lastGlyph] = a; 300 301 glyphStorage.setCharIndex(firstGlyph, id, success); 302 glyphStorage.setCharIndex(lastGlyph - 1, ib, success); 303 glyphStorage.setCharIndex(lastGlyph, ia, success); 304 break; 305 306 case irvCDxAB: 307 a = glyphStorage[firstGlyph]; 308 b = glyphStorage[firstGlyph + 1]; 309 310 glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1]; 311 glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph]; 312 313 glyphStorage[lastGlyph - 1] = a; 314 glyphStorage[lastGlyph] = b; 315 316 ia = glyphStorage.getCharIndex(firstGlyph, success); 317 ib = glyphStorage.getCharIndex(firstGlyph + 1, success); 318 ic = glyphStorage.getCharIndex(lastGlyph - 1, success); 319 id = glyphStorage.getCharIndex(lastGlyph, success); 320 321 glyphStorage.setCharIndex(firstGlyph, ic, success); 322 glyphStorage.setCharIndex(firstGlyph + 1, id, success); 323 324 glyphStorage.setCharIndex(lastGlyph - 1, ia, success); 325 glyphStorage.setCharIndex(lastGlyph, ib, success); 326 break; 327 328 case irvCDxBA: 329 a = glyphStorage[firstGlyph]; 330 b = glyphStorage[firstGlyph + 1]; 331 332 glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1]; 333 glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph]; 334 335 glyphStorage[lastGlyph - 1] = b; 336 glyphStorage[lastGlyph] = a; 337 338 ia = glyphStorage.getCharIndex(firstGlyph, success); 339 ib = glyphStorage.getCharIndex(firstGlyph + 1, success); 340 ic = glyphStorage.getCharIndex(lastGlyph - 1, success); 341 id = glyphStorage.getCharIndex(lastGlyph, success); 342 343 glyphStorage.setCharIndex(firstGlyph, ic, success); 344 glyphStorage.setCharIndex(firstGlyph + 1, id, success); 345 346 glyphStorage.setCharIndex(lastGlyph - 1, ib, success); 347 glyphStorage.setCharIndex(lastGlyph, ia, success); 348 break; 349 350 case irvDCxAB: 351 a = glyphStorage[firstGlyph]; 352 b = glyphStorage[firstGlyph + 1]; 353 354 glyphStorage[firstGlyph] = glyphStorage[lastGlyph]; 355 glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1]; 356 357 glyphStorage[lastGlyph - 1] = a; 358 glyphStorage[lastGlyph] = b; 359 360 ia = glyphStorage.getCharIndex(firstGlyph, success); 361 ib = glyphStorage.getCharIndex(firstGlyph + 1, success); 362 ic = glyphStorage.getCharIndex(lastGlyph - 1, success); 363 id = glyphStorage.getCharIndex(lastGlyph, success); 364 365 glyphStorage.setCharIndex(firstGlyph, id, success); 366 glyphStorage.setCharIndex(firstGlyph + 1, ic, success); 367 368 glyphStorage.setCharIndex(lastGlyph - 1, ia, success); 369 glyphStorage.setCharIndex(lastGlyph, ib, success); 370 break; 371 372 case irvDCxBA: 373 a = glyphStorage[firstGlyph]; 374 b = glyphStorage[firstGlyph + 1]; 375 376 glyphStorage[firstGlyph] = glyphStorage[lastGlyph]; 377 glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1]; 378 379 glyphStorage[lastGlyph - 1] = b; 380 glyphStorage[lastGlyph] = a; 381 382 ia = glyphStorage.getCharIndex(firstGlyph, success); 383 ib = glyphStorage.getCharIndex(firstGlyph + 1, success); 384 ic = glyphStorage.getCharIndex(lastGlyph - 1, success); 385 id = glyphStorage.getCharIndex(lastGlyph, success); 386 387 glyphStorage.setCharIndex(firstGlyph, id, success); 388 glyphStorage.setCharIndex(firstGlyph + 1, ic, success); 389 390 glyphStorage.setCharIndex(lastGlyph - 1, ib, success); 391 glyphStorage.setCharIndex(lastGlyph, ia, success); 392 break; 393 394 default: 395 break; 396 } 397 398 } 399 400 U_NAMESPACE_END 401