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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 | 150 |
151 /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */ | 151 /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */ |
152 { {NONE,NONE,0}, {NONE,ISOL,2}, {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}, }, |
153 | 153 |
154 /* State 6: prev was DALATH/RISH, not willing to join. */ | 154 /* State 6: prev was DALATH/RISH, not willing to join. */ |
155 { {NONE,NONE,0}, {NONE,ISOL,2}, {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}, } |
156 }; | 156 }; |
157 | 157 |
158 | 158 |
159 static void | 159 static void |
| 160 nuke_joiners (const hb_ot_shape_plan_t *plan, |
| 161 hb_font_t *font, |
| 162 hb_buffer_t *buffer); |
| 163 |
| 164 static void |
160 arabic_fallback_shape (const hb_ot_shape_plan_t *plan, | 165 arabic_fallback_shape (const hb_ot_shape_plan_t *plan, |
161 hb_font_t *font, | 166 hb_font_t *font, |
162 hb_buffer_t *buffer); | 167 hb_buffer_t *buffer); |
163 | 168 |
164 static void | 169 static void |
165 collect_features_arabic (hb_ot_shape_planner_t *plan) | 170 collect_features_arabic (hb_ot_shape_planner_t *plan) |
166 { | 171 { |
167 hb_ot_map_builder_t *map = &plan->map; | 172 hb_ot_map_builder_t *map = &plan->map; |
168 | 173 |
169 /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init togeth
er, | 174 /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init togeth
er, |
170 * then rlig and calt each in their own stage. This makes IranNastaliq's ALLA
H | 175 * then rlig and calt each in their own stage. This makes IranNastaliq's ALLA
H |
171 * ligature work correctly. It's unfortunate though... | 176 * ligature work correctly. It's unfortunate though... |
172 * | 177 * |
173 * This also makes Arial Bold in Windows7 work. See: | 178 * This also makes Arial Bold in Windows7 work. See: |
174 * https://bugzilla.mozilla.org/show_bug.cgi?id=644184 | 179 * https://bugzilla.mozilla.org/show_bug.cgi?id=644184 |
175 * | 180 * |
176 * TODO: Add test cases for these two. | 181 * TODO: Add test cases for these two. |
177 */ | 182 */ |
178 | 183 |
| 184 map->add_gsub_pause (nuke_joiners); |
| 185 |
179 map->add_global_bool_feature (HB_TAG('c','c','m','p')); | 186 map->add_global_bool_feature (HB_TAG('c','c','m','p')); |
180 map->add_global_bool_feature (HB_TAG('l','o','c','l')); | 187 map->add_global_bool_feature (HB_TAG('l','o','c','l')); |
181 | 188 |
182 map->add_gsub_pause (NULL); | 189 map->add_gsub_pause (NULL); |
183 | 190 |
184 for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) | 191 for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) |
185 map->add_feature (arabic_features[i], 1, i < 4 ? F_HAS_FALLBACK : F_NONE); /
* The first four features have fallback. */ | 192 map->add_feature (arabic_features[i], 1, i < 4 ? F_HAS_FALLBACK : F_NONE); /
* The first four features have fallback. */ |
186 | 193 |
187 map->add_gsub_pause (NULL); | 194 map->add_gsub_pause (NULL); |
188 | 195 |
189 map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK); | 196 map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK); |
190 map->add_gsub_pause (arabic_fallback_shape); | 197 map->add_gsub_pause (arabic_fallback_shape); |
191 | 198 |
192 map->add_global_bool_feature (HB_TAG('c','a','l','t')); | 199 map->add_global_bool_feature (HB_TAG('c','a','l','t')); |
193 map->add_gsub_pause (NULL); | 200 map->add_gsub_pause (NULL); |
194 | 201 |
195 map->add_global_bool_feature (HB_TAG('c','s','w','h')); | 202 map->add_global_bool_feature (HB_TAG('c','s','w','h')); |
196 map->add_global_bool_feature (HB_TAG('d','l','i','g')); | |
197 map->add_global_bool_feature (HB_TAG('m','s','e','t')); | 203 map->add_global_bool_feature (HB_TAG('m','s','e','t')); |
198 } | 204 } |
199 | 205 |
200 #include "hb-ot-shape-complex-arabic-fallback.hh" | 206 #include "hb-ot-shape-complex-arabic-fallback.hh" |
201 | 207 |
202 struct arabic_shape_plan_t | 208 struct arabic_shape_plan_t |
203 { | 209 { |
204 ASSERT_POD (); | 210 ASSERT_POD (); |
205 | 211 |
206 /* The "+ 1" in the next array is to accommodate for the "NONE" command, | 212 /* The "+ 1" in the next array is to accommodate for the "NONE" command, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 unsigned int this_type = get_joining_type (buffer->info[i].codepoint, _hb_gl
yph_info_get_general_category (&buffer->info[i])); | 273 unsigned int this_type = get_joining_type (buffer->info[i].codepoint, _hb_gl
yph_info_get_general_category (&buffer->info[i])); |
268 | 274 |
269 if (unlikely (this_type == JOINING_TYPE_T)) { | 275 if (unlikely (this_type == JOINING_TYPE_T)) { |
270 buffer->info[i].arabic_shaping_action() = NONE; | 276 buffer->info[i].arabic_shaping_action() = NONE; |
271 continue; | 277 continue; |
272 } | 278 } |
273 | 279 |
274 const arabic_state_table_entry *entry = &arabic_state_table[state][this_type
]; | 280 const arabic_state_table_entry *entry = &arabic_state_table[state][this_type
]; |
275 | 281 |
276 if (entry->prev_action != NONE && prev != (unsigned int) -1) | 282 if (entry->prev_action != NONE && prev != (unsigned int) -1) |
277 buffer->info[prev].arabic_shaping_action() = entry->prev_action; | 283 for (; prev < i; prev++) |
| 284 » buffer->info[prev].arabic_shaping_action() = entry->prev_action; |
278 | 285 |
279 buffer->info[i].arabic_shaping_action() = entry->curr_action; | 286 buffer->info[i].arabic_shaping_action() = entry->curr_action; |
280 | 287 |
281 prev = i; | 288 prev = i; |
282 state = entry->next_state; | 289 state = entry->next_state; |
283 } | 290 } |
284 | 291 |
285 if (!(buffer->flags & HB_BUFFER_FLAG_EOT)) | 292 if (!(buffer->flags & HB_BUFFER_FLAG_EOT)) |
286 for (unsigned int i = 0; i < buffer->context_len[1]; i++) | 293 for (unsigned int i = 0; i < buffer->context_len[1]; i++) |
287 { | 294 { |
(...skipping 20 matching lines...) Expand all Loading... |
308 const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->d
ata; | 315 const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->d
ata; |
309 | 316 |
310 arabic_joining (buffer); | 317 arabic_joining (buffer); |
311 unsigned int count = buffer->len; | 318 unsigned int count = buffer->len; |
312 for (unsigned int i = 0; i < count; i++) | 319 for (unsigned int i = 0; i < count; i++) |
313 buffer->info[i].mask |= arabic_plan->mask_array[buffer->info[i].arabic_shapi
ng_action()]; | 320 buffer->info[i].mask |= arabic_plan->mask_array[buffer->info[i].arabic_shapi
ng_action()]; |
314 } | 321 } |
315 | 322 |
316 | 323 |
317 static void | 324 static void |
| 325 nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED, |
| 326 hb_font_t *font HB_UNUSED, |
| 327 hb_buffer_t *buffer) |
| 328 { |
| 329 unsigned int count = buffer->len; |
| 330 for (unsigned int i = 0; i < count; i++) |
| 331 if (_hb_glyph_info_is_zwj (&buffer->info[i])) |
| 332 _hb_glyph_info_flip_joiners (&buffer->info[i]); |
| 333 } |
| 334 |
| 335 static void |
318 arabic_fallback_shape (const hb_ot_shape_plan_t *plan, | 336 arabic_fallback_shape (const hb_ot_shape_plan_t *plan, |
319 hb_font_t *font, | 337 hb_font_t *font, |
320 hb_buffer_t *buffer) | 338 hb_buffer_t *buffer) |
321 { | 339 { |
322 const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->d
ata; | 340 const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->d
ata; |
323 | 341 |
324 if (!arabic_plan->do_fallback) | 342 if (!arabic_plan->do_fallback) |
325 return; | 343 return; |
326 | 344 |
327 retry: | 345 retry: |
(...skipping 20 matching lines...) Expand all Loading... |
348 data_create_arabic, | 366 data_create_arabic, |
349 data_destroy_arabic, | 367 data_destroy_arabic, |
350 NULL, /* preprocess_text_arabic */ | 368 NULL, /* preprocess_text_arabic */ |
351 NULL, /* normalization_preference */ | 369 NULL, /* normalization_preference */ |
352 NULL, /* decompose */ | 370 NULL, /* decompose */ |
353 NULL, /* compose */ | 371 NULL, /* compose */ |
354 setup_masks_arabic, | 372 setup_masks_arabic, |
355 HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, | 373 HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, |
356 true, /* fallback_position */ | 374 true, /* fallback_position */ |
357 }; | 375 }; |
OLD | NEW |