| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2015 Mozilla Foundation. | 2 * Copyright © 2015 Mozilla Foundation. |
| 3 * Copyright © 2015 Google, Inc. | 3 * Copyright © 2015 Google, Inc. |
| 4 * | 4 * |
| 5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
| 6 * | 6 * |
| 7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
| 8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
| 9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
| 10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end
- start); | 278 unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end
- start); |
| 279 for (unsigned int i = start; i < start + limit; i++) | 279 for (unsigned int i = start; i < start + limit; i++) |
| 280 info[i].mask |= mask; | 280 info[i].mask |= mask; |
| 281 } | 281 } |
| 282 } | 282 } |
| 283 | 283 |
| 284 static void | 284 static void |
| 285 setup_topographical_masks (const hb_ot_shape_plan_t *plan, | 285 setup_topographical_masks (const hb_ot_shape_plan_t *plan, |
| 286 hb_buffer_t *buffer) | 286 hb_buffer_t *buffer) |
| 287 { | 287 { |
| 288 const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; |
| 289 if (use_plan->arabic_plan) |
| 290 return; |
| 288 | 291 |
| 289 ASSERT_STATIC (INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4); | 292 ASSERT_STATIC (INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4); |
| 290 hb_mask_t masks[4], all_masks = 0; | 293 hb_mask_t masks[4], all_masks = 0; |
| 291 for (unsigned int i = 0; i < 4; i++) | 294 for (unsigned int i = 0; i < 4; i++) |
| 292 { | 295 { |
| 293 masks[i] = plan->map.get_1_mask (arabic_features[i]); | 296 masks[i] = plan->map.get_1_mask (arabic_features[i]); |
| 294 if (masks[i] == plan->map.get_global_mask ()) | 297 if (masks[i] == plan->map.get_global_mask ()) |
| 295 masks[i] = 0; | 298 masks[i] = 0; |
| 296 all_masks |= masks[i]; | 299 all_masks |= masks[i]; |
| 297 } | 300 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 } | 356 } |
| 354 | 357 |
| 355 static void | 358 static void |
| 356 clear_substitution_flags (const hb_ot_shape_plan_t *plan, | 359 clear_substitution_flags (const hb_ot_shape_plan_t *plan, |
| 357 hb_font_t *font HB_UNUSED, | 360 hb_font_t *font HB_UNUSED, |
| 358 hb_buffer_t *buffer) | 361 hb_buffer_t *buffer) |
| 359 { | 362 { |
| 360 hb_glyph_info_t *info = buffer->info; | 363 hb_glyph_info_t *info = buffer->info; |
| 361 unsigned int count = buffer->len; | 364 unsigned int count = buffer->len; |
| 362 for (unsigned int i = 0; i < count; i++) | 365 for (unsigned int i = 0; i < count; i++) |
| 363 _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (&info[i]); | 366 _hb_glyph_info_clear_substituted (&info[i]); |
| 364 } | 367 } |
| 365 | 368 |
| 366 static void | 369 static void |
| 367 record_rphf (const hb_ot_shape_plan_t *plan, | 370 record_rphf (const hb_ot_shape_plan_t *plan, |
| 368 hb_font_t *font, | 371 hb_font_t *font, |
| 369 hb_buffer_t *buffer) | 372 hb_buffer_t *buffer) |
| 370 { | 373 { |
| 371 const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; | 374 const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; |
| 372 | 375 |
| 373 hb_mask_t mask = use_plan->rphf_mask; | 376 hb_mask_t mask = use_plan->rphf_mask; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 398 /* Mark a substituted pref as VPre, as they behave the same way. */ | 401 /* Mark a substituted pref as VPre, as they behave the same way. */ |
| 399 for (unsigned int i = start; i < end; i++) | 402 for (unsigned int i = start; i < end; i++) |
| 400 if (_hb_glyph_info_substituted (&info[i])) | 403 if (_hb_glyph_info_substituted (&info[i])) |
| 401 { | 404 { |
| 402 info[i].use_category() = USE_VPre; | 405 info[i].use_category() = USE_VPre; |
| 403 break; | 406 break; |
| 404 } | 407 } |
| 405 } | 408 } |
| 406 } | 409 } |
| 407 | 410 |
| 411 static inline bool |
| 412 is_halant (const hb_glyph_info_t &info) |
| 413 { |
| 414 return info.use_category() == USE_H && !_hb_glyph_info_ligated (&info); |
| 415 } |
| 416 |
| 408 static void | 417 static void |
| 409 reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) | 418 reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) |
| 410 { | 419 { |
| 411 syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllabl
e() & 0x0F); | 420 syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllabl
e() & 0x0F); |
| 412 /* Only a few syllable types need reordering. */ | 421 /* Only a few syllable types need reordering. */ |
| 413 if (unlikely (!(FLAG_SAFE (syllable_type) & | 422 if (unlikely (!(FLAG_SAFE (syllable_type) & |
| 414 (FLAG (virama_terminated_cluster) | | 423 (FLAG (virama_terminated_cluster) | |
| 415 FLAG (consonant_cluster) | | 424 FLAG (consonant_cluster) | |
| 416 FLAG (vowel_cluster) | | 425 FLAG (vowel_cluster) | |
| 417 FLAG (broken_cluster) | | 426 FLAG (broken_cluster) | |
| 418 0)))) | 427 0)))) |
| 419 return; | 428 return; |
| 420 | 429 |
| 421 hb_glyph_info_t *info = buffer->info; | 430 hb_glyph_info_t *info = buffer->info; |
| 422 | 431 |
| 423 #define HALANT_FLAGS FLAG(USE_H) | |
| 424 #define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB) | FLAG (USE_IV)) | 432 #define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB) | FLAG (USE_IV)) |
| 425 | 433 |
| 426 /* Move things forward. */ | 434 /* Move things forward. */ |
| 427 if (info[start].use_category() == USE_R && end - start > 1) | 435 if (info[start].use_category() == USE_R && end - start > 1) |
| 428 { | 436 { |
| 429 /* Got a repha. Reorder it to after first base, before first halant. */ | 437 /* Got a repha. Reorder it to after first base, before first halant. */ |
| 430 for (unsigned int i = start + 1; i < end; i++) | 438 for (unsigned int i = start + 1; i < end; i++) |
| 431 if (FLAG_UNSAFE (info[i].use_category()) & (HALANT_FLAGS | BASE_FLAGS)) | 439 if ((FLAG_UNSAFE (info[i].use_category()) & (BASE_FLAGS)) || is_halant (in
fo[i])) |
| 432 { | 440 { |
| 433 /* If we hit a halant, move before it; otherwise it's a base: move to it
's | 441 /* If we hit a halant, move before it; otherwise it's a base: move to it
's |
| 434 * place, and shift things in between backward. */ | 442 * place, and shift things in between backward. */ |
| 435 | 443 |
| 436 » if (info[i].use_category() == USE_H) | 444 » if (is_halant (info[i])) |
| 437 i--; | 445 i--; |
| 438 | 446 |
| 439 buffer->merge_clusters (start, i + 1); | 447 buffer->merge_clusters (start, i + 1); |
| 440 hb_glyph_info_t t = info[start]; | 448 hb_glyph_info_t t = info[start]; |
| 441 memmove (&info[start], &info[start + 1], (i - start) * sizeof (info[0]))
; | 449 memmove (&info[start], &info[start + 1], (i - start) * sizeof (info[0]))
; |
| 442 info[i] = t; | 450 info[i] = t; |
| 443 | 451 |
| 444 break; | 452 break; |
| 445 } | 453 } |
| 446 } | 454 } |
| 447 | 455 |
| 448 /* Move things back. */ | 456 /* Move things back. */ |
| 449 unsigned int j = end; | 457 unsigned int j = end; |
| 450 for (unsigned int i = start; i < end; i++) | 458 for (unsigned int i = start; i < end; i++) |
| 451 { | 459 { |
| 452 uint32_t flag = FLAG_UNSAFE (info[i].use_category()); | 460 uint32_t flag = FLAG_UNSAFE (info[i].use_category()); |
| 453 if (flag & (HALANT_FLAGS | BASE_FLAGS)) | 461 if ((flag & (BASE_FLAGS)) || is_halant (info[i])) |
| 454 { | 462 { |
| 455 /* If we hit a halant, move before it; otherwise it's a base: move to it's | 463 /* If we hit a halant, move after it; otherwise it's a base: move to it's |
| 456 * place, and shift things in between backward. */ | 464 * place, and shift things in between backward. */ |
| 457 if (info[i].use_category() == USE_H) | 465 if (is_halant (info[i])) |
| 458 j = i + 1; | 466 j = i + 1; |
| 459 else | 467 else |
| 460 j = i; | 468 j = i; |
| 461 } | 469 } |
| 462 else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && | 470 else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && |
| 463 /* Only move the first component of a MultipleSubst. */ | 471 /* Only move the first component of a MultipleSubst. */ |
| 464 0 == _hb_glyph_info_get_lig_comp (&info[i]) && | 472 0 == _hb_glyph_info_get_lig_comp (&info[i]) && |
| 465 j < i) | 473 j < i) |
| 466 { | 474 { |
| 467 buffer->merge_clusters (j, i + 1); | 475 buffer->merge_clusters (j, i + 1); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 551 static bool | 559 static bool |
| 552 compose_use (const hb_ot_shape_normalize_context_t *c, | 560 compose_use (const hb_ot_shape_normalize_context_t *c, |
| 553 hb_codepoint_t a, | 561 hb_codepoint_t a, |
| 554 hb_codepoint_t b, | 562 hb_codepoint_t b, |
| 555 hb_codepoint_t *ab) | 563 hb_codepoint_t *ab) |
| 556 { | 564 { |
| 557 /* Avoid recomposing split matras. */ | 565 /* Avoid recomposing split matras. */ |
| 558 if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a))) | 566 if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a))) |
| 559 return false; | 567 return false; |
| 560 | 568 |
| 561 return c->unicode->compose (a, b, ab); | 569 return (bool)c->unicode->compose (a, b, ab); |
| 562 } | 570 } |
| 563 | 571 |
| 564 | 572 |
| 565 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = | 573 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = |
| 566 { | 574 { |
| 567 "use", | 575 "use", |
| 568 collect_features_use, | 576 collect_features_use, |
| 569 NULL, /* override_features */ | 577 NULL, /* override_features */ |
| 570 data_create_use, | 578 data_create_use, |
| 571 data_destroy_use, | 579 data_destroy_use, |
| 572 NULL, /* preprocess_text */ | 580 NULL, /* preprocess_text */ |
| 573 NULL, /* postprocess_glyphs */ | 581 NULL, /* postprocess_glyphs */ |
| 574 HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, | 582 HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, |
| 575 NULL, /* decompose */ | 583 NULL, /* decompose */ |
| 576 compose_use, | 584 compose_use, |
| 577 setup_masks_use, | 585 setup_masks_use, |
| 578 HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, | 586 HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, |
| 579 false, /* fallback_position */ | 587 false, /* fallback_position */ |
| 580 }; | 588 }; |
| OLD | NEW |