]>
Commit | Line | Data |
---|---|---|
b75a7d8f | 1 | /* |
b75a7d8f | 2 | * |
4388f060 | 3 | * (C) Copyright IBM Corp. 1998-2011 - All Rights Reserved |
b75a7d8f A |
4 | * |
5 | */ | |
6 | ||
7 | #ifndef __INDICREORDERING_H | |
8 | #define __INDICREORDERING_H | |
9 | ||
10 | /** | |
11 | * \file | |
12 | * \internal | |
13 | */ | |
14 | ||
15 | #include "LETypes.h" | |
16 | #include "OpenTypeTables.h" | |
17 | ||
18 | U_NAMESPACE_BEGIN | |
19 | ||
20 | // Characters that get refered to by name... | |
73c04bcf A |
21 | #define C_SIGN_ZWNJ 0x200C |
22 | #define C_SIGN_ZWJ 0x200D | |
23 | ||
24 | // Character class values | |
25 | #define CC_RESERVED 0U | |
26 | #define CC_VOWEL_MODIFIER 1U | |
27 | #define CC_STRESS_MARK 2U | |
28 | #define CC_INDEPENDENT_VOWEL 3U | |
29 | #define CC_INDEPENDENT_VOWEL_2 4U | |
30 | #define CC_INDEPENDENT_VOWEL_3 5U | |
31 | #define CC_CONSONANT 6U | |
32 | #define CC_CONSONANT_WITH_NUKTA 7U | |
33 | #define CC_NUKTA 8U | |
34 | #define CC_DEPENDENT_VOWEL 9U | |
35 | #define CC_SPLIT_VOWEL_PIECE_1 10U | |
36 | #define CC_SPLIT_VOWEL_PIECE_2 11U | |
37 | #define CC_SPLIT_VOWEL_PIECE_3 12U | |
38 | #define CC_VIRAMA 13U | |
39 | #define CC_ZERO_WIDTH_MARK 14U | |
46f4442e A |
40 | #define CC_AL_LAKUNA 15U |
41 | #define CC_COUNT 16U | |
73c04bcf A |
42 | |
43 | // Character class flags | |
44 | #define CF_CLASS_MASK 0x0000FFFFU | |
45 | ||
46 | #define CF_CONSONANT 0x80000000U | |
47 | ||
48 | #define CF_REPH 0x40000000U | |
49 | #define CF_VATTU 0x20000000U | |
50 | #define CF_BELOW_BASE 0x10000000U | |
51 | #define CF_POST_BASE 0x08000000U | |
52 | #define CF_LENGTH_MARK 0x04000000U | |
729e4ab9 | 53 | #define CF_PRE_BASE 0x02000000U |
73c04bcf A |
54 | |
55 | #define CF_POS_BEFORE 0x00300000U | |
56 | #define CF_POS_BELOW 0x00200000U | |
57 | #define CF_POS_ABOVE 0x00100000U | |
58 | #define CF_POS_AFTER 0x00000000U | |
59 | #define CF_POS_MASK 0x00300000U | |
60 | ||
61 | #define CF_INDEX_MASK 0x000F0000U | |
62 | #define CF_INDEX_SHIFT 16 | |
63 | ||
64 | // Script flag bits | |
65 | #define SF_MATRAS_AFTER_BASE 0x80000000U | |
66 | #define SF_REPH_AFTER_BELOW 0x40000000U | |
67 | #define SF_EYELASH_RA 0x20000000U | |
68 | #define SF_MPRE_FIXUP 0x10000000U | |
69 | #define SF_FILTER_ZERO_WIDTH 0x08000000U | |
70 | ||
71 | #define SF_POST_BASE_LIMIT_MASK 0x0000FFFFU | |
72 | #define SF_NO_POST_BASE_LIMIT 0x00007FFFU | |
b75a7d8f | 73 | |
4388f060 A |
74 | #define SM_MAX_PIECES 3 |
75 | ||
76 | typedef LEUnicode SplitMatra[SM_MAX_PIECES]; | |
b75a7d8f | 77 | |
374ca955 A |
78 | class MPreFixups; |
79 | class LEGlyphStorage; | |
b75a7d8f | 80 | |
729e4ab9 A |
81 | // Dynamic Properties ( v2 fonts only ) |
82 | typedef le_uint32 DynamicProperties; | |
83 | ||
84 | #define DP_REPH 0x80000000U | |
85 | #define DP_HALF 0x40000000U | |
86 | #define DP_PREF 0x20000000U | |
87 | #define DP_BLWF 0x10000000U | |
88 | #define DP_PSTF 0x08000000U | |
89 | ||
b75a7d8f A |
90 | struct IndicClassTable |
91 | { | |
374ca955 | 92 | typedef le_uint32 CharClass; |
73c04bcf | 93 | typedef le_uint32 ScriptFlags; |
729e4ab9 | 94 | |
b75a7d8f A |
95 | LEUnicode firstChar; |
96 | LEUnicode lastChar; | |
97 | le_int32 worstCaseExpansion; | |
98 | ScriptFlags scriptFlags; | |
99 | const CharClass *classTable; | |
100 | const SplitMatra *splitMatraTable; | |
101 | ||
73c04bcf A |
102 | inline le_int32 getWorstCaseExpansion() const; |
103 | inline le_bool getFilterZeroWidth() const; | |
b75a7d8f A |
104 | |
105 | CharClass getCharClass(LEUnicode ch) const; | |
73c04bcf A |
106 | |
107 | inline const SplitMatra *getSplitMatra(CharClass charClass) const; | |
108 | ||
109 | inline le_bool isVowelModifier(LEUnicode ch) const; | |
110 | inline le_bool isStressMark(LEUnicode ch) const; | |
111 | inline le_bool isConsonant(LEUnicode ch) const; | |
112 | inline le_bool isReph(LEUnicode ch) const; | |
113 | inline le_bool isVirama(LEUnicode ch) const; | |
46f4442e | 114 | inline le_bool isAlLakuna(LEUnicode ch) const; |
73c04bcf A |
115 | inline le_bool isNukta(LEUnicode ch) const; |
116 | inline le_bool isVattu(LEUnicode ch) const; | |
117 | inline le_bool isMatra(LEUnicode ch) const; | |
118 | inline le_bool isSplitMatra(LEUnicode ch) const; | |
119 | inline le_bool isLengthMark(LEUnicode ch) const; | |
120 | inline le_bool hasPostOrBelowBaseForm(LEUnicode ch) const; | |
121 | inline le_bool hasPostBaseForm(LEUnicode ch) const; | |
122 | inline le_bool hasBelowBaseForm(LEUnicode ch) const; | |
729e4ab9 A |
123 | inline le_bool hasAboveBaseForm(LEUnicode ch) const; |
124 | inline le_bool hasPreBaseForm(LEUnicode ch) const; | |
73c04bcf A |
125 | |
126 | inline static le_bool isVowelModifier(CharClass charClass); | |
127 | inline static le_bool isStressMark(CharClass charClass); | |
128 | inline static le_bool isConsonant(CharClass charClass); | |
129 | inline static le_bool isReph(CharClass charClass); | |
130 | inline static le_bool isVirama(CharClass charClass); | |
46f4442e | 131 | inline static le_bool isAlLakuna(CharClass charClass); |
73c04bcf A |
132 | inline static le_bool isNukta(CharClass charClass); |
133 | inline static le_bool isVattu(CharClass charClass); | |
134 | inline static le_bool isMatra(CharClass charClass); | |
135 | inline static le_bool isSplitMatra(CharClass charClass); | |
136 | inline static le_bool isLengthMark(CharClass charClass); | |
137 | inline static le_bool hasPostOrBelowBaseForm(CharClass charClass); | |
138 | inline static le_bool hasPostBaseForm(CharClass charClass); | |
139 | inline static le_bool hasBelowBaseForm(CharClass charClass); | |
729e4ab9 A |
140 | inline static le_bool hasAboveBaseForm(CharClass charClass); |
141 | inline static le_bool hasPreBaseForm(CharClass charClass); | |
b75a7d8f A |
142 | |
143 | static const IndicClassTable *getScriptClassTable(le_int32 scriptCode); | |
144 | }; | |
145 | ||
146 | class IndicReordering /* not : public UObject because all methods are static */ { | |
147 | public: | |
148 | static le_int32 getWorstCaseExpansion(le_int32 scriptCode); | |
149 | ||
73c04bcf A |
150 | static le_bool getFilterZeroWidth(le_int32 scriptCode); |
151 | ||
b75a7d8f | 152 | static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode, |
374ca955 | 153 | LEUnicode *outChars, LEGlyphStorage &glyphStorage, |
729e4ab9 | 154 | MPreFixups **outMPreFixups, LEErrorCode& success); |
b75a7d8f | 155 | |
729e4ab9 A |
156 | static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage, LEErrorCode& success); |
157 | ||
158 | static le_int32 v2process(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode, | |
159 | LEUnicode *outChars, LEGlyphStorage &glyphStorage); | |
b75a7d8f | 160 | |
73c04bcf | 161 | static const FeatureMap *getFeatureMap(le_int32 &count); |
b75a7d8f | 162 | |
729e4ab9 A |
163 | static const FeatureMap *getv2FeatureMap(le_int32 &count); |
164 | ||
165 | static void applyPresentationForms(LEGlyphStorage &glyphStorage, le_int32 count); | |
166 | ||
167 | static void finalReordering(LEGlyphStorage &glyphStorage, le_int32 count); | |
168 | ||
169 | static void getDynamicProperties(DynamicProperties *dProps, const IndicClassTable *classTable); | |
170 | ||
b75a7d8f A |
171 | private: |
172 | // do not instantiate | |
173 | IndicReordering(); | |
174 | ||
175 | static le_int32 findSyllable(const IndicClassTable *classTable, const LEUnicode *chars, le_int32 prev, le_int32 charCount); | |
176 | ||
177 | }; | |
178 | ||
179 | inline le_int32 IndicClassTable::getWorstCaseExpansion() const | |
180 | { | |
181 | return worstCaseExpansion; | |
182 | } | |
183 | ||
73c04bcf A |
184 | inline le_bool IndicClassTable::getFilterZeroWidth() const |
185 | { | |
186 | return (scriptFlags & SF_FILTER_ZERO_WIDTH) != 0; | |
187 | } | |
188 | ||
b75a7d8f A |
189 | inline const SplitMatra *IndicClassTable::getSplitMatra(CharClass charClass) const |
190 | { | |
191 | le_int32 index = (charClass & CF_INDEX_MASK) >> CF_INDEX_SHIFT; | |
192 | ||
193 | return &splitMatraTable[index - 1]; | |
194 | } | |
195 | ||
374ca955 | 196 | inline le_bool IndicClassTable::isVowelModifier(CharClass charClass) |
b75a7d8f | 197 | { |
374ca955 | 198 | return (charClass & CF_CLASS_MASK) == CC_VOWEL_MODIFIER; |
b75a7d8f A |
199 | } |
200 | ||
374ca955 | 201 | inline le_bool IndicClassTable::isStressMark(CharClass charClass) |
b75a7d8f | 202 | { |
374ca955 | 203 | return (charClass & CF_CLASS_MASK) == CC_STRESS_MARK; |
b75a7d8f A |
204 | } |
205 | ||
206 | inline le_bool IndicClassTable::isConsonant(CharClass charClass) | |
207 | { | |
208 | return (charClass & CF_CONSONANT) != 0; | |
209 | } | |
210 | ||
211 | inline le_bool IndicClassTable::isReph(CharClass charClass) | |
212 | { | |
213 | return (charClass & CF_REPH) != 0; | |
214 | } | |
215 | ||
216 | inline le_bool IndicClassTable::isNukta(CharClass charClass) | |
217 | { | |
218 | return (charClass & CF_CLASS_MASK) == CC_NUKTA; | |
219 | } | |
220 | ||
221 | inline le_bool IndicClassTable::isVirama(CharClass charClass) | |
222 | { | |
223 | return (charClass & CF_CLASS_MASK) == CC_VIRAMA; | |
224 | } | |
225 | ||
46f4442e A |
226 | inline le_bool IndicClassTable::isAlLakuna(CharClass charClass) |
227 | { | |
228 | return (charClass & CF_CLASS_MASK) == CC_AL_LAKUNA; | |
229 | } | |
230 | ||
b75a7d8f A |
231 | inline le_bool IndicClassTable::isVattu(CharClass charClass) |
232 | { | |
233 | return (charClass & CF_VATTU) != 0; | |
234 | } | |
235 | ||
236 | inline le_bool IndicClassTable::isMatra(CharClass charClass) | |
237 | { | |
374ca955 A |
238 | charClass &= CF_CLASS_MASK; |
239 | ||
240 | return charClass >= CC_DEPENDENT_VOWEL && charClass <= CC_SPLIT_VOWEL_PIECE_3; | |
b75a7d8f A |
241 | } |
242 | ||
243 | inline le_bool IndicClassTable::isSplitMatra(CharClass charClass) | |
244 | { | |
245 | return (charClass & CF_INDEX_MASK) != 0; | |
246 | } | |
247 | ||
b75a7d8f A |
248 | inline le_bool IndicClassTable::isLengthMark(CharClass charClass) |
249 | { | |
250 | return (charClass & CF_LENGTH_MARK) != 0; | |
251 | } | |
252 | ||
253 | inline le_bool IndicClassTable::hasPostOrBelowBaseForm(CharClass charClass) | |
254 | { | |
255 | return (charClass & (CF_POST_BASE | CF_BELOW_BASE)) != 0; | |
256 | } | |
257 | ||
258 | inline le_bool IndicClassTable::hasPostBaseForm(CharClass charClass) | |
259 | { | |
260 | return (charClass & CF_POST_BASE) != 0; | |
261 | } | |
262 | ||
729e4ab9 A |
263 | inline le_bool IndicClassTable::hasPreBaseForm(CharClass charClass) |
264 | { | |
265 | return (charClass & CF_PRE_BASE) != 0; | |
266 | } | |
267 | ||
b75a7d8f A |
268 | inline le_bool IndicClassTable::hasBelowBaseForm(CharClass charClass) |
269 | { | |
270 | return (charClass & CF_BELOW_BASE) != 0; | |
271 | } | |
272 | ||
729e4ab9 A |
273 | inline le_bool IndicClassTable::hasAboveBaseForm(CharClass charClass) |
274 | { | |
275 | return ((charClass & CF_POS_MASK) == CF_POS_ABOVE); | |
276 | } | |
277 | ||
374ca955 | 278 | inline le_bool IndicClassTable::isVowelModifier(LEUnicode ch) const |
b75a7d8f | 279 | { |
374ca955 | 280 | return isVowelModifier(getCharClass(ch)); |
b75a7d8f A |
281 | } |
282 | ||
374ca955 | 283 | inline le_bool IndicClassTable::isStressMark(LEUnicode ch) const |
b75a7d8f | 284 | { |
374ca955 | 285 | return isStressMark(getCharClass(ch)); |
b75a7d8f A |
286 | } |
287 | ||
288 | inline le_bool IndicClassTable::isConsonant(LEUnicode ch) const | |
289 | { | |
290 | return isConsonant(getCharClass(ch)); | |
291 | } | |
292 | ||
293 | inline le_bool IndicClassTable::isReph(LEUnicode ch) const | |
294 | { | |
295 | return isReph(getCharClass(ch)); | |
296 | } | |
297 | ||
298 | inline le_bool IndicClassTable::isVirama(LEUnicode ch) const | |
299 | { | |
300 | return isVirama(getCharClass(ch)); | |
301 | } | |
302 | ||
46f4442e A |
303 | inline le_bool IndicClassTable::isAlLakuna(LEUnicode ch) const |
304 | { | |
305 | return isAlLakuna(getCharClass(ch)); | |
306 | } | |
307 | ||
b75a7d8f A |
308 | inline le_bool IndicClassTable::isNukta(LEUnicode ch) const |
309 | { | |
310 | return isNukta(getCharClass(ch)); | |
311 | } | |
312 | ||
313 | inline le_bool IndicClassTable::isVattu(LEUnicode ch) const | |
314 | { | |
315 | return isVattu(getCharClass(ch)); | |
316 | } | |
317 | ||
318 | inline le_bool IndicClassTable::isMatra(LEUnicode ch) const | |
319 | { | |
320 | return isMatra(getCharClass(ch)); | |
321 | } | |
322 | ||
323 | inline le_bool IndicClassTable::isSplitMatra(LEUnicode ch) const | |
324 | { | |
325 | return isSplitMatra(getCharClass(ch)); | |
326 | } | |
327 | ||
b75a7d8f A |
328 | inline le_bool IndicClassTable::isLengthMark(LEUnicode ch) const |
329 | { | |
330 | return isLengthMark(getCharClass(ch)); | |
331 | } | |
332 | ||
333 | inline le_bool IndicClassTable::hasPostOrBelowBaseForm(LEUnicode ch) const | |
334 | { | |
335 | return hasPostOrBelowBaseForm(getCharClass(ch)); | |
336 | } | |
337 | ||
338 | inline le_bool IndicClassTable::hasPostBaseForm(LEUnicode ch) const | |
339 | { | |
340 | return hasPostBaseForm(getCharClass(ch)); | |
341 | } | |
342 | ||
343 | inline le_bool IndicClassTable::hasBelowBaseForm(LEUnicode ch) const | |
344 | { | |
345 | return hasBelowBaseForm(getCharClass(ch)); | |
346 | } | |
347 | ||
729e4ab9 A |
348 | inline le_bool IndicClassTable::hasPreBaseForm(LEUnicode ch) const |
349 | { | |
350 | return hasPreBaseForm(getCharClass(ch)); | |
351 | } | |
352 | ||
353 | inline le_bool IndicClassTable::hasAboveBaseForm(LEUnicode ch) const | |
354 | { | |
355 | return hasAboveBaseForm(getCharClass(ch)); | |
356 | } | |
b75a7d8f A |
357 | U_NAMESPACE_END |
358 | #endif |