|
1 /* |
|
2 * |
|
3 * (C) Copyright IBM Corp. 2002-2004 - All Rights Reserved |
|
4 * |
|
5 */ |
|
6 |
|
7 #include "LETypes.h" |
|
8 #include "LEGlyphStorage.h" |
|
9 #include "MPreFixups.h" |
|
10 |
|
11 U_NAMESPACE_BEGIN |
|
12 |
|
13 struct FixupData |
|
14 { |
|
15 le_int32 fBaseIndex; |
|
16 le_int32 fMPreIndex; |
|
17 }; |
|
18 |
|
19 MPreFixups::MPreFixups(le_int32 charCount) |
|
20 : fFixupData(NULL), fFixupCount(0) |
|
21 { |
|
22 fFixupData = LE_NEW_ARRAY(FixupData, charCount); |
|
23 } |
|
24 |
|
25 MPreFixups::~MPreFixups() |
|
26 { |
|
27 LE_DELETE_ARRAY(fFixupData); |
|
28 fFixupData = NULL; |
|
29 } |
|
30 |
|
31 void 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 |
|
43 void 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 if (!mpreSave || !indexSave) { |
|
73 LE_DELETE_ARRAY(mpreSave); |
|
74 LE_DELETE_ARRAY(indexSave); |
|
75 success = LE_MEMORY_ALLOCATION_ERROR; |
|
76 return; |
|
77 } |
|
78 le_int32 i; |
|
79 |
|
80 for (i = 0; i < mpreCount; i += 1) { |
|
81 mpreSave[i] = glyphStorage[mpreIndex + i]; |
|
82 indexSave[i] = glyphStorage.getCharIndex(mpreIndex + i, success); //charIndices[mpreIndex + i]; |
|
83 } |
|
84 |
|
85 for (i = 0; i < moveCount; i += 1) { |
|
86 LEGlyphID glyph = glyphStorage[mpreLimit + i]; |
|
87 le_int32 charIndex = glyphStorage.getCharIndex(mpreLimit + i, success); |
|
88 |
|
89 glyphStorage[mpreIndex + i] = glyph; |
|
90 glyphStorage.setCharIndex(mpreIndex + i, charIndex, success); |
|
91 } |
|
92 |
|
93 for (i = 0; i < mpreCount; i += 1) { |
|
94 glyphStorage[mpreDest + i] = mpreSave[i]; |
|
95 glyphStorage.setCharIndex(mpreDest, indexSave[i], success); |
|
96 } |
|
97 |
|
98 LE_DELETE_ARRAY(indexSave); |
|
99 LE_DELETE_ARRAY(mpreSave); |
|
100 } |
|
101 } |
|
102 |
|
103 U_NAMESPACE_END |