| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 } | 138 } |
| 139 | 139 |
| 140 | 140 |
| 141 /* | 141 /* |
| 142 * shaper font data | 142 * shaper font data |
| 143 */ | 143 */ |
| 144 | 144 |
| 145 struct hb_ot_shaper_font_data_t {}; | 145 struct hb_ot_shaper_font_data_t {}; |
| 146 | 146 |
| 147 hb_ot_shaper_font_data_t * | 147 hb_ot_shaper_font_data_t * |
| 148 _hb_ot_shaper_font_data_create (hb_font_t *font) | 148 _hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED) |
| 149 { | 149 { |
| 150 return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; | 150 return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; |
| 151 } | 151 } |
| 152 | 152 |
| 153 void | 153 void |
| 154 _hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data) | 154 _hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data) |
| 155 { | 155 { |
| 156 } | 156 } |
| 157 | 157 |
| 158 | 158 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 buffer->swap_buffers (); | 260 buffer->swap_buffers (); |
| 261 } | 261 } |
| 262 | 262 |
| 263 static void | 263 static void |
| 264 hb_form_clusters (hb_buffer_t *buffer) | 264 hb_form_clusters (hb_buffer_t *buffer) |
| 265 { | 265 { |
| 266 if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || | 266 if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || |
| 267 buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) | 267 buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) |
| 268 return; | 268 return; |
| 269 | 269 |
| 270 /* Loop duplicated in hb_ensure_native_direction(). */ | 270 /* Loop duplicated in hb_ensure_native_direction(), and in _hb-coretext.cc */ |
| 271 unsigned int base = 0; | 271 unsigned int base = 0; |
| 272 unsigned int count = buffer->len; | 272 unsigned int count = buffer->len; |
| 273 hb_glyph_info_t *info = buffer->info; | 273 hb_glyph_info_t *info = buffer->info; |
| 274 for (unsigned int i = 1; i < count; i++) | 274 for (unsigned int i = 1; i < count; i++) |
| 275 { | 275 { |
| 276 if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general
_category (&info[i])))) | 276 if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general
_category (&info[i])) && |
| 277 » » !_hb_glyph_info_is_joiner (&info[i]))) |
| 277 { | 278 { |
| 278 buffer->merge_clusters (base, i); | 279 buffer->merge_clusters (base, i); |
| 279 base = i; | 280 base = i; |
| 280 } | 281 } |
| 281 } | 282 } |
| 282 buffer->merge_clusters (base, count); | 283 buffer->merge_clusters (base, count); |
| 283 } | 284 } |
| 284 | 285 |
| 285 static void | 286 static void |
| 286 hb_ensure_native_direction (hb_buffer_t *buffer) | 287 hb_ensure_native_direction (hb_buffer_t *buffer) |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 { | 578 { |
| 578 hb_buffer_t *buffer = c->buffer; | 579 hb_buffer_t *buffer = c->buffer; |
| 579 | 580 |
| 580 hb_ot_layout_substitute_start (c->font, buffer); | 581 hb_ot_layout_substitute_start (c->font, buffer); |
| 581 | 582 |
| 582 if (!hb_ot_layout_has_glyph_classes (c->face)) | 583 if (!hb_ot_layout_has_glyph_classes (c->face)) |
| 583 hb_synthesize_glyph_classes (c); | 584 hb_synthesize_glyph_classes (c); |
| 584 | 585 |
| 585 c->plan->substitute (c->font, buffer); | 586 c->plan->substitute (c->font, buffer); |
| 586 | 587 |
| 587 hb_ot_layout_substitute_finish (c->font, buffer); | |
| 588 | |
| 589 return; | 588 return; |
| 590 } | 589 } |
| 591 | 590 |
| 592 static inline void | 591 static inline void |
| 593 hb_ot_substitute (hb_ot_shape_context_t *c) | 592 hb_ot_substitute (hb_ot_shape_context_t *c) |
| 594 { | 593 { |
| 595 hb_ot_substitute_default (c); | 594 hb_ot_substitute_default (c); |
| 596 | 595 |
| 597 _hb_buffer_allocate_gsubgpos_vars (c->buffer); | 596 _hb_buffer_allocate_gsubgpos_vars (c->buffer); |
| 598 | 597 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 628 { | 627 { |
| 629 if (adjust_offsets) | 628 if (adjust_offsets) |
| 630 adjust_mark_offsets (&buffer->pos[i]); | 629 adjust_mark_offsets (&buffer->pos[i]); |
| 631 zero_mark_width (&buffer->pos[i]); | 630 zero_mark_width (&buffer->pos[i]); |
| 632 } | 631 } |
| 633 } | 632 } |
| 634 | 633 |
| 635 static inline void | 634 static inline void |
| 636 zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) | 635 zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) |
| 637 { | 636 { |
| 638 /* This one is a hack; Technically GDEF can mark ASCII glyphs as marks, but we
don't listen. */ | |
| 639 if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) | |
| 640 return; | |
| 641 | |
| 642 unsigned int count = buffer->len; | 637 unsigned int count = buffer->len; |
| 643 hb_glyph_info_t *info = buffer->info; | 638 hb_glyph_info_t *info = buffer->info; |
| 644 for (unsigned int i = 0; i < count; i++) | 639 for (unsigned int i = 0; i < count; i++) |
| 645 if (_hb_glyph_info_is_mark (&info[i])) | 640 if (_hb_glyph_info_is_mark (&info[i])) |
| 646 { | 641 { |
| 647 if (adjust_offsets) | 642 if (adjust_offsets) |
| 648 adjust_mark_offsets (&buffer->pos[i]); | 643 adjust_mark_offsets (&buffer->pos[i]); |
| 649 zero_mark_width (&buffer->pos[i]); | 644 zero_mark_width (&buffer->pos[i]); |
| 650 } | 645 } |
| 651 } | 646 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 679 &pos[i].y_offset); | 674 &pos[i].y_offset); |
| 680 } | 675 } |
| 681 } | 676 } |
| 682 if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) | 677 if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) |
| 683 _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); | 678 _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); |
| 684 } | 679 } |
| 685 | 680 |
| 686 static inline bool | 681 static inline bool |
| 687 hb_ot_position_complex (hb_ot_shape_context_t *c) | 682 hb_ot_position_complex (hb_ot_shape_context_t *c) |
| 688 { | 683 { |
| 684 hb_ot_layout_position_start (c->font, c->buffer); |
| 685 |
| 689 bool ret = false; | 686 bool ret = false; |
| 690 unsigned int count = c->buffer->len; | 687 unsigned int count = c->buffer->len; |
| 691 bool has_positioning = (bool) hb_ot_layout_has_positioning (c->face); | 688 bool has_positioning = (bool) hb_ot_layout_has_positioning (c->face); |
| 689 |
| 692 /* If the font has no GPOS, AND, no fallback positioning will | 690 /* If the font has no GPOS, AND, no fallback positioning will |
| 693 * happen, AND, direction is forward, then when zeroing mark | 691 * happen, AND, direction is forward, then when zeroing mark |
| 694 * widths, we shift the mark with it, such that the mark | 692 * widths, we shift the mark with it, such that the mark |
| 695 * is positioned hanging over the previous glyph. When | 693 * is positioned hanging over the previous glyph. When |
| 696 * direction is backward we don't shift and it will end up | 694 * direction is backward we don't shift and it will end up |
| 697 * hanging over the next glyph after the final reordering. | 695 * hanging over the next glyph after the final reordering. |
| 698 * If fallback positinoing happens or GPOS is present, we don't | 696 * If fallback positinoing happens or GPOS is present, we don't |
| 699 * care. | 697 * care. |
| 700 */ | 698 */ |
| 701 bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallb
ack_position || | 699 bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallb
ack_position || |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); | 754 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); |
| 757 break; | 755 break; |
| 758 | 756 |
| 759 default: | 757 default: |
| 760 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: | 758 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: |
| 761 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: | 759 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: |
| 762 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: | 760 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: |
| 763 break; | 761 break; |
| 764 } | 762 } |
| 765 | 763 |
| 764 /* Finishing off GPOS has to follow a certain order. */ |
| 765 hb_ot_layout_position_finish_advances (c->font, c->buffer); |
| 766 hb_ot_zero_width_default_ignorables (c); |
| 767 hb_ot_layout_position_finish_offsets (c->font, c->buffer); |
| 768 |
| 766 return ret; | 769 return ret; |
| 767 } | 770 } |
| 768 | 771 |
| 769 static inline void | 772 static inline void |
| 770 hb_ot_position (hb_ot_shape_context_t *c) | 773 hb_ot_position (hb_ot_shape_context_t *c) |
| 771 { | 774 { |
| 772 hb_ot_layout_position_start (c->font, c->buffer); | 775 c->buffer->clear_positions (); |
| 773 | 776 |
| 774 hb_ot_position_default (c); | 777 hb_ot_position_default (c); |
| 775 | 778 |
| 776 hb_bool_t fallback = !hb_ot_position_complex (c); | 779 hb_bool_t fallback = !hb_ot_position_complex (c); |
| 777 | 780 |
| 778 hb_ot_zero_width_default_ignorables (c); | |
| 779 | |
| 780 hb_ot_layout_position_finish (c->font, c->buffer); | |
| 781 | |
| 782 if (fallback && c->plan->shaper->fallback_position) | 781 if (fallback && c->plan->shaper->fallback_position) |
| 783 _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); | 782 _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); |
| 784 | 783 |
| 785 if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) | 784 if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) |
| 786 hb_buffer_reverse (c->buffer); | 785 hb_buffer_reverse (c->buffer); |
| 787 | 786 |
| 788 /* Visual fallback goes here. */ | 787 /* Visual fallback goes here. */ |
| 789 | 788 |
| 790 if (fallback) | 789 if (fallback) |
| 791 _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); | 790 _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 hb_set_t copy; | 921 hb_set_t copy; |
| 923 copy.init (); | 922 copy.init (); |
| 924 do { | 923 do { |
| 925 copy.set (glyphs); | 924 copy.set (glyphs); |
| 926 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) | 925 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) |
| 927 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); | 926 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); |
| 928 } while (!copy.is_equal (glyphs)); | 927 } while (!copy.is_equal (glyphs)); |
| 929 | 928 |
| 930 hb_shape_plan_destroy (shape_plan); | 929 hb_shape_plan_destroy (shape_plan); |
| 931 } | 930 } |
| OLD | NEW |