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