0N/A/*
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A *
0N/A */
0N/A
0N/A/*
0N/A *
0N/A * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
0N/A *
0N/A */
0N/A
0N/A#include "LETypes.h"
0N/A#include "MorphTables.h"
0N/A#include "StateTables.h"
0N/A#include "MorphStateTables.h"
0N/A#include "SubtableProcessor.h"
0N/A#include "StateTableProcessor.h"
0N/A#include "IndicRearrangementProcessor.h"
0N/A#include "LEGlyphStorage.h"
0N/A#include "LESwaps.h"
0N/A
1693N/AU_NAMESPACE_BEGIN
1693N/A
1693N/AUOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor)
1693N/A
5980N/A IndicRearrangementProcessor::IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
5980N/A : StateTableProcessor(morphSubtableHeader, success),
5980N/A indicRearrangementSubtableHeader(morphSubtableHeader, success),
5980N/A entryTable(stateTableHeader, success, (const IndicRearrangementStateEntry*)(&stateTableHeader->stHeader),
5980N/A entryTableOffset, LE_UNBOUNDED_ARRAY),
5980N/A int16Table(stateTableHeader, success, (const le_int16*)entryTable.getAlias(), 0, LE_UNBOUNDED_ARRAY)
5980N/A
0N/A{
0N/A}
0N/A
0N/AIndicRearrangementProcessor::~IndicRearrangementProcessor()
0N/A{
0N/A}
0N/A
0N/Avoid IndicRearrangementProcessor::beginStateTable()
0N/A{
0N/A firstGlyph = 0;
0N/A lastGlyph = 0;
0N/A}
0N/A
1693N/AByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
0N/A{
5980N/A LEErrorCode success = LE_NO_ERROR; // todo- make a param?
5980N/A const IndicRearrangementStateEntry *entry = entryTable.getAlias(index,success);
0N/A ByteOffset newState = SWAPW(entry->newStateOffset);
0N/A IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
0N/A
0N/A if (flags & irfMarkFirst) {
0N/A firstGlyph = currGlyph;
0N/A }
0N/A
0N/A if (flags & irfMarkLast) {
0N/A lastGlyph = currGlyph;
0N/A }
0N/A
0N/A doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask));
0N/A
0N/A if (!(flags & irfDontAdvance)) {
0N/A // XXX: Should handle reverse too...
0N/A currGlyph += 1;
0N/A }
0N/A
0N/A return newState;
0N/A}
0N/A
0N/Avoid IndicRearrangementProcessor::endStateTable()
0N/A{
0N/A}
0N/A
0N/Avoid IndicRearrangementProcessor::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const
0N/A{
0N/A LEGlyphID a, b, c, d;
0N/A le_int32 ia, ib, ic, id, ix, x;
0N/A LEErrorCode success = LE_NO_ERROR;
0N/A
0N/A switch(verb)
0N/A {
0N/A case irvNoAction:
0N/A break;
0N/A
0N/A case irvxA:
0N/A a = glyphStorage[firstGlyph];
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A x = firstGlyph + 1;
0N/A
0N/A while (x <= lastGlyph) {
0N/A glyphStorage[x - 1] = glyphStorage[x];
0N/A ix = glyphStorage.getCharIndex(x, success);
0N/A glyphStorage.setCharIndex(x - 1, ix, success);
0N/A x += 1;
0N/A }
0N/A
0N/A glyphStorage[lastGlyph] = a;
0N/A glyphStorage.setCharIndex(lastGlyph, ia, success);
0N/A break;
0N/A
0N/A case irvDx:
0N/A d = glyphStorage[lastGlyph];
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A x = lastGlyph - 1;
0N/A
0N/A while (x >= firstGlyph) {
0N/A glyphStorage[x + 1] = glyphStorage[x];
0N/A ix = glyphStorage.getCharIndex(x, success);
0N/A glyphStorage.setCharIndex(x + 1, ix, success);
0N/A x -= 1;
0N/A }
0N/A
0N/A glyphStorage[firstGlyph] = d;
0N/A glyphStorage.setCharIndex(firstGlyph, id, success);
0N/A break;
0N/A
0N/A case irvDxA:
0N/A a = glyphStorage[firstGlyph];
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A
0N/A glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
0N/A glyphStorage[lastGlyph] = a;
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, id, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ia, success);
0N/A break;
0N/A
0N/A case irvxAB:
0N/A a = glyphStorage[firstGlyph];
0N/A b = glyphStorage[firstGlyph + 1];
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
0N/A x = firstGlyph + 2;
0N/A
0N/A while (x <= lastGlyph) {
0N/A glyphStorage[x - 2] = glyphStorage[x];
0N/A ix = glyphStorage.getCharIndex(x, success);
0N/A glyphStorage.setCharIndex(x - 2, ix, success);
0N/A x += 1;
0N/A }
0N/A
0N/A glyphStorage[lastGlyph - 1] = a;
0N/A glyphStorage[lastGlyph] = b;
0N/A
0N/A glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ib, success);
0N/A break;
0N/A
0N/A case irvxBA:
0N/A a = glyphStorage[firstGlyph];
0N/A b = glyphStorage[firstGlyph + 1];
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
0N/A x = firstGlyph + 2;
0N/A
0N/A while (x <= lastGlyph) {
0N/A glyphStorage[x - 2] = glyphStorage[x];
0N/A ix = glyphStorage.getCharIndex(x, success);
0N/A glyphStorage.setCharIndex(x - 2, ix, success);
0N/A x += 1;
0N/A }
0N/A
0N/A glyphStorage[lastGlyph - 1] = b;
0N/A glyphStorage[lastGlyph] = a;
0N/A
0N/A glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ia, success);
0N/A break;
0N/A
0N/A case irvCDx:
0N/A c = glyphStorage[lastGlyph - 1];
0N/A d = glyphStorage[lastGlyph];
0N/A ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A x = lastGlyph - 2;
0N/A
0N/A while (x >= firstGlyph) {
0N/A glyphStorage[x + 2] = glyphStorage[x];
0N/A ix = glyphStorage.getCharIndex(x, success);
0N/A glyphStorage.setCharIndex(x + 2, ix, success);
0N/A x -= 1;
0N/A }
0N/A
0N/A glyphStorage[firstGlyph] = c;
0N/A glyphStorage[firstGlyph + 1] = d;
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, ic, success);
0N/A glyphStorage.setCharIndex(firstGlyph + 1, id, success);
0N/A break;
0N/A
0N/A case irvDCx:
0N/A c = glyphStorage[lastGlyph - 1];
0N/A d = glyphStorage[lastGlyph];
0N/A ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A x = lastGlyph - 2;
0N/A
0N/A while (x >= firstGlyph) {
0N/A glyphStorage[x + 2] = glyphStorage[x];
0N/A ix = glyphStorage.getCharIndex(x, success);
0N/A glyphStorage.setCharIndex(x + 2, ix, success);
0N/A x -= 1;
0N/A }
0N/A
0N/A glyphStorage[firstGlyph] = d;
0N/A glyphStorage[firstGlyph + 1] = c;
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, id, success);
0N/A glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
0N/A break;
0N/A
0N/A case irvCDxA:
0N/A a = glyphStorage[firstGlyph];
0N/A c = glyphStorage[lastGlyph - 1];
0N/A d = glyphStorage[lastGlyph];
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A x = lastGlyph - 2;
0N/A
0N/A while (x > firstGlyph) {
0N/A glyphStorage[x + 1] = glyphStorage[x];
0N/A ix = glyphStorage.getCharIndex(x, success);
0N/A glyphStorage.setCharIndex(x + 1, ix, success);
0N/A x -= 1;
0N/A }
0N/A
0N/A glyphStorage[firstGlyph] = c;
0N/A glyphStorage[firstGlyph + 1] = d;
0N/A glyphStorage[lastGlyph] = a;
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, ic, success);
0N/A glyphStorage.setCharIndex(firstGlyph + 1, id, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ia, success);
0N/A break;
0N/A
0N/A case irvDCxA:
0N/A a = glyphStorage[firstGlyph];
0N/A c = glyphStorage[lastGlyph - 1];
0N/A d = glyphStorage[lastGlyph];
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A x = lastGlyph - 2;
0N/A
0N/A while (x > firstGlyph) {
0N/A glyphStorage[x + 1] = glyphStorage[x];
0N/A ix = glyphStorage.getCharIndex(x, success);
0N/A glyphStorage.setCharIndex(x + 1, ix, success);
0N/A x -= 1;
0N/A }
0N/A
0N/A glyphStorage[firstGlyph] = d;
0N/A glyphStorage[firstGlyph + 1] = c;
0N/A glyphStorage[lastGlyph] = a;
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, id, success);
0N/A glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ia, success);
0N/A break;
0N/A
0N/A case irvDxAB:
0N/A a = glyphStorage[firstGlyph];
0N/A b = glyphStorage[firstGlyph + 1];
0N/A d = glyphStorage[lastGlyph];
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A x = firstGlyph + 2;
0N/A
0N/A while (x < lastGlyph) {
0N/A glyphStorage[x - 2] = glyphStorage[x];
0N/A ix = glyphStorage.getCharIndex(x, success);
0N/A glyphStorage.setCharIndex(x - 2, ix, success);
0N/A x += 1;
0N/A }
0N/A
0N/A glyphStorage[firstGlyph] = d;
0N/A glyphStorage[lastGlyph - 1] = a;
0N/A glyphStorage[lastGlyph] = b;
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, id, success);
0N/A glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ib, success);
0N/A break;
0N/A
0N/A case irvDxBA:
0N/A a = glyphStorage[firstGlyph];
0N/A b = glyphStorage[firstGlyph + 1];
0N/A d = glyphStorage[lastGlyph];
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A x = firstGlyph + 2;
0N/A
0N/A while (x < lastGlyph) {
0N/A glyphStorage[x - 2] = glyphStorage[x];
0N/A ix = glyphStorage.getCharIndex(x, success);
0N/A glyphStorage.setCharIndex(x - 2, ix, success);
0N/A x += 1;
0N/A }
0N/A
0N/A glyphStorage[firstGlyph] = d;
0N/A glyphStorage[lastGlyph - 1] = b;
0N/A glyphStorage[lastGlyph] = a;
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, id, success);
0N/A glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ia, success);
0N/A break;
0N/A
0N/A case irvCDxAB:
0N/A a = glyphStorage[firstGlyph];
0N/A b = glyphStorage[firstGlyph + 1];
0N/A
0N/A glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
0N/A glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
0N/A
0N/A glyphStorage[lastGlyph - 1] = a;
0N/A glyphStorage[lastGlyph] = b;
0N/A
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
0N/A ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, ic, success);
0N/A glyphStorage.setCharIndex(firstGlyph + 1, id, success);
0N/A
0N/A glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ib, success);
0N/A break;
0N/A
0N/A case irvCDxBA:
0N/A a = glyphStorage[firstGlyph];
0N/A b = glyphStorage[firstGlyph + 1];
0N/A
0N/A glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
0N/A glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
0N/A
0N/A glyphStorage[lastGlyph - 1] = b;
0N/A glyphStorage[lastGlyph] = a;
0N/A
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
0N/A ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, ic, success);
0N/A glyphStorage.setCharIndex(firstGlyph + 1, id, success);
0N/A
0N/A glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ia, success);
0N/A break;
0N/A
0N/A case irvDCxAB:
0N/A a = glyphStorage[firstGlyph];
0N/A b = glyphStorage[firstGlyph + 1];
0N/A
0N/A glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
0N/A glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
0N/A
0N/A glyphStorage[lastGlyph - 1] = a;
0N/A glyphStorage[lastGlyph] = b;
0N/A
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
0N/A ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, id, success);
0N/A glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
0N/A
0N/A glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ib, success);
0N/A break;
0N/A
0N/A case irvDCxBA:
0N/A a = glyphStorage[firstGlyph];
0N/A b = glyphStorage[firstGlyph + 1];
0N/A
0N/A glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
0N/A glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
0N/A
0N/A glyphStorage[lastGlyph - 1] = b;
0N/A glyphStorage[lastGlyph] = a;
0N/A
0N/A ia = glyphStorage.getCharIndex(firstGlyph, success);
0N/A ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
0N/A ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
0N/A id = glyphStorage.getCharIndex(lastGlyph, success);
0N/A
0N/A glyphStorage.setCharIndex(firstGlyph, id, success);
0N/A glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
0N/A
0N/A glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
0N/A glyphStorage.setCharIndex(lastGlyph, ia, success);
0N/A break;
0N/A
0N/A default:
0N/A break;
0N/A }
0N/A}
1693N/A
1693N/AU_NAMESPACE_END