Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/harfbuzz-ng/src/hb-ot-shape.cc

Issue 2622553002: Roll HarfBuzz to 1.4.1 (Closed)
Patch Set: Linux rebaselines Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 62
63 63
64 static void 64 static void
65 hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, 65 hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
66 const hb_segment_properties_t *props, 66 const hb_segment_properties_t *props,
67 const hb_feature_t *user_features, 67 const hb_feature_t *user_features,
68 unsigned int num_user_features) 68 unsigned int num_user_features)
69 { 69 {
70 hb_ot_map_builder_t *map = &planner->map; 70 hb_ot_map_builder_t *map = &planner->map;
71 71
72 map->add_global_bool_feature (HB_TAG('r','v','r','n'));
73 map->add_gsub_pause (NULL);
74
72 switch (props->direction) { 75 switch (props->direction) {
73 case HB_DIRECTION_LTR: 76 case HB_DIRECTION_LTR:
74 map->add_global_bool_feature (HB_TAG ('l','t','r','a')); 77 map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
75 map->add_global_bool_feature (HB_TAG ('l','t','r','m')); 78 map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
76 break; 79 break;
77 case HB_DIRECTION_RTL: 80 case HB_DIRECTION_RTL:
78 map->add_global_bool_feature (HB_TAG ('r','t','l','a')); 81 map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
79 map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE); 82 map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE);
80 break; 83 break;
81 case HB_DIRECTION_TTB: 84 case HB_DIRECTION_TTB:
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 159 }
157 160
158 161
159 /* 162 /*
160 * shaper shape_plan data 163 * shaper shape_plan data
161 */ 164 */
162 165
163 hb_ot_shaper_shape_plan_data_t * 166 hb_ot_shaper_shape_plan_data_t *
164 _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, 167 _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
165 const hb_feature_t *user_features, 168 const hb_feature_t *user_features,
166 » » » » unsigned int num_user_features) 169 » » » » unsigned int num_user_features,
170 » » » » const int *coords,
171 » » » » unsigned int num_coords)
167 { 172 {
168 hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_sha pe_plan_t)); 173 hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_sha pe_plan_t));
169 if (unlikely (!plan)) 174 if (unlikely (!plan))
170 return NULL; 175 return NULL;
171 176
172 hb_ot_shape_planner_t planner (shape_plan); 177 hb_ot_shape_planner_t planner (shape_plan);
173 178
174 planner.shaper = hb_ot_shape_complex_categorize (&planner); 179 planner.shaper = hb_ot_shape_complex_categorize (&planner);
175 180
176 hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num _user_features); 181 hb_ot_shape_collect_features (&planner, &shape_plan->props,
182 » » » » user_features, num_user_features);
177 183
178 planner.compile (*plan); 184 planner.compile (*plan, coords, num_coords);
179 185
180 if (plan->shaper->data_create) { 186 if (plan->shaper->data_create) {
181 plan->data = plan->shaper->data_create (plan); 187 plan->data = plan->shaper->data_create (plan);
182 if (unlikely (!plan->data)) 188 if (unlikely (!plan->data))
183 return NULL; 189 return NULL;
184 } 190 }
185 191
186 return plan; 192 return plan;
187 } 193 }
188 194
(...skipping 16 matching lines...) Expand all
205 struct hb_ot_shape_context_t 211 struct hb_ot_shape_context_t
206 { 212 {
207 hb_ot_shape_plan_t *plan; 213 hb_ot_shape_plan_t *plan;
208 hb_font_t *font; 214 hb_font_t *font;
209 hb_face_t *face; 215 hb_face_t *face;
210 hb_buffer_t *buffer; 216 hb_buffer_t *buffer;
211 const hb_feature_t *user_features; 217 const hb_feature_t *user_features;
212 unsigned int num_user_features; 218 unsigned int num_user_features;
213 219
214 /* Transient stuff */ 220 /* Transient stuff */
221 bool fallback_positioning;
222 bool fallback_glyph_classes;
215 hb_direction_t target_direction; 223 hb_direction_t target_direction;
216 }; 224 };
217 225
218 226
219 227
220 /* Main shaper */ 228 /* Main shaper */
221 229
222 230
223 /* Prepare */ 231 /* Prepare */
224 232
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 /* Normalization process sets up glyph_index(), we just copy it. */ 525 /* Normalization process sets up glyph_index(), we just copy it. */
518 unsigned int count = buffer->len; 526 unsigned int count = buffer->len;
519 hb_glyph_info_t *info = buffer->info; 527 hb_glyph_info_t *info = buffer->info;
520 for (unsigned int i = 0; i < count; i++) 528 for (unsigned int i = 0; i < count; i++)
521 info[i].codepoint = info[i].glyph_index(); 529 info[i].codepoint = info[i].glyph_index();
522 530
523 buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; 531 buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
524 } 532 }
525 533
526 static inline void 534 static inline void
535 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
536 {
537 unsigned int count = c->buffer->len;
538 hb_glyph_info_t *info = c->buffer->info;
539 for (unsigned int i = 0; i < count; i++)
540 {
541 hb_ot_layout_glyph_props_flags_t klass;
542
543 /* Never mark default-ignorables as marks.
544 * They won't get in the way of lookups anyway,
545 * but having them as mark will cause them to be skipped
546 * over if the lookup-flag says so, but at least for the
547 * Mongolian variation selectors, looks like Uniscribe
548 * marks them as non-mark. Some Mongolian fonts without
549 * GDEF rely on this. Another notable character that
550 * this applies to is COMBINING GRAPHEME JOINER. */
551 klass = (_hb_glyph_info_get_general_category (&info[i]) !=
552 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ||
553 _hb_glyph_info_is_default_ignorable (&info[i])) ?
554 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH :
555 HB_OT_LAYOUT_GLYPH_PROPS_MARK;
556 _hb_glyph_info_set_glyph_props (&info[i], klass);
557 }
558 }
559
560 static inline void
527 hb_ot_substitute_default (hb_ot_shape_context_t *c) 561 hb_ot_substitute_default (hb_ot_shape_context_t *c)
528 { 562 {
529 hb_buffer_t *buffer = c->buffer; 563 hb_buffer_t *buffer = c->buffer;
530 564
531 hb_ot_shape_initialize_masks (c); 565 hb_ot_shape_initialize_masks (c);
532 566
533 hb_ot_mirror_chars (c); 567 hb_ot_mirror_chars (c);
534 568
535 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); 569 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
536 570
537 _hb_ot_shape_normalize (c->plan, buffer, c->font); 571 _hb_ot_shape_normalize (c->plan, buffer, c->font);
538 572
539 hb_ot_shape_setup_masks (c); 573 hb_ot_shape_setup_masks (c);
540 574
541 /* This is unfortunate to go here, but necessary... */ 575 /* This is unfortunate to go here, but necessary... */
542 if (!hb_ot_layout_has_positioning (c->face)) 576 if (c->fallback_positioning)
543 _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer) ; 577 _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer) ;
544 578
545 hb_ot_map_glyphs_fast (buffer); 579 hb_ot_map_glyphs_fast (buffer);
546 580
547 HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); 581 HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index);
548 } 582 }
549 583
550 static inline void 584 static inline void
551 hb_ot_substitute_complex (hb_ot_shape_context_t *c) 585 hb_ot_substitute_complex (hb_ot_shape_context_t *c)
552 { 586 {
553 hb_buffer_t *buffer = c->buffer; 587 hb_buffer_t *buffer = c->buffer;
554 588
555 hb_ot_layout_substitute_start (c->font, buffer); 589 hb_ot_layout_substitute_start (c->font, buffer);
556 590
591 if (!hb_ot_layout_has_glyph_classes (c->face))
592 hb_synthesize_glyph_classes (c);
593
557 c->plan->substitute (c->font, buffer); 594 c->plan->substitute (c->font, buffer);
558 595
559 return; 596 return;
560 } 597 }
561 598
562 static inline void 599 static inline void
563 hb_ot_substitute (hb_ot_shape_context_t *c) 600 hb_ot_substitute (hb_ot_shape_context_t *c)
564 { 601 {
565 hb_ot_substitute_default (c); 602 hb_ot_substitute_default (c);
566 603
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 pos[i].y_advance = c->font->get_glyph_v_advance (info[i].codepoint); 662 pos[i].y_advance = c->font->get_glyph_v_advance (info[i].codepoint);
626 c->font->subtract_glyph_v_origin (info[i].codepoint, 663 c->font->subtract_glyph_v_origin (info[i].codepoint,
627 &pos[i].x_offset, 664 &pos[i].x_offset,
628 &pos[i].y_offset); 665 &pos[i].y_offset);
629 } 666 }
630 } 667 }
631 if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) 668 if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK)
632 _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); 669 _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer);
633 } 670 }
634 671
635 static inline bool 672 static inline void
636 hb_ot_position_complex (hb_ot_shape_context_t *c) 673 hb_ot_position_complex (hb_ot_shape_context_t *c)
637 { 674 {
638 hb_ot_layout_position_start (c->font, c->buffer); 675 hb_ot_layout_position_start (c->font, c->buffer);
639 676
640 bool ret = false;
641 unsigned int count = c->buffer->len; 677 unsigned int count = c->buffer->len;
642 bool has_positioning = (bool) hb_ot_layout_has_positioning (c->face);
643 678
644 /* If the font has no GPOS, AND, no fallback positioning will 679 /* If the font has no GPOS, AND, no fallback positioning will
645 * happen, AND, direction is forward, then when zeroing mark 680 * happen, AND, direction is forward, then when zeroing mark
646 * widths, we shift the mark with it, such that the mark 681 * widths, we shift the mark with it, such that the mark
647 * is positioned hanging over the previous glyph. When 682 * is positioned hanging over the previous glyph. When
648 * direction is backward we don't shift and it will end up 683 * direction is backward we don't shift and it will end up
649 * hanging over the next glyph after the final reordering. 684 * hanging over the next glyph after the final reordering.
650 * If fallback positinoing happens or GPOS is present, we don't 685 * If fallback positinoing happens or GPOS is present, we don't
651 * care. 686 * care.
652 */ 687 */
653 bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallb ack_position || 688 bool adjust_offsets_when_zeroing = c->fallback_positioning &&
654 HB_DIRECTION_IS_BACKWARD (c->buffer->prop s.direction)); 689 » » » » !c->plan->shaper->fallback_position &&
690 » » » » HB_DIRECTION_IS_FORWARD (c->buffer->props.d irection);
655 691
656 switch (c->plan->shaper->zero_width_marks) 692 switch (c->plan->shaper->zero_width_marks)
657 { 693 {
658 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: 694 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
659 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); 695 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
660 break; 696 break;
661 697
662 default: 698 default:
663 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: 699 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
664 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: 700 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
665 break; 701 break;
666 } 702 }
667 703
668 if (has_positioning) 704 if (likely (!c->fallback_positioning))
669 { 705 {
670 hb_glyph_info_t *info = c->buffer->info; 706 hb_glyph_info_t *info = c->buffer->info;
671 hb_glyph_position_t *pos = c->buffer->pos; 707 hb_glyph_position_t *pos = c->buffer->pos;
672 708
673 /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */ 709 /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
674 710
675 /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ 711 /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
676 if (c->font->has_glyph_h_origin_func ()) 712 if (c->font->has_glyph_h_origin_func ())
677 for (unsigned int i = 0; i < count; i++) 713 for (unsigned int i = 0; i < count; i++)
678 c->font->add_glyph_h_origin (info[i].codepoint, 714 c->font->add_glyph_h_origin (info[i].codepoint,
679 &pos[i].x_offset, 715 &pos[i].x_offset,
680 &pos[i].y_offset); 716 &pos[i].y_offset);
681 717
682 c->plan->position (c->font, c->buffer); 718 c->plan->position (c->font, c->buffer);
683 719
684 /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ 720 /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
685 if (c->font->has_glyph_h_origin_func ()) 721 if (c->font->has_glyph_h_origin_func ())
686 for (unsigned int i = 0; i < count; i++) 722 for (unsigned int i = 0; i < count; i++)
687 c->font->subtract_glyph_h_origin (info[i].codepoint, 723 c->font->subtract_glyph_h_origin (info[i].codepoint,
688 &pos[i].x_offset, 724 &pos[i].x_offset,
689 &pos[i].y_offset); 725 &pos[i].y_offset);
690 726
691 ret = true;
692 } 727 }
693 728
694 switch (c->plan->shaper->zero_width_marks) 729 switch (c->plan->shaper->zero_width_marks)
695 { 730 {
696 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: 731 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
697 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); 732 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
698 break; 733 break;
699 734
700 default: 735 default:
701 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: 736 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
702 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: 737 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
703 break; 738 break;
704 } 739 }
705 740
706 /* Finishing off GPOS has to follow a certain order. */ 741 /* Finishing off GPOS has to follow a certain order. */
707 hb_ot_layout_position_finish_advances (c->font, c->buffer); 742 hb_ot_layout_position_finish_advances (c->font, c->buffer);
708 hb_ot_zero_width_default_ignorables (c); 743 hb_ot_zero_width_default_ignorables (c);
709 hb_ot_layout_position_finish_offsets (c->font, c->buffer); 744 hb_ot_layout_position_finish_offsets (c->font, c->buffer);
710
711 return ret;
712 } 745 }
713 746
714 static inline void 747 static inline void
715 hb_ot_position (hb_ot_shape_context_t *c) 748 hb_ot_position (hb_ot_shape_context_t *c)
716 { 749 {
717 c->buffer->clear_positions (); 750 c->buffer->clear_positions ();
718 751
719 hb_ot_position_default (c); 752 hb_ot_position_default (c);
720 753
721 hb_bool_t fallback = !hb_ot_position_complex (c); 754 hb_ot_position_complex (c);
722 755
723 if (fallback && c->plan->shaper->fallback_position) 756 if (c->fallback_positioning && c->plan->shaper->fallback_position)
724 _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); 757 _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
725 758
726 if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) 759 if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
727 hb_buffer_reverse (c->buffer); 760 hb_buffer_reverse (c->buffer);
728 761
729 /* Visual fallback goes here. */ 762 /* Visual fallback goes here. */
730 763
731 if (fallback) 764 if (c->fallback_positioning)
732 _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); 765 _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
733 766
734 _hb_buffer_deallocate_gsubgpos_vars (c->buffer); 767 _hb_buffer_deallocate_gsubgpos_vars (c->buffer);
735 } 768 }
736 769
737 770
738 /* Pull it all together! */ 771 /* Pull it all together! */
739 772
740 static void 773 static void
741 hb_ot_shape_internal (hb_ot_shape_context_t *c) 774 hb_ot_shape_internal (hb_ot_shape_context_t *c)
742 { 775 {
743 c->buffer->deallocate_var_all (); 776 c->buffer->deallocate_var_all ();
744 c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; 777 c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
745 if (likely (!_hb_unsigned_int_mul_overflows (c->buffer->len, HB_BUFFER_MAX_EXP ANSION_FACTOR))) 778 if (likely (!_hb_unsigned_int_mul_overflows (c->buffer->len, HB_BUFFER_MAX_EXP ANSION_FACTOR)))
746 { 779 {
747 c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_EXPANSION_FACTOR, 780 c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_EXPANSION_FACTOR,
748 (unsigned) HB_BUFFER_MAX_LEN_MIN); 781 (unsigned) HB_BUFFER_MAX_LEN_MIN);
749 } 782 }
750 783
784 bool disable_otl = c->plan->shaper->disable_otl && c->plan->shaper->disable_ot l (c->plan);
785 //c->fallback_substitute = disable_otl || !hb_ot_layout_has_substitution ( c->face);
786 c->fallback_positioning = disable_otl || !hb_ot_layout_has_positioning (c-> face);
787 c->fallback_glyph_classes = disable_otl || !hb_ot_layout_has_glyph_classes (c ->face);
788
751 /* Save the original direction, we use it later. */ 789 /* Save the original direction, we use it later. */
752 c->target_direction = c->buffer->props.direction; 790 c->target_direction = c->buffer->props.direction;
753 791
754 _hb_buffer_allocate_unicode_vars (c->buffer); 792 _hb_buffer_allocate_unicode_vars (c->buffer);
755 793
756 c->buffer->clear_output (); 794 c->buffer->clear_output ();
757 795
758 hb_set_unicode_props (c->buffer); 796 hb_set_unicode_props (c->buffer);
759 hb_insert_dotted_circle (c->buffer, c->font); 797 hb_insert_dotted_circle (c->buffer, c->font);
760 hb_form_clusters (c->buffer); 798 hb_form_clusters (c->buffer);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 hb_set_t copy; 901 hb_set_t copy;
864 copy.init (); 902 copy.init ();
865 do { 903 do {
866 copy.set (glyphs); 904 copy.set (glyphs);
867 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index) ;) 905 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index) ;)
868 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); 906 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
869 } while (!copy.is_equal (glyphs)); 907 } while (!copy.is_equal (glyphs));
870 908
871 hb_shape_plan_destroy (shape_plan); 909 hb_shape_plan_destroy (shape_plan);
872 } 910 }
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-math.cc ('k') | third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698