1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LETypes.h"
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LEGlyphStorage.h"
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "MPreFixups.h"
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct FixupData
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_int32 fBaseIndex;
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    le_int32 fMPreIndex;
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMPreFixups::MPreFixups(le_int32 charCount)
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    : fFixupData(NULL), fFixupCount(0)
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fFixupData = LE_NEW_ARRAY(FixupData, charCount);
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMPreFixups::~MPreFixups()
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    LE_DELETE_ARRAY(fFixupData);
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fFixupData = NULL;
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid MPreFixups::add(le_int32 baseIndex, le_int32 mpreIndex)
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // NOTE: don't add the fixup data if the mpre is right
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // before the base consonant glyph.
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (baseIndex - mpreIndex > 1) {
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fFixupData[fFixupCount].fBaseIndex = baseIndex;
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fFixupData[fFixupCount].fMPreIndex = mpreIndex;
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fFixupCount += 1;
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
4385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& success)
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
4585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (LE_FAILURE(success)) {
4685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
4785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
4885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (le_int32 fixup = 0; fixup < fFixupCount; fixup += 1) {
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32 baseIndex = fFixupData[fixup].fBaseIndex;
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32 mpreIndex = fFixupData[fixup].fMPreIndex;
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32 mpreLimit = mpreIndex + 1;
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (glyphStorage[baseIndex] == 0xFFFF || glyphStorage[baseIndex] == 0xFFFE) {
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            baseIndex -= 1;
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (glyphStorage[mpreLimit] == 0xFFFF || glyphStorage[mpreLimit] == 0xFFFE) {
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            mpreLimit += 1;
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (mpreLimit == baseIndex) {
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            continue;
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        LEErrorCode success = LE_NO_ERROR;
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32   mpreCount = mpreLimit - mpreIndex;
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32   moveCount = baseIndex - mpreLimit;
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32   mpreDest  = baseIndex - mpreCount;
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        LEGlyphID *mpreSave  = LE_NEW_ARRAY(LEGlyphID, mpreCount);
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32  *indexSave = LE_NEW_ARRAY(le_int32, mpreCount);
7285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
7385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (mpreSave == NULL || indexSave == NULL) {
7485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            LE_DELETE_ARRAY(mpreSave);
7585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            LE_DELETE_ARRAY(indexSave);
7685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            success = LE_MEMORY_ALLOCATION_ERROR;
7785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
7885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
7985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        le_int32   i;
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (i = 0; i < mpreCount; i += 1) {
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            mpreSave[i]  = glyphStorage[mpreIndex + i];
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            indexSave[i] = glyphStorage.getCharIndex(mpreIndex + i, success); //charIndices[mpreIndex + i];
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (i = 0; i < moveCount; i += 1) {
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            LEGlyphID glyph = glyphStorage[mpreLimit + i];
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            le_int32 charIndex = glyphStorage.getCharIndex(mpreLimit + i, success);
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            glyphStorage[mpreIndex + i] = glyph;
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            glyphStorage.setCharIndex(mpreIndex + i, charIndex, success);
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (i = 0; i < mpreCount; i += 1) {
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            glyphStorage[mpreDest + i] = mpreSave[i];
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            glyphStorage.setCharIndex(mpreDest, indexSave[i], success);
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        LE_DELETE_ARRAY(indexSave);
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        LE_DELETE_ARRAY(mpreSave);
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
106