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 19 matching lines...) Expand all Loading... |
30 | 30 |
31 /* buffer var allocations */ | 31 /* buffer var allocations */ |
32 #define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ | 32 #define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ |
33 | 33 |
34 | 34 |
35 /* | 35 /* |
36 * Bits used in the joining tables | 36 * Bits used in the joining tables |
37 */ | 37 */ |
38 enum { | 38 enum { |
39 JOINING_TYPE_U = 0, | 39 JOINING_TYPE_U = 0, |
40 JOINING_TYPE_R» » = 1, | 40 JOINING_TYPE_L» » = 1, |
41 JOINING_TYPE_D» » = 2, | 41 JOINING_TYPE_R» » = 2, |
| 42 JOINING_TYPE_D» » = 3, |
42 JOINING_TYPE_C = JOINING_TYPE_D, | 43 JOINING_TYPE_C = JOINING_TYPE_D, |
43 JOINING_GROUP_ALAPH» » = 3, | 44 JOINING_GROUP_ALAPH» » = 4, |
44 JOINING_GROUP_DALATH_RISH» = 4, | 45 JOINING_GROUP_DALATH_RISH» = 5, |
45 NUM_STATE_MACHINE_COLS» = 5, | 46 NUM_STATE_MACHINE_COLS» = 6, |
46 | 47 |
47 /* We deliberately don't have a JOINING_TYPE_L since that's unused in Unicode.
*/ | 48 JOINING_TYPE_T = 7, |
48 | 49 JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. *
/ |
49 JOINING_TYPE_T = 6, | |
50 JOINING_TYPE_X = 7 /* means: use general-category to choose between U or T. *
/ | |
51 }; | 50 }; |
52 | 51 |
53 /* | 52 /* |
54 * Joining types: | 53 * Joining types: |
55 */ | 54 */ |
56 | 55 |
57 #include "hb-ot-shape-complex-arabic-table.hh" | 56 #include "hb-ot-shape-complex-arabic-table.hh" |
58 | 57 |
59 static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ
ory_t gen_cat) | 58 static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ
ory_t gen_cat) |
60 { | 59 { |
(...skipping 13 matching lines...) Expand all Loading... |
74 if ((FLAG(gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | | 73 if ((FLAG(gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | |
75 FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER))) | 74 FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER))) |
76 || u == 0x1807 || u == 0x180A) | 75 || u == 0x1807 || u == 0x180A) |
77 return JOINING_TYPE_D; | 76 return JOINING_TYPE_D; |
78 } | 77 } |
79 | 78 |
80 /* 'Phags-pa joining data is not in ArabicJoining.txt yet. */ | 79 /* 'Phags-pa joining data is not in ArabicJoining.txt yet. */ |
81 if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xA840, 0xA872))) | 80 if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xA840, 0xA872))) |
82 { | 81 { |
83 if (unlikely (u == 0xA872)) | 82 if (unlikely (u == 0xA872)) |
84 » /* XXX Looks like this should be TYPE_L, but we don't support that yet!
*/ | 83 » return JOINING_TYPE_L; |
85 » return JOINING_TYPE_R; | |
86 | 84 |
87 return JOINING_TYPE_D; | 85 return JOINING_TYPE_D; |
88 } | 86 } |
89 | 87 |
90 if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D))) | 88 if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D))) |
91 { | 89 { |
92 return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C; | 90 return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C; |
93 } | 91 } |
94 | 92 |
95 return (FLAG(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEG
ORY_FORMAT))) ? | 93 return (FLAG(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEG
ORY_FORMAT))) ? |
(...skipping 30 matching lines...) Expand all Loading... |
126 | 124 |
127 ARABIC_NUM_FEATURES = NONE | 125 ARABIC_NUM_FEATURES = NONE |
128 }; | 126 }; |
129 | 127 |
130 static const struct arabic_state_table_entry { | 128 static const struct arabic_state_table_entry { |
131 uint8_t prev_action; | 129 uint8_t prev_action; |
132 uint8_t curr_action; | 130 uint8_t curr_action; |
133 uint16_t next_state; | 131 uint16_t next_state; |
134 } arabic_state_table[][NUM_STATE_MACHINE_COLS] = | 132 } arabic_state_table[][NUM_STATE_MACHINE_COLS] = |
135 { | 133 { |
136 /* jt_U, jt_R, jt_D, jg_ALAPH, jg_DALATH_RIS
H */ | 134 /* jt_U, jt_L, jt_R, jt_D, jg_ALAPH,
jg_DALATH_RISH */ |
137 | 135 |
138 /* State 0: prev was U, not willing to join. */ | 136 /* State 0: prev was U, not willing to join. */ |
139 { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, }
, | 137 { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {
NONE,ISOL,6}, }, |
140 | 138 |
141 /* State 1: prev was R or ISOL/ALAPH, not willing to join. */ | 139 /* State 1: prev was R or ISOL/ALAPH, not willing to join. */ |
142 { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, }
, | 140 { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {
NONE,ISOL,6}, }, |
143 | 141 |
144 /* State 2: prev was D/ISOL, willing to join. */ | 142 /* State 2: prev was D/L in ISOL form, willing to join. */ |
145 { {NONE,NONE,0}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, }
, | 143 { {NONE,NONE,0}, {NONE,ISOL,2}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {
INIT,FINA,6}, }, |
146 | 144 |
147 /* State 3: prev was D/FINA, willing to join. */ | 145 /* State 3: prev was D in FINA form, willing to join. */ |
148 { {NONE,NONE,0}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, }
, | 146 { {NONE,NONE,0}, {NONE,ISOL,2}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {
MEDI,FINA,6}, }, |
149 | 147 |
150 /* State 4: prev was FINA ALAPH, not willing to join. */ | 148 /* State 4: prev was FINA ALAPH, not willing to join. */ |
151 { {NONE,NONE,0}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, }
, | 149 { {NONE,NONE,0}, {NONE,ISOL,2}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {
MED2,ISOL,6}, }, |
152 | 150 |
153 /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */ | 151 /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */ |
154 { {NONE,NONE,0}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, }
, | 152 { {NONE,NONE,0}, {NONE,ISOL,2}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {
ISOL,ISOL,6}, }, |
155 | 153 |
156 /* State 6: prev was DALATH/RISH, not willing to join. */ | 154 /* State 6: prev was DALATH/RISH, not willing to join. */ |
157 { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, } | 155 { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {
NONE,ISOL,6}, } |
158 }; | 156 }; |
159 | 157 |
160 | 158 |
161 static void | 159 static void |
162 arabic_fallback_shape (const hb_ot_shape_plan_t *plan, | 160 arabic_fallback_shape (const hb_ot_shape_plan_t *plan, |
163 hb_font_t *font, | 161 hb_font_t *font, |
164 hb_buffer_t *buffer); | 162 hb_buffer_t *buffer); |
165 | 163 |
166 static void | 164 static void |
167 collect_features_arabic (hb_ot_shape_planner_t *plan) | 165 collect_features_arabic (hb_ot_shape_planner_t *plan) |
168 { | 166 { |
169 hb_ot_map_builder_t *map = &plan->map; | 167 hb_ot_map_builder_t *map = &plan->map; |
170 | 168 |
171 /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init togeth
er, | 169 /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init togeth
er, |
172 * then rlig and calt each in their own stage. This makes IranNastaliq's ALLA
H | 170 * then rlig and calt each in their own stage. This makes IranNastaliq's ALLA
H |
173 * ligature work correctly. It's unfortunate though... | 171 * ligature work correctly. It's unfortunate though... |
174 * | 172 * |
175 * This also makes Arial Bold in Windows7 work. See: | 173 * This also makes Arial Bold in Windows7 work. See: |
176 * https://bugzilla.mozilla.org/show_bug.cgi?id=644184 | 174 * https://bugzilla.mozilla.org/show_bug.cgi?id=644184 |
177 * | 175 * |
178 * TODO: Add test cases for these two. | 176 * TODO: Add test cases for these two. |
179 */ | 177 */ |
180 | 178 |
181 map->add_bool_feature (HB_TAG('c','c','m','p')); | 179 map->add_global_bool_feature (HB_TAG('c','c','m','p')); |
182 map->add_bool_feature (HB_TAG('l','o','c','l')); | 180 map->add_global_bool_feature (HB_TAG('l','o','c','l')); |
183 | 181 |
184 map->add_gsub_pause (NULL); | 182 map->add_gsub_pause (NULL); |
185 | 183 |
186 for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) | 184 for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) |
187 map->add_bool_feature (arabic_features[i], false, i < 4); /* The first four
features have fallback. */ | 185 map->add_feature (arabic_features[i], 1, i < 4 ? F_HAS_FALLBACK : F_NONE); /
* The first four features have fallback. */ |
188 | 186 |
189 map->add_gsub_pause (NULL); | 187 map->add_gsub_pause (NULL); |
190 | 188 |
191 map->add_bool_feature (HB_TAG('r','l','i','g'), true, true); | 189 map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK); |
192 map->add_gsub_pause (arabic_fallback_shape); | 190 map->add_gsub_pause (arabic_fallback_shape); |
193 | 191 |
194 map->add_bool_feature (HB_TAG('c','a','l','t')); | 192 map->add_global_bool_feature (HB_TAG('c','a','l','t')); |
195 map->add_gsub_pause (NULL); | 193 map->add_gsub_pause (NULL); |
196 | 194 |
197 map->add_bool_feature (HB_TAG('c','s','w','h')); | 195 map->add_global_bool_feature (HB_TAG('c','s','w','h')); |
198 map->add_bool_feature (HB_TAG('d','l','i','g')); | 196 map->add_global_bool_feature (HB_TAG('d','l','i','g')); |
199 map->add_bool_feature (HB_TAG('m','s','e','t')); | 197 map->add_global_bool_feature (HB_TAG('m','s','e','t')); |
200 } | 198 } |
201 | 199 |
202 #include "hb-ot-shape-complex-arabic-fallback.hh" | 200 #include "hb-ot-shape-complex-arabic-fallback.hh" |
203 | 201 |
204 struct arabic_shape_plan_t | 202 struct arabic_shape_plan_t |
205 { | 203 { |
206 ASSERT_POD (); | 204 ASSERT_POD (); |
207 | 205 |
208 /* The "+ 1" in the next array is to accommodate for the "NONE" command, | 206 /* The "+ 1" in the next array is to accommodate for the "NONE" command, |
209 * which is not an OpenType feature, but this simplifies the code by not | 207 * which is not an OpenType feature, but this simplifies the code by not |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 "arabic", | 345 "arabic", |
348 collect_features_arabic, | 346 collect_features_arabic, |
349 NULL, /* override_features */ | 347 NULL, /* override_features */ |
350 data_create_arabic, | 348 data_create_arabic, |
351 data_destroy_arabic, | 349 data_destroy_arabic, |
352 NULL, /* preprocess_text_arabic */ | 350 NULL, /* preprocess_text_arabic */ |
353 NULL, /* normalization_preference */ | 351 NULL, /* normalization_preference */ |
354 NULL, /* decompose */ | 352 NULL, /* decompose */ |
355 NULL, /* compose */ | 353 NULL, /* compose */ |
356 setup_masks_arabic, | 354 setup_masks_arabic, |
357 true, /* zero_width_attached_marks */ | 355 HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE, |
358 true, /* fallback_position */ | 356 true, /* fallback_position */ |
359 }; | 357 }; |
OLD | NEW |