]>
Commit | Line | Data |
---|---|---|
73c04bcf A |
1 | /* |
2 | * | |
57a6839d | 3 | * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved |
73c04bcf A |
4 | * |
5 | */ | |
6 | ||
7 | #include "LETypes.h" | |
8 | #include "LEGlyphStorage.h" | |
9 | #include "CanonShaping.h" | |
10 | #include "GlyphDefinitionTables.h" | |
11 | #include "ClassDefinitionTables.h" | |
12 | ||
13 | U_NAMESPACE_BEGIN | |
14 | ||
15 | void CanonShaping::sortMarks(le_int32 *indices, const le_int32 *combiningClasses, le_int32 index, le_int32 limit) | |
16 | { | |
17 | for (le_int32 j = index + 1; j < limit; j += 1) { | |
18 | le_int32 i; | |
19 | le_int32 v = indices[j]; | |
20 | le_int32 c = combiningClasses[v]; | |
21 | ||
22 | for (i = j - 1; i >= index; i -= 1) { | |
23 | if (c >= combiningClasses[indices[i]]) { | |
24 | break; | |
25 | } | |
26 | ||
27 | indices[i + 1] = indices[i]; | |
28 | } | |
29 | ||
30 | indices[i + 1] = v; | |
31 | } | |
32 | } | |
33 | ||
34 | void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft, | |
35 | LEUnicode *outChars, LEGlyphStorage &glyphStorage) | |
36 | { | |
57a6839d A |
37 | LEErrorCode success = LE_NO_ERROR; |
38 | LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); | |
39 | LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success); | |
73c04bcf A |
40 | le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount); |
41 | le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount); | |
73c04bcf A |
42 | le_int32 i; |
43 | ||
44 | for (i = 0; i < charCount; i += 1) { | |
57a6839d | 45 | combiningClasses[i] = classTable->getGlyphClass(classTable, (LEGlyphID) inChars[i], success); |
73c04bcf A |
46 | indices[i] = i; |
47 | } | |
48 | ||
49 | for (i = 0; i < charCount; i += 1) { | |
50 | if (combiningClasses[i] != 0) { | |
51 | le_int32 mark; | |
52 | ||
53 | for (mark = i; mark < charCount; mark += 1) { | |
54 | if (combiningClasses[mark] == 0) { | |
55 | break; | |
56 | } | |
57 | } | |
58 | ||
59 | sortMarks(indices, combiningClasses, i, mark); | |
60 | } | |
61 | } | |
62 | ||
63 | le_int32 out = 0, dir = 1; | |
64 | ||
65 | if (rightToLeft) { | |
66 | out = charCount - 1; | |
67 | dir = -1; | |
68 | } | |
69 | ||
70 | for (i = 0; i < charCount; i += 1, out += dir) { | |
71 | le_int32 index = indices[i]; | |
72 | ||
73 | outChars[i] = inChars[index]; | |
57a6839d | 74 | glyphStorage.setCharIndex(out, index, success); |
73c04bcf A |
75 | } |
76 | ||
77 | LE_DELETE_ARRAY(indices); | |
78 | LE_DELETE_ARRAY(combiningClasses); | |
79 | } | |
80 | ||
81 | U_NAMESPACE_END |