OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2010,2012 Google, Inc. | 2 * Copyright © 2010,2012 Google, Inc. |
3 * | 3 * |
4 * This is part of HarfBuzz, a text shaping library. | 4 * This is part of HarfBuzz, a text shaping library. |
5 * | 5 * |
6 * Permission is hereby granted, without written agreement and without | 6 * Permission is hereby granted, without written agreement and without |
7 * license or royalty fees, to use, copy, modify, and distribute this | 7 * license or royalty fees, to use, copy, modify, and distribute this |
8 * software and its documentation for any purpose, provided that the | 8 * software and its documentation for any purpose, provided that the |
9 * above copyright notice and the following two paragraphs appear in | 9 * above copyright notice and the following two paragraphs appear in |
10 * all copies of this software. | 10 * all copies of this software. |
(...skipping 28 matching lines...) Expand all Loading... |
39 AC, | 39 AC, |
40 RC, | 40 RC, |
41 DC, | 41 DC, |
42 NOT_CONSONANT, | 42 NOT_CONSONANT, |
43 NUM_CONSONANT_TYPES = NOT_CONSONANT | 43 NUM_CONSONANT_TYPES = NOT_CONSONANT |
44 }; | 44 }; |
45 | 45 |
46 static thai_consonant_type_t | 46 static thai_consonant_type_t |
47 get_consonant_type (hb_codepoint_t u) | 47 get_consonant_type (hb_codepoint_t u) |
48 { | 48 { |
49 if (u == 0x0E1B || u == 0x0E1D || u == 0x0E1F/* || u == 0x0E2C*/) | 49 if (u == 0x0E1Bu || u == 0x0E1Du || u == 0x0E1Fu/* || u == 0x0E2Cu*/) |
50 return AC; | 50 return AC; |
51 if (u == 0x0E0D || u == 0x0E10) | 51 if (u == 0x0E0Du || u == 0x0E10u) |
52 return RC; | 52 return RC; |
53 if (u == 0x0E0E || u == 0x0E0F) | 53 if (u == 0x0E0Eu || u == 0x0E0Fu) |
54 return DC; | 54 return DC; |
55 if (hb_in_range<hb_codepoint_t> (u, 0x0E01, 0x0E2E)) | 55 if (hb_in_range (u, 0x0E01u, 0x0E2Eu)) |
56 return NC; | 56 return NC; |
57 return NOT_CONSONANT; | 57 return NOT_CONSONANT; |
58 } | 58 } |
59 | 59 |
60 | 60 |
61 enum thai_mark_type_t | 61 enum thai_mark_type_t |
62 { | 62 { |
63 AV, | 63 AV, |
64 BV, | 64 BV, |
65 T, | 65 T, |
66 NOT_MARK, | 66 NOT_MARK, |
67 NUM_MARK_TYPES = NOT_MARK | 67 NUM_MARK_TYPES = NOT_MARK |
68 }; | 68 }; |
69 | 69 |
70 static thai_mark_type_t | 70 static thai_mark_type_t |
71 get_mark_type (hb_codepoint_t u) | 71 get_mark_type (hb_codepoint_t u) |
72 { | 72 { |
73 if (u == 0x0E31 || hb_in_range<hb_codepoint_t> (u, 0x0E34, 0x0E37) || | 73 if (u == 0x0E31u || hb_in_range (u, 0x0E34u, 0x0E37u) || |
74 u == 0x0E47 || hb_in_range<hb_codepoint_t> (u, 0x0E4D, 0x0E4E)) | 74 u == 0x0E47u || hb_in_range (u, 0x0E4Du, 0x0E4Eu)) |
75 return AV; | 75 return AV; |
76 if (hb_in_range<hb_codepoint_t> (u, 0x0E38, 0x0E3A)) | 76 if (hb_in_range (u, 0x0E38u, 0x0E3Au)) |
77 return BV; | 77 return BV; |
78 if (hb_in_range<hb_codepoint_t> (u, 0x0E48, 0x0E4C)) | 78 if (hb_in_range (u, 0x0E48u, 0x0E4Cu)) |
79 return T; | 79 return T; |
80 return NOT_MARK; | 80 return NOT_MARK; |
81 } | 81 } |
82 | 82 |
83 | 83 |
84 enum thai_action_t | 84 enum thai_action_t |
85 { | 85 { |
86 NOP, | 86 NOP, |
87 SD, /* Shift combining-mark down */ | 87 SD, /* Shift combining-mark down */ |
88 SL, /* Shift combining-mark left */ | 88 SL, /* Shift combining-mark left */ |
89 SDL, /* Shift combining-mark down-left */ | 89 SDL, /* Shift combining-mark down-left */ |
90 RD /* Remove descender from base */ | 90 RD /* Remove descender from base */ |
91 }; | 91 }; |
92 | 92 |
93 static hb_codepoint_t | 93 static hb_codepoint_t |
94 thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font) | 94 thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font) |
95 { | 95 { |
96 struct thai_pua_mapping_t { | 96 struct thai_pua_mapping_t { |
97 hb_codepoint_t u; | 97 hb_codepoint_t u; |
98 hb_codepoint_t win_pua; | 98 hb_codepoint_t win_pua; |
99 hb_codepoint_t mac_pua; | 99 hb_codepoint_t mac_pua; |
100 } const *pua_mappings = NULL; | 100 } const *pua_mappings = NULL; |
101 static const thai_pua_mapping_t SD_mappings[] = { | 101 static const thai_pua_mapping_t SD_mappings[] = { |
102 {0x0E48, 0xF70A, 0xF88B}, /* MAI EK */ | 102 {0x0E48u, 0xF70Au, 0xF88Bu}, /* MAI EK */ |
103 {0x0E49, 0xF70B, 0xF88E}, /* MAI THO */ | 103 {0x0E49u, 0xF70Bu, 0xF88Eu}, /* MAI THO */ |
104 {0x0E4A, 0xF70C, 0xF891}, /* MAI TRI */ | 104 {0x0E4Au, 0xF70Cu, 0xF891u}, /* MAI TRI */ |
105 {0x0E4B, 0xF70D, 0xF894}, /* MAI CHATTAWA */ | 105 {0x0E4Bu, 0xF70Du, 0xF894u}, /* MAI CHATTAWA */ |
106 {0x0E4C, 0xF70E, 0xF897}, /* THANTHAKHAT */ | 106 {0x0E4Cu, 0xF70Eu, 0xF897u}, /* THANTHAKHAT */ |
107 {0x0E38, 0xF718, 0xF89B}, /* SARA U */ | 107 {0x0E38u, 0xF718u, 0xF89Bu}, /* SARA U */ |
108 {0x0E39, 0xF719, 0xF89C}, /* SARA UU */ | 108 {0x0E39u, 0xF719u, 0xF89Cu}, /* SARA UU */ |
109 {0x0E3A, 0xF71A, 0xF89D}, /* PHINTHU */ | 109 {0x0E3Au, 0xF71Au, 0xF89Du}, /* PHINTHU */ |
110 {0x0000, 0x0000, 0x0000} | 110 {0x0000u, 0x0000u, 0x0000u} |
111 }; | 111 }; |
112 static const thai_pua_mapping_t SDL_mappings[] = { | 112 static const thai_pua_mapping_t SDL_mappings[] = { |
113 {0x0E48, 0xF705, 0xF88C}, /* MAI EK */ | 113 {0x0E48u, 0xF705u, 0xF88Cu}, /* MAI EK */ |
114 {0x0E49, 0xF706, 0xF88F}, /* MAI THO */ | 114 {0x0E49u, 0xF706u, 0xF88Fu}, /* MAI THO */ |
115 {0x0E4A, 0xF707, 0xF892}, /* MAI TRI */ | 115 {0x0E4Au, 0xF707u, 0xF892u}, /* MAI TRI */ |
116 {0x0E4B, 0xF708, 0xF895}, /* MAI CHATTAWA */ | 116 {0x0E4Bu, 0xF708u, 0xF895u}, /* MAI CHATTAWA */ |
117 {0x0E4C, 0xF709, 0xF898}, /* THANTHAKHAT */ | 117 {0x0E4Cu, 0xF709u, 0xF898u}, /* THANTHAKHAT */ |
118 {0x0000, 0x0000, 0x0000} | 118 {0x0000u, 0x0000u, 0x0000u} |
119 }; | 119 }; |
120 static const thai_pua_mapping_t SL_mappings[] = { | 120 static const thai_pua_mapping_t SL_mappings[] = { |
121 {0x0E48, 0xF713, 0xF88A}, /* MAI EK */ | 121 {0x0E48u, 0xF713u, 0xF88Au}, /* MAI EK */ |
122 {0x0E49, 0xF714, 0xF88D}, /* MAI THO */ | 122 {0x0E49u, 0xF714u, 0xF88Du}, /* MAI THO */ |
123 {0x0E4A, 0xF715, 0xF890}, /* MAI TRI */ | 123 {0x0E4Au, 0xF715u, 0xF890u}, /* MAI TRI */ |
124 {0x0E4B, 0xF716, 0xF893}, /* MAI CHATTAWA */ | 124 {0x0E4Bu, 0xF716u, 0xF893u}, /* MAI CHATTAWA */ |
125 {0x0E4C, 0xF717, 0xF896}, /* THANTHAKHAT */ | 125 {0x0E4Cu, 0xF717u, 0xF896u}, /* THANTHAKHAT */ |
126 {0x0E31, 0xF710, 0xF884}, /* MAI HAN-AKAT */ | 126 {0x0E31u, 0xF710u, 0xF884u}, /* MAI HAN-AKAT */ |
127 {0x0E34, 0xF701, 0xF885}, /* SARA I */ | 127 {0x0E34u, 0xF701u, 0xF885u}, /* SARA I */ |
128 {0x0E35, 0xF702, 0xF886}, /* SARA II */ | 128 {0x0E35u, 0xF702u, 0xF886u}, /* SARA II */ |
129 {0x0E36, 0xF703, 0xF887}, /* SARA UE */ | 129 {0x0E36u, 0xF703u, 0xF887u}, /* SARA UE */ |
130 {0x0E37, 0xF704, 0xF888}, /* SARA UEE */ | 130 {0x0E37u, 0xF704u, 0xF888u}, /* SARA UEE */ |
131 {0x0E47, 0xF712, 0xF889}, /* MAITAIKHU */ | 131 {0x0E47u, 0xF712u, 0xF889u}, /* MAITAIKHU */ |
132 {0x0E4D, 0xF711, 0xF899}, /* NIKHAHIT */ | 132 {0x0E4Du, 0xF711u, 0xF899u}, /* NIKHAHIT */ |
133 {0x0000, 0x0000, 0x0000} | 133 {0x0000u, 0x0000u, 0x0000u} |
134 }; | 134 }; |
135 static const thai_pua_mapping_t RD_mappings[] = { | 135 static const thai_pua_mapping_t RD_mappings[] = { |
136 {0x0E0D, 0xF70F, 0xF89A}, /* YO YING */ | 136 {0x0E0Du, 0xF70Fu, 0xF89Au}, /* YO YING */ |
137 {0x0E10, 0xF700, 0xF89E}, /* THO THAN */ | 137 {0x0E10u, 0xF700u, 0xF89Eu}, /* THO THAN */ |
138 {0x0000, 0x0000, 0x0000} | 138 {0x0000u, 0x0000u, 0x0000u} |
139 }; | 139 }; |
140 | 140 |
141 switch (action) { | 141 switch (action) { |
142 default: assert (false); /* Fallthrough */ | 142 default: assert (false); /* Fallthrough */ |
143 case NOP: return u; | 143 case NOP: return u; |
144 case SD: pua_mappings = SD_mappings; break; | 144 case SD: pua_mappings = SD_mappings; break; |
145 case SDL: pua_mappings = SDL_mappings; break; | 145 case SDL: pua_mappings = SDL_mappings; break; |
146 case SL: pua_mappings = SL_mappings; break; | 146 case SL: pua_mappings = SL_mappings; break; |
147 case RD: pua_mappings = RD_mappings; break; | 147 case RD: pua_mappings = RD_mappings; break; |
148 } | 148 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 * | 301 * |
302 * Testing shows that Uniscribe reorder the following marks: | 302 * Testing shows that Uniscribe reorder the following marks: |
303 * Thai: <0E31,0E34..0E37,0E47..0E4E> | 303 * Thai: <0E31,0E34..0E37,0E47..0E4E> |
304 * Lao: <0EB1,0EB4..0EB7,0EC7..0ECE> | 304 * Lao: <0EB1,0EB4..0EB7,0EC7..0ECE> |
305 * | 305 * |
306 * Note how the Lao versions are the same as Thai + 0x80. | 306 * Note how the Lao versions are the same as Thai + 0x80. |
307 */ | 307 */ |
308 | 308 |
309 /* We only get one script at a time, so a script-agnostic implementation | 309 /* We only get one script at a time, so a script-agnostic implementation |
310 * is adequate here. */ | 310 * is adequate here. */ |
311 #define IS_SARA_AM(x) (((x) & ~0x0080) == 0x0E33) | 311 #define IS_SARA_AM(x) (((x) & ~0x0080u) == 0x0E33u) |
312 #define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0xE33 + 0xE4D) | 312 #define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0x0E33u + 0x0E4Du) |
313 #define SARA_AA_FROM_SARA_AM(x) ((x) - 1) | 313 #define SARA_AA_FROM_SARA_AM(x) ((x) - 1) |
314 #define IS_TONE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080, 0x0E34, 0x
0E37, 0x0E47, 0x0E4E, 0x0E31, 0x0E31)) | 314 #define IS_TONE_MARK(x) (hb_in_ranges ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u
, 0x0E4Eu, 0x0E31u, 0x0E31u)) |
315 | 315 |
316 buffer->clear_output (); | 316 buffer->clear_output (); |
317 unsigned int count = buffer->len; | 317 unsigned int count = buffer->len; |
318 for (buffer->idx = 0; buffer->idx < count;) | 318 for (buffer->idx = 0; buffer->idx < count;) |
319 { | 319 { |
320 hb_codepoint_t u = buffer->cur().codepoint; | 320 hb_codepoint_t u = buffer->cur().codepoint; |
321 if (likely (!IS_SARA_AM (u))) { | 321 if (likely (!IS_SARA_AM (u))) { |
322 buffer->next_glyph (); | 322 buffer->next_glyph (); |
323 continue; | 323 continue; |
324 } | 324 } |
325 | 325 |
326 /* Is SARA AM. Decompose and reorder. */ | 326 /* Is SARA AM. Decompose and reorder. */ |
327 hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)), | 327 hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)), |
328 hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))}; | 328 hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))}; |
329 buffer->replace_glyphs (1, 2, decomposed); | 329 buffer->replace_glyphs (1, 2, decomposed); |
330 if (unlikely (buffer->in_error)) | 330 if (unlikely (buffer->in_error)) |
331 return; | 331 return; |
332 | 332 |
| 333 /* Make Nikhahit be recognized as a mark when zeroing widths. */ |
| 334 unsigned int end = buffer->out_len; |
| 335 _hb_glyph_info_set_general_category (&buffer->out_info[end - 2], HB_UNICODE_
GENERAL_CATEGORY_NON_SPACING_MARK); |
| 336 |
333 /* Ok, let's see... */ | 337 /* Ok, let's see... */ |
334 unsigned int end = buffer->out_len; | |
335 unsigned int start = end - 2; | 338 unsigned int start = end - 2; |
336 while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint)) | 339 while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint)) |
337 start--; | 340 start--; |
338 | 341 |
339 if (start + 2 < end) | 342 if (start + 2 < end) |
340 { | 343 { |
341 /* Move Nikhahit (end-2) to the beginning */ | 344 /* Move Nikhahit (end-2) to the beginning */ |
342 buffer->merge_out_clusters (start, end); | 345 buffer->merge_out_clusters (start, end); |
343 hb_glyph_info_t t = buffer->out_info[end - 2]; | 346 hb_glyph_info_t t = buffer->out_info[end - 2]; |
344 memmove (buffer->out_info + start + 1, | 347 memmove (buffer->out_info + start + 1, |
(...skipping 24 matching lines...) Expand all Loading... |
369 NULL, /* data_create */ | 372 NULL, /* data_create */ |
370 NULL, /* data_destroy */ | 373 NULL, /* data_destroy */ |
371 preprocess_text_thai, | 374 preprocess_text_thai, |
372 HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, | 375 HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, |
373 NULL, /* decompose */ | 376 NULL, /* decompose */ |
374 NULL, /* compose */ | 377 NULL, /* compose */ |
375 NULL, /* setup_masks */ | 378 NULL, /* setup_masks */ |
376 HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT, | 379 HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT, |
377 false,/* fallback_position */ | 380 false,/* fallback_position */ |
378 }; | 381 }; |
OLD | NEW |