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 |