| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2009,2010 Red Hat, Inc. | 2 * Copyright © 2009,2010 Red Hat, Inc. |
| 3 * Copyright © 2010,2011,2012 Google, Inc. | 3 * Copyright © 2010,2011,2012 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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 { | 449 { |
| 450 if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) | 450 if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) |
| 451 break; | 451 break; |
| 452 } | 452 } |
| 453 | 453 |
| 454 /* No default-ignorables found; return. */ | 454 /* No default-ignorables found; return. */ |
| 455 if (i == count) | 455 if (i == count) |
| 456 return; | 456 return; |
| 457 | 457 |
| 458 hb_codepoint_t space; | 458 hb_codepoint_t space; |
| 459 if (c->font->get_glyph (' ', 0, &space)) | 459 if (c->font->get_nominal_glyph (' ', &space)) |
| 460 { | 460 { |
| 461 /* Replace default-ignorables with a zero-advance space glyph. */ | 461 /* Replace default-ignorables with a zero-advance space glyph. */ |
| 462 for (/*continue*/; i < count; i++) | 462 for (/*continue*/; i < count; i++) |
| 463 { | 463 { |
| 464 if (_hb_glyph_info_is_default_ignorable (&info[i])) | 464 if (_hb_glyph_info_is_default_ignorable (&info[i])) |
| 465 info[i].codepoint = space; | 465 info[i].codepoint = space; |
| 466 } | 466 } |
| 467 } | 467 } |
| 468 else | 468 else |
| 469 { | 469 { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 /* Normalization process sets up glyph_index(), we just copy it. */ | 517 /* Normalization process sets up glyph_index(), we just copy it. */ |
| 518 unsigned int count = buffer->len; | 518 unsigned int count = buffer->len; |
| 519 hb_glyph_info_t *info = buffer->info; | 519 hb_glyph_info_t *info = buffer->info; |
| 520 for (unsigned int i = 0; i < count; i++) | 520 for (unsigned int i = 0; i < count; i++) |
| 521 info[i].codepoint = info[i].glyph_index(); | 521 info[i].codepoint = info[i].glyph_index(); |
| 522 | 522 |
| 523 buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; | 523 buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; |
| 524 } | 524 } |
| 525 | 525 |
| 526 static inline void | 526 static inline void |
| 527 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) | |
| 528 { | |
| 529 unsigned int count = c->buffer->len; | |
| 530 hb_glyph_info_t *info = c->buffer->info; | |
| 531 for (unsigned int i = 0; i < count; i++) | |
| 532 { | |
| 533 hb_ot_layout_glyph_props_flags_t klass; | |
| 534 | |
| 535 /* Never mark default-ignorables as marks. | |
| 536 * They won't get in the way of lookups anyway, | |
| 537 * but having them as mark will cause them to be skipped | |
| 538 * over if the lookup-flag says so, but at least for the | |
| 539 * Mongolian variation selectors, looks like Uniscribe | |
| 540 * marks them as non-mark. Some Mongolian fonts without | |
| 541 * GDEF rely on this. Another notable character that | |
| 542 * this applies to is COMBINING GRAPHEME JOINER. */ | |
| 543 klass = (_hb_glyph_info_get_general_category (&info[i]) != | |
| 544 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK || | |
| 545 _hb_glyph_info_is_default_ignorable (&info[i])) ? | |
| 546 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : | |
| 547 HB_OT_LAYOUT_GLYPH_PROPS_MARK; | |
| 548 _hb_glyph_info_set_glyph_props (&info[i], klass); | |
| 549 } | |
| 550 } | |
| 551 | |
| 552 static inline void | |
| 553 hb_ot_substitute_default (hb_ot_shape_context_t *c) | 527 hb_ot_substitute_default (hb_ot_shape_context_t *c) |
| 554 { | 528 { |
| 555 hb_buffer_t *buffer = c->buffer; | 529 hb_buffer_t *buffer = c->buffer; |
| 556 | 530 |
| 557 hb_ot_shape_initialize_masks (c); | 531 hb_ot_shape_initialize_masks (c); |
| 558 | 532 |
| 559 hb_ot_mirror_chars (c); | 533 hb_ot_mirror_chars (c); |
| 560 | 534 |
| 561 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); | 535 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); |
| 562 | 536 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 573 HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); | 547 HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); |
| 574 } | 548 } |
| 575 | 549 |
| 576 static inline void | 550 static inline void |
| 577 hb_ot_substitute_complex (hb_ot_shape_context_t *c) | 551 hb_ot_substitute_complex (hb_ot_shape_context_t *c) |
| 578 { | 552 { |
| 579 hb_buffer_t *buffer = c->buffer; | 553 hb_buffer_t *buffer = c->buffer; |
| 580 | 554 |
| 581 hb_ot_layout_substitute_start (c->font, buffer); | 555 hb_ot_layout_substitute_start (c->font, buffer); |
| 582 | 556 |
| 583 if (!hb_ot_layout_has_glyph_classes (c->face)) | |
| 584 hb_synthesize_glyph_classes (c); | |
| 585 | |
| 586 c->plan->substitute (c->font, buffer); | 557 c->plan->substitute (c->font, buffer); |
| 587 | 558 |
| 588 return; | 559 return; |
| 589 } | 560 } |
| 590 | 561 |
| 591 static inline void | 562 static inline void |
| 592 hb_ot_substitute (hb_ot_shape_context_t *c) | 563 hb_ot_substitute (hb_ot_shape_context_t *c) |
| 593 { | 564 { |
| 594 hb_ot_substitute_default (c); | 565 hb_ot_substitute_default (c); |
| 595 | 566 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 608 } | 579 } |
| 609 | 580 |
| 610 static inline void | 581 static inline void |
| 611 zero_mark_width (hb_glyph_position_t *pos) | 582 zero_mark_width (hb_glyph_position_t *pos) |
| 612 { | 583 { |
| 613 pos->x_advance = 0; | 584 pos->x_advance = 0; |
| 614 pos->y_advance = 0; | 585 pos->y_advance = 0; |
| 615 } | 586 } |
| 616 | 587 |
| 617 static inline void | 588 static inline void |
| 618 zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets) | |
| 619 { | |
| 620 if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) | |
| 621 return; | |
| 622 | |
| 623 unsigned int count = buffer->len; | |
| 624 hb_glyph_info_t *info = buffer->info; | |
| 625 for (unsigned int i = 0; i < count; i++) | |
| 626 if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CAT
EGORY_NON_SPACING_MARK) | |
| 627 { | |
| 628 if (adjust_offsets) | |
| 629 adjust_mark_offsets (&buffer->pos[i]); | |
| 630 zero_mark_width (&buffer->pos[i]); | |
| 631 } | |
| 632 } | |
| 633 | |
| 634 static inline void | |
| 635 zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) | 589 zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) |
| 636 { | 590 { |
| 637 unsigned int count = buffer->len; | 591 unsigned int count = buffer->len; |
| 638 hb_glyph_info_t *info = buffer->info; | 592 hb_glyph_info_t *info = buffer->info; |
| 639 for (unsigned int i = 0; i < count; i++) | 593 for (unsigned int i = 0; i < count; i++) |
| 640 if (_hb_glyph_info_is_mark (&info[i])) | 594 if (_hb_glyph_info_is_mark (&info[i])) |
| 641 { | 595 { |
| 642 if (adjust_offsets) | 596 if (adjust_offsets) |
| 643 adjust_mark_offsets (&buffer->pos[i]); | 597 adjust_mark_offsets (&buffer->pos[i]); |
| 644 zero_mark_width (&buffer->pos[i]); | 598 zero_mark_width (&buffer->pos[i]); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 */ | 652 */ |
| 699 bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallb
ack_position || | 653 bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallb
ack_position || |
| 700 HB_DIRECTION_IS_BACKWARD (c->buffer->prop
s.direction)); | 654 HB_DIRECTION_IS_BACKWARD (c->buffer->prop
s.direction)); |
| 701 | 655 |
| 702 switch (c->plan->shaper->zero_width_marks) | 656 switch (c->plan->shaper->zero_width_marks) |
| 703 { | 657 { |
| 704 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: | 658 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: |
| 705 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); | 659 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); |
| 706 break; | 660 break; |
| 707 | 661 |
| 708 /* Not currently used for any shaper: | |
| 709 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: | |
| 710 zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); | |
| 711 break; | |
| 712 */ | |
| 713 | |
| 714 default: | 662 default: |
| 715 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: | 663 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: |
| 716 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: | |
| 717 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: | 664 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: |
| 718 break; | 665 break; |
| 719 } | 666 } |
| 720 | 667 |
| 721 if (has_positioning) | 668 if (has_positioning) |
| 722 { | 669 { |
| 723 hb_glyph_info_t *info = c->buffer->info; | 670 hb_glyph_info_t *info = c->buffer->info; |
| 724 hb_glyph_position_t *pos = c->buffer->pos; | 671 hb_glyph_position_t *pos = c->buffer->pos; |
| 725 | 672 |
| 726 /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change
it back. */ | 673 /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change
it back. */ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 739 for (unsigned int i = 0; i < count; i++) | 686 for (unsigned int i = 0; i < count; i++) |
| 740 c->font->subtract_glyph_h_origin (info[i].codepoint, | 687 c->font->subtract_glyph_h_origin (info[i].codepoint, |
| 741 &pos[i].x_offset, | 688 &pos[i].x_offset, |
| 742 &pos[i].y_offset); | 689 &pos[i].y_offset); |
| 743 | 690 |
| 744 ret = true; | 691 ret = true; |
| 745 } | 692 } |
| 746 | 693 |
| 747 switch (c->plan->shaper->zero_width_marks) | 694 switch (c->plan->shaper->zero_width_marks) |
| 748 { | 695 { |
| 749 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: | |
| 750 zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); | |
| 751 break; | |
| 752 | |
| 753 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: | 696 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: |
| 754 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); | 697 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); |
| 755 break; | 698 break; |
| 756 | 699 |
| 757 default: | 700 default: |
| 758 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: | 701 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: |
| 759 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: | |
| 760 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: | 702 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: |
| 761 break; | 703 break; |
| 762 } | 704 } |
| 763 | 705 |
| 764 /* Finishing off GPOS has to follow a certain order. */ | 706 /* Finishing off GPOS has to follow a certain order. */ |
| 765 hb_ot_layout_position_finish_advances (c->font, c->buffer); | 707 hb_ot_layout_position_finish_advances (c->font, c->buffer); |
| 766 hb_ot_zero_width_default_ignorables (c); | 708 hb_ot_zero_width_default_ignorables (c); |
| 767 hb_ot_layout_position_finish_offsets (c->font, c->buffer); | 709 hb_ot_layout_position_finish_offsets (c->font, c->buffer); |
| 768 | 710 |
| 769 return ret; | 711 return ret; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 | 812 |
| 871 /* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it pu
blic. */ | 813 /* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it pu
blic. */ |
| 872 static void | 814 static void |
| 873 add_char (hb_font_t *font, | 815 add_char (hb_font_t *font, |
| 874 hb_unicode_funcs_t *unicode, | 816 hb_unicode_funcs_t *unicode, |
| 875 hb_bool_t mirror, | 817 hb_bool_t mirror, |
| 876 hb_codepoint_t u, | 818 hb_codepoint_t u, |
| 877 hb_set_t *glyphs) | 819 hb_set_t *glyphs) |
| 878 { | 820 { |
| 879 hb_codepoint_t glyph; | 821 hb_codepoint_t glyph; |
| 880 if (font->get_glyph (u, 0, &glyph)) | 822 if (font->get_nominal_glyph (u, &glyph)) |
| 881 glyphs->add (glyph); | 823 glyphs->add (glyph); |
| 882 if (mirror) | 824 if (mirror) |
| 883 { | 825 { |
| 884 hb_codepoint_t m = unicode->mirroring (u); | 826 hb_codepoint_t m = unicode->mirroring (u); |
| 885 if (m != u && font->get_glyph (m, 0, &glyph)) | 827 if (m != u && font->get_nominal_glyph (m, &glyph)) |
| 886 glyphs->add (glyph); | 828 glyphs->add (glyph); |
| 887 } | 829 } |
| 888 } | 830 } |
| 889 | 831 |
| 890 | 832 |
| 891 /** | 833 /** |
| 892 * hb_ot_shape_glyphs_closure: | 834 * hb_ot_shape_glyphs_closure: |
| 893 * | 835 * |
| 894 * Since: 0.9.2 | 836 * Since: 0.9.2 |
| 895 **/ | 837 **/ |
| (...skipping 25 matching lines...) Expand all Loading... |
| 921 hb_set_t copy; | 863 hb_set_t copy; |
| 922 copy.init (); | 864 copy.init (); |
| 923 do { | 865 do { |
| 924 copy.set (glyphs); | 866 copy.set (glyphs); |
| 925 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) | 867 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) |
| 926 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); | 868 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); |
| 927 } while (!copy.is_equal (glyphs)); | 869 } while (!copy.is_equal (glyphs)); |
| 928 | 870 |
| 929 hb_shape_plan_destroy (shape_plan); | 871 hb_shape_plan_destroy (shape_plan); |
| 930 } | 872 } |
| OLD | NEW |