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