os/textandloc/fontservices/textshaperplugin/IcuSource/layout/IndicRearrangementProcessor.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/fontservices/textshaperplugin/IcuSource/layout/IndicRearrangementProcessor.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,398 @@
1.4 +/*
1.5 + *
1.6 + * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
1.7 + *
1.8 + */
1.9 +
1.10 +#include "LETypes.h"
1.11 +#include "MorphTables.h"
1.12 +#include "StateTables.h"
1.13 +#include "MorphStateTables.h"
1.14 +#include "SubtableProcessor.h"
1.15 +#include "StateTableProcessor.h"
1.16 +#include "IndicRearrangementProcessor.h"
1.17 +#include "LEGlyphStorage.h"
1.18 +#include "LESwaps.h"
1.19 +
1.20 +U_NAMESPACE_BEGIN
1.21 +
1.22 +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor)
1.23 +
1.24 +IndicRearrangementProcessor::IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader)
1.25 + : StateTableProcessor(morphSubtableHeader)
1.26 +{
1.27 + indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader *) morphSubtableHeader;
1.28 + entryTable = (const IndicRearrangementStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
1.29 +}
1.30 +
1.31 +IndicRearrangementProcessor::~IndicRearrangementProcessor()
1.32 +{
1.33 +}
1.34 +
1.35 +void IndicRearrangementProcessor::beginStateTable()
1.36 +{
1.37 + firstGlyph = 0;
1.38 + lastGlyph = 0;
1.39 +}
1.40 +
1.41 +ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
1.42 +{
1.43 + const IndicRearrangementStateEntry *entry = &entryTable[index];
1.44 + ByteOffset newState = SWAPW(entry->newStateOffset);
1.45 + IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
1.46 +
1.47 + if (flags & irfMarkFirst) {
1.48 + firstGlyph = currGlyph;
1.49 + }
1.50 +
1.51 + if (flags & irfMarkLast) {
1.52 + lastGlyph = currGlyph;
1.53 + }
1.54 +
1.55 + doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask));
1.56 +
1.57 + if (!(flags & irfDontAdvance)) {
1.58 + // XXX: Should handle reverse too...
1.59 + currGlyph += 1;
1.60 + }
1.61 +
1.62 + return newState;
1.63 +}
1.64 +
1.65 +void IndicRearrangementProcessor::endStateTable()
1.66 +{
1.67 +}
1.68 +
1.69 +void IndicRearrangementProcessor::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const
1.70 +{
1.71 + LEGlyphID a, b, c, d;
1.72 + le_int32 ia, ib, ic, id, ix, x;
1.73 + LEErrorCode success = LE_NO_ERROR;
1.74 +
1.75 + switch(verb)
1.76 + {
1.77 + case irvNoAction:
1.78 + break;
1.79 +
1.80 + case irvxA:
1.81 + a = glyphStorage[firstGlyph];
1.82 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.83 + x = firstGlyph + 1;
1.84 +
1.85 + while (x <= lastGlyph) {
1.86 + glyphStorage[x - 1] = glyphStorage[x];
1.87 + ix = glyphStorage.getCharIndex(x, success);
1.88 + glyphStorage.setCharIndex(x - 1, ix, success);
1.89 + x += 1;
1.90 + }
1.91 +
1.92 + glyphStorage[lastGlyph] = a;
1.93 + glyphStorage.setCharIndex(lastGlyph, ia, success);
1.94 + break;
1.95 +
1.96 + case irvDx:
1.97 + d = glyphStorage[lastGlyph];
1.98 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.99 + x = lastGlyph - 1;
1.100 +
1.101 + while (x >= firstGlyph) {
1.102 + glyphStorage[x + 1] = glyphStorage[x];
1.103 + ix = glyphStorage.getCharIndex(x, success);
1.104 + glyphStorage.setCharIndex(x + 1, ix, success);
1.105 + x -= 1;
1.106 + }
1.107 +
1.108 + glyphStorage[firstGlyph] = d;
1.109 + glyphStorage.setCharIndex(firstGlyph, id, success);
1.110 + break;
1.111 +
1.112 + case irvDxA:
1.113 + a = glyphStorage[firstGlyph];
1.114 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.115 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.116 +
1.117 + glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
1.118 + glyphStorage[lastGlyph] = a;
1.119 +
1.120 + glyphStorage.setCharIndex(firstGlyph, id, success);
1.121 + glyphStorage.setCharIndex(lastGlyph, ia, success);
1.122 + break;
1.123 +
1.124 + case irvxAB:
1.125 + a = glyphStorage[firstGlyph];
1.126 + b = glyphStorage[firstGlyph + 1];
1.127 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.128 + ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
1.129 + x = firstGlyph + 2;
1.130 +
1.131 + while (x <= lastGlyph) {
1.132 + glyphStorage[x - 2] = glyphStorage[x];
1.133 + ix = glyphStorage.getCharIndex(x, success);
1.134 + glyphStorage.setCharIndex(x - 2, ix, success);
1.135 + x += 1;
1.136 + }
1.137 +
1.138 + glyphStorage[lastGlyph - 1] = a;
1.139 + glyphStorage[lastGlyph] = b;
1.140 +
1.141 + glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
1.142 + glyphStorage.setCharIndex(lastGlyph, ib, success);
1.143 + break;
1.144 +
1.145 + case irvxBA:
1.146 + a = glyphStorage[firstGlyph];
1.147 + b = glyphStorage[firstGlyph + 1];
1.148 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.149 + ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
1.150 + x = firstGlyph + 2;
1.151 +
1.152 + while (x <= lastGlyph) {
1.153 + glyphStorage[x - 2] = glyphStorage[x];
1.154 + ix = glyphStorage.getCharIndex(x, success);
1.155 + glyphStorage.setCharIndex(x - 2, ix, success);
1.156 + x += 1;
1.157 + }
1.158 +
1.159 + glyphStorage[lastGlyph - 1] = b;
1.160 + glyphStorage[lastGlyph] = a;
1.161 +
1.162 + glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
1.163 + glyphStorage.setCharIndex(lastGlyph, ia, success);
1.164 + break;
1.165 +
1.166 + case irvCDx:
1.167 + c = glyphStorage[lastGlyph - 1];
1.168 + d = glyphStorage[lastGlyph];
1.169 + ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
1.170 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.171 + x = lastGlyph - 2;
1.172 +
1.173 + while (x >= firstGlyph) {
1.174 + glyphStorage[x + 2] = glyphStorage[x];
1.175 + ix = glyphStorage.getCharIndex(x, success);
1.176 + glyphStorage.setCharIndex(x + 2, ix, success);
1.177 + x -= 1;
1.178 + }
1.179 +
1.180 + glyphStorage[firstGlyph] = c;
1.181 + glyphStorage[firstGlyph + 1] = d;
1.182 +
1.183 + glyphStorage.setCharIndex(firstGlyph, ic, success);
1.184 + glyphStorage.setCharIndex(firstGlyph + 1, id, success);
1.185 + break;
1.186 +
1.187 + case irvDCx:
1.188 + c = glyphStorage[lastGlyph - 1];
1.189 + d = glyphStorage[lastGlyph];
1.190 + ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
1.191 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.192 + x = lastGlyph - 2;
1.193 +
1.194 + while (x >= firstGlyph) {
1.195 + glyphStorage[x + 2] = glyphStorage[x];
1.196 + ix = glyphStorage.getCharIndex(x, success);
1.197 + glyphStorage.setCharIndex(x + 2, ix, success);
1.198 + x -= 1;
1.199 + }
1.200 +
1.201 + glyphStorage[firstGlyph] = d;
1.202 + glyphStorage[firstGlyph + 1] = c;
1.203 +
1.204 + glyphStorage.setCharIndex(firstGlyph, id, success);
1.205 + glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
1.206 + break;
1.207 +
1.208 + case irvCDxA:
1.209 + a = glyphStorage[firstGlyph];
1.210 + c = glyphStorage[lastGlyph - 1];
1.211 + d = glyphStorage[lastGlyph];
1.212 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.213 + ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
1.214 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.215 + x = lastGlyph - 2;
1.216 +
1.217 + while (x > firstGlyph) {
1.218 + glyphStorage[x + 1] = glyphStorage[x];
1.219 + ix = glyphStorage.getCharIndex(x, success);
1.220 + glyphStorage.setCharIndex(x + 1, ix, success);
1.221 + x -= 1;
1.222 + }
1.223 +
1.224 + glyphStorage[firstGlyph] = c;
1.225 + glyphStorage[firstGlyph + 1] = d;
1.226 + glyphStorage[lastGlyph] = a;
1.227 +
1.228 + glyphStorage.setCharIndex(firstGlyph, ic, success);
1.229 + glyphStorage.setCharIndex(firstGlyph + 1, id, success);
1.230 + glyphStorage.setCharIndex(lastGlyph, ia, success);
1.231 + break;
1.232 +
1.233 + case irvDCxA:
1.234 + a = glyphStorage[firstGlyph];
1.235 + c = glyphStorage[lastGlyph - 1];
1.236 + d = glyphStorage[lastGlyph];
1.237 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.238 + ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
1.239 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.240 + x = lastGlyph - 2;
1.241 +
1.242 + while (x > firstGlyph) {
1.243 + glyphStorage[x + 1] = glyphStorage[x];
1.244 + ix = glyphStorage.getCharIndex(x, success);
1.245 + glyphStorage.setCharIndex(x + 1, ix, success);
1.246 + x -= 1;
1.247 + }
1.248 +
1.249 + glyphStorage[firstGlyph] = d;
1.250 + glyphStorage[firstGlyph + 1] = c;
1.251 + glyphStorage[lastGlyph] = a;
1.252 +
1.253 + glyphStorage.setCharIndex(firstGlyph, id, success);
1.254 + glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
1.255 + glyphStorage.setCharIndex(lastGlyph, ia, success);
1.256 + break;
1.257 +
1.258 + case irvDxAB:
1.259 + a = glyphStorage[firstGlyph];
1.260 + b = glyphStorage[firstGlyph + 1];
1.261 + d = glyphStorage[lastGlyph];
1.262 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.263 + ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
1.264 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.265 + x = firstGlyph + 2;
1.266 +
1.267 + while (x < lastGlyph) {
1.268 + glyphStorage[x - 2] = glyphStorage[x];
1.269 + ix = glyphStorage.getCharIndex(x, success);
1.270 + glyphStorage.setCharIndex(x - 2, ix, success);
1.271 + x += 1;
1.272 + }
1.273 +
1.274 + glyphStorage[firstGlyph] = d;
1.275 + glyphStorage[lastGlyph - 1] = a;
1.276 + glyphStorage[lastGlyph] = b;
1.277 +
1.278 + glyphStorage.setCharIndex(firstGlyph, id, success);
1.279 + glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
1.280 + glyphStorage.setCharIndex(lastGlyph, ib, success);
1.281 + break;
1.282 +
1.283 + case irvDxBA:
1.284 + a = glyphStorage[firstGlyph];
1.285 + b = glyphStorage[firstGlyph + 1];
1.286 + d = glyphStorage[lastGlyph];
1.287 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.288 + ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
1.289 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.290 + x = firstGlyph + 2;
1.291 +
1.292 + while (x < lastGlyph) {
1.293 + glyphStorage[x - 2] = glyphStorage[x];
1.294 + ix = glyphStorage.getCharIndex(x, success);
1.295 + glyphStorage.setCharIndex(x - 2, ix, success);
1.296 + x += 1;
1.297 + }
1.298 +
1.299 + glyphStorage[firstGlyph] = d;
1.300 + glyphStorage[lastGlyph - 1] = b;
1.301 + glyphStorage[lastGlyph] = a;
1.302 +
1.303 + glyphStorage.setCharIndex(firstGlyph, id, success);
1.304 + glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
1.305 + glyphStorage.setCharIndex(lastGlyph, ia, success);
1.306 + break;
1.307 +
1.308 + case irvCDxAB:
1.309 + a = glyphStorage[firstGlyph];
1.310 + b = glyphStorage[firstGlyph + 1];
1.311 +
1.312 + glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
1.313 + glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
1.314 +
1.315 + glyphStorage[lastGlyph - 1] = a;
1.316 + glyphStorage[lastGlyph] = b;
1.317 +
1.318 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.319 + ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
1.320 + ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
1.321 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.322 +
1.323 + glyphStorage.setCharIndex(firstGlyph, ic, success);
1.324 + glyphStorage.setCharIndex(firstGlyph + 1, id, success);
1.325 +
1.326 + glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
1.327 + glyphStorage.setCharIndex(lastGlyph, ib, success);
1.328 + break;
1.329 +
1.330 + case irvCDxBA:
1.331 + a = glyphStorage[firstGlyph];
1.332 + b = glyphStorage[firstGlyph + 1];
1.333 +
1.334 + glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
1.335 + glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
1.336 +
1.337 + glyphStorage[lastGlyph - 1] = b;
1.338 + glyphStorage[lastGlyph] = a;
1.339 +
1.340 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.341 + ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
1.342 + ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
1.343 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.344 +
1.345 + glyphStorage.setCharIndex(firstGlyph, ic, success);
1.346 + glyphStorage.setCharIndex(firstGlyph + 1, id, success);
1.347 +
1.348 + glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
1.349 + glyphStorage.setCharIndex(lastGlyph, ia, success);
1.350 + break;
1.351 +
1.352 + case irvDCxAB:
1.353 + a = glyphStorage[firstGlyph];
1.354 + b = glyphStorage[firstGlyph + 1];
1.355 +
1.356 + glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
1.357 + glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
1.358 +
1.359 + glyphStorage[lastGlyph - 1] = a;
1.360 + glyphStorage[lastGlyph] = b;
1.361 +
1.362 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.363 + ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
1.364 + ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
1.365 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.366 +
1.367 + glyphStorage.setCharIndex(firstGlyph, id, success);
1.368 + glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
1.369 +
1.370 + glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
1.371 + glyphStorage.setCharIndex(lastGlyph, ib, success);
1.372 + break;
1.373 +
1.374 + case irvDCxBA:
1.375 + a = glyphStorage[firstGlyph];
1.376 + b = glyphStorage[firstGlyph + 1];
1.377 +
1.378 + glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
1.379 + glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
1.380 +
1.381 + glyphStorage[lastGlyph - 1] = b;
1.382 + glyphStorage[lastGlyph] = a;
1.383 +
1.384 + ia = glyphStorage.getCharIndex(firstGlyph, success);
1.385 + ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
1.386 + ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
1.387 + id = glyphStorage.getCharIndex(lastGlyph, success);
1.388 +
1.389 + glyphStorage.setCharIndex(firstGlyph, id, success);
1.390 + glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
1.391 +
1.392 + glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
1.393 + glyphStorage.setCharIndex(lastGlyph, ia, success);
1.394 + break;
1.395 +
1.396 + default:
1.397 + break;
1.398 + }
1.399 +}
1.400 +
1.401 +U_NAMESPACE_END