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

Side by Side Diff: third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh

Issue 70193010: Update harfbuzz-ng to 0.9.24 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
3 * Copyright © 2010,2012 Google, Inc. 3 * Copyright © 2010,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 25 matching lines...) Expand all
36 36
37 namespace OT { 37 namespace OT {
38 38
39 39
40 40
41 #define TRACE_DISPATCH(this) \ 41 #define TRACE_DISPATCH(this) \
42 hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t > trace \ 42 hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t > trace \
43 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 43 (&c->debug_depth, c->get_name (), this, HB_FUNC, \
44 ""); 44 "");
45 45
46
47 #ifndef HB_DEBUG_CLOSURE 46 #ifndef HB_DEBUG_CLOSURE
48 #define HB_DEBUG_CLOSURE (HB_DEBUG+0) 47 #define HB_DEBUG_CLOSURE (HB_DEBUG+0)
49 #endif 48 #endif
50 49
51 #define TRACE_CLOSURE(this) \ 50 #define TRACE_CLOSURE(this) \
52 hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \ 51 hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \
53 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 52 (&c->debug_depth, c->get_name (), this, HB_FUNC, \
54 ""); 53 "");
55 54
56 struct hb_closure_context_t 55 struct hb_closure_context_t
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB _VOID; } 150 inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB _VOID; }
152 static return_t default_return_value (void) { return HB_VOID; } 151 static return_t default_return_value (void) { return HB_VOID; }
153 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } 152 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
154 return_t recurse (unsigned int lookup_index) 153 return_t recurse (unsigned int lookup_index)
155 { 154 {
156 if (unlikely (nesting_level_left == 0 || !recurse_func)) 155 if (unlikely (nesting_level_left == 0 || !recurse_func))
157 return default_return_value (); 156 return default_return_value ();
158 157
159 /* Note that GPOS sets recurse_func to NULL already, so it doesn't get 158 /* Note that GPOS sets recurse_func to NULL already, so it doesn't get
160 * past the previous check. For GSUB, we only want to collect the output 159 * past the previous check. For GSUB, we only want to collect the output
161 * glyphs in the recursion. If output is not requested, we can go home now. */ 160 * glyphs in the recursion. If output is not requested, we can go home now.
161 *
162 * Note further, that the above is not exactly correct. A recursed lookup
163 * is allowed to match input that is not matched in the context, but that's
164 * not how most fonts are built. It's possible to relax that and recurse
165 * with all sets here if it proves to be an issue.
166 */
162 167
163 if (output == hb_set_get_empty ()) 168 if (output == hb_set_get_empty ())
164 return HB_VOID; 169 return HB_VOID;
165 170
166 hb_set_t *old_before = before; 171 hb_set_t *old_before = before;
167 hb_set_t *old_input = input; 172 hb_set_t *old_input = input;
168 hb_set_t *old_after = after; 173 hb_set_t *old_after = after;
169 before = input = after = hb_set_get_empty (); 174 before = input = after = hb_set_get_empty ();
170 175
171 nesting_level_left--; 176 nesting_level_left--;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 recurse_func_t recurse_func; 270 recurse_func_t recurse_func;
266 unsigned int nesting_level_left; 271 unsigned int nesting_level_left;
267 unsigned int lookup_props; 272 unsigned int lookup_props;
268 const GDEF &gdef; 273 const GDEF &gdef;
269 bool has_glyph_classes; 274 bool has_glyph_classes;
270 unsigned int debug_depth; 275 unsigned int debug_depth;
271 276
272 277
273 hb_apply_context_t (unsigned int table_index_, 278 hb_apply_context_t (unsigned int table_index_,
274 hb_font_t *font_, 279 hb_font_t *font_,
275 » » hb_buffer_t *buffer_, 280 » » hb_buffer_t *buffer_) :
276 » » hb_mask_t lookup_mask_,
277 » » bool auto_zwj_) :
278 table_index (table_index_), 281 table_index (table_index_),
279 font (font_), face (font->face), buffer (buffer_), 282 font (font_), face (font->face), buffer (buffer_),
280 direction (buffer_->props.direction), 283 direction (buffer_->props.direction),
281 » » » lookup_mask (lookup_mask_), 284 » » » lookup_mask (1),
282 » » » auto_zwj (auto_zwj_), 285 » » » auto_zwj (true),
283 recurse_func (NULL), 286 recurse_func (NULL),
284 nesting_level_left (MAX_NESTING_LEVEL), 287 nesting_level_left (MAX_NESTING_LEVEL),
285 lookup_props (0), 288 lookup_props (0),
286 gdef (*hb_ot_layout_from_face (face)->gdef), 289 gdef (*hb_ot_layout_from_face (face)->gdef),
287 has_glyph_classes (gdef.has_glyph_classes ()), 290 has_glyph_classes (gdef.has_glyph_classes ()),
288 debug_depth (0) {} 291 debug_depth (0) {}
289 292
293 inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
294 inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; }
290 inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } 295 inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
291 inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = loo kup_props_; } 296 inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = loo kup_props_; }
292 inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } 297 inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); }
293 298
294 struct matcher_t 299 struct matcher_t
295 { 300 {
296 inline matcher_t (void) : 301 inline matcher_t (void) :
297 lookup_props (0), 302 lookup_props (0),
298 ignore_zwnj (false), 303 ignore_zwnj (false),
299 ignore_zwj (false), 304 ignore_zwj (false),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 SKIP_YES, 344 SKIP_YES,
340 SKIP_MAYBE 345 SKIP_MAYBE
341 }; 346 };
342 347
343 inline may_skip_t 348 inline may_skip_t
344 may_skip (const hb_apply_context_t *c, 349 may_skip (const hb_apply_context_t *c,
345 const hb_glyph_info_t &info) const 350 const hb_glyph_info_t &info) const
346 { 351 {
347 unsigned int property; 352 unsigned int property;
348 353
349 property = info.glyph_props(); 354 property = _hb_glyph_info_get_glyph_props (&info);
350 355
351 if (!c->match_properties (info.codepoint, property, lookup_props)) 356 if (!c->match_properties (info.codepoint, property, lookup_props))
352 return SKIP_YES; 357 return SKIP_YES;
353 358
354 if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && 359 if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
355 (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && 360 (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
356 (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && 361 (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
357 » » !is_a_ligature (info))) 362 » » !_hb_glyph_info_ligated (&info)))
358 return SKIP_MAYBE; 363 return SKIP_MAYBE;
359 364
360 return SKIP_NO; 365 return SKIP_NO;
361 } 366 }
362 367
363 protected: 368 protected:
364 unsigned int lookup_props; 369 unsigned int lookup_props;
365 bool ignore_zwnj; 370 bool ignore_zwnj;
366 bool ignore_zwj; 371 bool ignore_zwj;
367 hb_mask_t mask; 372 hb_mask_t mask;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 553
549 return true; 554 return true;
550 } 555 }
551 556
552 inline bool 557 inline bool
553 check_glyph_property (hb_glyph_info_t *info, 558 check_glyph_property (hb_glyph_info_t *info,
554 unsigned int lookup_props) const 559 unsigned int lookup_props) const
555 { 560 {
556 unsigned int property; 561 unsigned int property;
557 562
558 property = info->glyph_props(); 563 property = _hb_glyph_info_get_glyph_props (info);
559 564
560 return match_properties (info->codepoint, property, lookup_props); 565 return match_properties (info->codepoint, property, lookup_props);
561 } 566 }
562 567
563 inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) c onst 568 inline void _set_glyph_props (hb_codepoint_t glyph_index,
569 » » » unsigned int class_guess = 0,
570 » » » bool ligature = false) const
564 { 571 {
572 unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
573 HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
574 add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
575 if (ligature)
576 add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
565 if (likely (has_glyph_classes)) 577 if (likely (has_glyph_classes))
566 buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index); 578 _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_pr ops (glyph_index));
567 else if (class_guess) 579 else if (class_guess)
568 buffer->cur().glyph_props() = class_guess; 580 _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
569 } 581 }
570 582
571 inline void output_glyph (hb_codepoint_t glyph_index, 583 inline void replace_glyph (hb_codepoint_t glyph_index) const
572 » » » unsigned int class_guess = 0) const
573 { 584 {
574 set_class (glyph_index, class_guess); 585 _set_glyph_props (glyph_index);
575 buffer->output_glyph (glyph_index);
576 }
577 inline void replace_glyph (hb_codepoint_t glyph_index,
578 » » » unsigned int class_guess = 0) const
579 {
580 set_class (glyph_index, class_guess);
581 buffer->replace_glyph (glyph_index); 586 buffer->replace_glyph (glyph_index);
582 } 587 }
583 inline void replace_glyph_inplace (hb_codepoint_t glyph_index, 588 inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const
584 » » » » unsigned int class_guess = 0) const
585 { 589 {
586 set_class (glyph_index, class_guess); 590 _set_glyph_props (glyph_index);
587 buffer->cur().codepoint = glyph_index; 591 buffer->cur().codepoint = glyph_index;
588 } 592 }
593 inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
594 unsigned int class_guess) const
595 {
596 _set_glyph_props (glyph_index, class_guess, true);
597 buffer->replace_glyph (glyph_index);
598 }
599 inline void output_glyph (hb_codepoint_t glyph_index,
600 unsigned int class_guess) const
601 {
602 _set_glyph_props (glyph_index, class_guess);
603 buffer->output_glyph (glyph_index);
604 }
589 }; 605 };
590 606
591 607
592 608
593 typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); 609 typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data);
594 typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const USHORT &value, co nst void *data); 610 typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const USHORT &value, co nst void *data);
595 typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, cons t void *data); 611 typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, cons t void *data);
596 612
597 struct ContextClosureFuncs 613 struct ContextClosureFuncs
598 { 614 {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 if (likely (!match_func (c->glyphs[i], input[i - 1], match_data))) 706 if (likely (!match_func (c->glyphs[i], input[i - 1], match_data)))
691 return false; 707 return false;
692 708
693 return true; 709 return true;
694 } 710 }
695 static inline bool match_input (hb_apply_context_t *c, 711 static inline bool match_input (hb_apply_context_t *c,
696 unsigned int count, /* Including the first glyph (not matched) */ 712 unsigned int count, /* Including the first glyph (not matched) */
697 const USHORT input[], /* Array of input values-- start with second glyph */ 713 const USHORT input[], /* Array of input values-- start with second glyph */
698 match_func_t match_func, 714 match_func_t match_func,
699 const void *match_data, 715 const void *match_data,
700 » » » » unsigned int *end_offset = NULL, 716 » » » » unsigned int *end_offset,
717 » » » » unsigned int match_positions[MAX_CONTEXT_LENGTH] ,
701 bool *p_is_mark_ligature = NULL, 718 bool *p_is_mark_ligature = NULL,
702 unsigned int *p_total_component_count = NULL) 719 unsigned int *p_total_component_count = NULL)
703 { 720 {
704 TRACE_APPLY (NULL); 721 TRACE_APPLY (NULL);
705 722
706 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx , count - 1); 723 if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false);
724
725 hb_buffer_t *buffer = c->buffer;
726
727 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, c ount - 1);
707 skippy_iter.set_match_func (match_func, match_data, input); 728 skippy_iter.set_match_func (match_func, match_data, input);
708 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 729 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
709 730
710 /* 731 /*
711 * This is perhaps the trickiest part of OpenType... Remarks: 732 * This is perhaps the trickiest part of OpenType... Remarks:
712 * 733 *
713 * - If all components of the ligature were marks, we call this a mark ligatur e. 734 * - If all components of the ligature were marks, we call this a mark ligatur e.
714 * 735 *
715 * - If there is no GDEF, and the ligature is NOT a mark ligature, we categori ze 736 * - If there is no GDEF, and the ligature is NOT a mark ligature, we categori ze
716 * it as a ligature glyph. 737 * it as a ligature glyph.
717 * 738 *
718 * - Ligatures cannot be formed across glyphs attached to different components 739 * - Ligatures cannot be formed across glyphs attached to different components
719 * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and 740 * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and
720 * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother. 741 * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother.
721 * However, it would be wrong to ligate that SHADDA,FATHA sequence.o 742 * However, it would be wrong to ligate that SHADDA,FATHA sequence.o
722 * There is an exception to this: If a ligature tries ligating with marks th at 743 * There is an exception to this: If a ligature tries ligating with marks th at
723 * belong to it itself, go ahead, assuming that the font designer knows what 744 * belong to it itself, go ahead, assuming that the font designer knows what
724 * they are doing (otherwise it can break Indic stuff when a matra wants to 745 * they are doing (otherwise it can break Indic stuff when a matra wants to
725 * ligate with a conjunct...) 746 * ligate with a conjunct...)
726 */ 747 */
727 748
728 bool is_mark_ligature = !!(c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH _PROPS_MARK); 749 bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
729 750
730 unsigned int total_component_count = 0; 751 unsigned int total_component_count = 0;
731 total_component_count += get_lig_num_comps (c->buffer->cur()); 752 total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
732 753
733 unsigned int first_lig_id = get_lig_id (c->buffer->cur()); 754 unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
734 unsigned int first_lig_comp = get_lig_comp (c->buffer->cur()); 755 unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
735 756
757 match_positions[0] = buffer->idx;
736 for (unsigned int i = 1; i < count; i++) 758 for (unsigned int i = 1; i < count; i++)
737 { 759 {
738 if (!skippy_iter.next ()) return TRACE_RETURN (false); 760 if (!skippy_iter.next ()) return TRACE_RETURN (false);
739 761
740 unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]); 762 match_positions[i] = skippy_iter.idx;
741 unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]) ; 763
764 unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_i ter.idx]);
765 unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skip py_iter.idx]);
742 766
743 if (first_lig_id && first_lig_comp) { 767 if (first_lig_id && first_lig_comp) {
744 /* If first component was attached to a previous ligature component, 768 /* If first component was attached to a previous ligature component,
745 * all subsequent components should be attached to the same ligature 769 * all subsequent components should be attached to the same ligature
746 * component, otherwise we shouldn't ligate them. */ 770 * component, otherwise we shouldn't ligate them. */
747 if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) 771 if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
748 return TRACE_RETURN (false); 772 return TRACE_RETURN (false);
749 } else { 773 } else {
750 /* If first component was NOT attached to a previous ligature component, 774 /* If first component was NOT attached to a previous ligature component,
751 * all subsequent components should also NOT be attached to any ligature 775 * all subsequent components should also NOT be attached to any ligature
752 * component, unless they are attached to the first component itself! */ 776 * component, unless they are attached to the first component itself! */
753 if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id)) 777 if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id))
754 return TRACE_RETURN (false); 778 return TRACE_RETURN (false);
755 } 779 }
756 780
757 is_mark_ligature = is_mark_ligature && (c->buffer->info[skippy_iter.idx].gly ph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK); 781 is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info [skippy_iter.idx]);
758 total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx] ); 782 total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[ski ppy_iter.idx]);
759 } 783 }
760 784
761 if (end_offset) 785 *end_offset = skippy_iter.idx - buffer->idx + 1;
762 *end_offset = skippy_iter.idx - c->buffer->idx + 1;
763 786
764 if (p_is_mark_ligature) 787 if (p_is_mark_ligature)
765 *p_is_mark_ligature = is_mark_ligature; 788 *p_is_mark_ligature = is_mark_ligature;
766 789
767 if (p_total_component_count) 790 if (p_total_component_count)
768 *p_total_component_count = total_component_count; 791 *p_total_component_count = total_component_count;
769 792
770 return TRACE_RETURN (true); 793 return TRACE_RETURN (true);
771 } 794 }
772 static inline void ligate_input (hb_apply_context_t *c, 795 static inline void ligate_input (hb_apply_context_t *c,
773 » » » » unsigned int count, /* Including the first glyp h (not matched) */ 796 » » » » unsigned int count, /* Including the first glyp h */
774 » » » » const USHORT input[], /* Array of input values- -start with second glyph */ 797 » » » » unsigned int match_positions[MAX_CONTEXT_LENGTH ], /* Including the first glyph */
775 » » » » match_func_t match_func, 798 » » » » unsigned int match_length,
776 » » » » const void *match_data,
777 hb_codepoint_t lig_glyph, 799 hb_codepoint_t lig_glyph,
778 bool is_mark_ligature, 800 bool is_mark_ligature,
779 unsigned int total_component_count) 801 unsigned int total_component_count)
780 { 802 {
781 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx , count - 1); 803 TRACE_APPLY (NULL);
782 skippy_iter.set_match_func (match_func, match_data, input); 804
783 if (skippy_iter.has_no_chance ()) return; 805 hb_buffer_t *buffer = c->buffer;
806
807 buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
784 808
785 /* 809 /*
786 * - If it *is* a mark ligature, we don't allocate a new ligature id, and leav e 810 * - If it *is* a mark ligature, we don't allocate a new ligature id, and leav e
787 * the ligature to keep its old ligature id. This will allow it to attach t o 811 * the ligature to keep its old ligature id. This will allow it to attach t o
788 * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HE H, 812 * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HE H,
789 * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a 813 * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a
790 * ligature id and component value of 2. Then if SHADDA,FATHA form a ligatu re 814 * ligature id and component value of 2. Then if SHADDA,FATHA form a ligatu re
791 * later, we don't want them to lose their ligature id/component, otherwise 815 * later, we don't want them to lose their ligature id/component, otherwise
792 * GPOS will fail to correctly position the mark ligature on top of the 816 * GPOS will fail to correctly position the mark ligature on top of the
793 * LAM,LAM,HEH ligature. See: 817 * LAM,LAM,HEH ligature. See:
(...skipping 10 matching lines...) Expand all
804 * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature 828 * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature
805 * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligat ure 829 * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligat ure
806 * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to 830 * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to
807 * the new ligature with a component value of 2. 831 * the new ligature with a component value of 2.
808 * 832 *
809 * This in fact happened to a font... See: 833 * This in fact happened to a font... See:
810 * https://bugzilla.gnome.org/show_bug.cgi?id=437633 834 * https://bugzilla.gnome.org/show_bug.cgi?id=437633
811 */ 835 */
812 836
813 unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE; 837 unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
814 unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (c->buffer); 838 unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer);
815 unsigned int last_lig_id = get_lig_id (c->buffer->cur()); 839 unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
816 unsigned int last_num_components = get_lig_num_comps (c->buffer->cur()); 840 unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer-> cur());
817 unsigned int components_so_far = last_num_components; 841 unsigned int components_so_far = last_num_components;
818 842
819 if (!is_mark_ligature) 843 if (!is_mark_ligature)
820 set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count) ; 844 {
821 c->replace_glyph (lig_glyph, klass); 845 _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_com ponent_count);
846 if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENER AL_CATEGORY_NON_SPACING_MARK)
847 {
848 _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CA TEGORY_OTHER_LETTER);
849 _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0);
850 }
851 }
852 c->replace_glyph_with_ligature (lig_glyph, klass);
822 853
823 for (unsigned int i = 1; i < count; i++) 854 for (unsigned int i = 1; i < count; i++)
824 { 855 {
825 if (!skippy_iter.next ()) return; 856 while (buffer->idx < match_positions[i])
826
827 while (c->buffer->idx < skippy_iter.idx)
828 { 857 {
829 if (!is_mark_ligature) { 858 if (!is_mark_ligature) {
830 unsigned int new_lig_comp = components_so_far - last_num_components + 859 unsigned int new_lig_comp = components_so_far - last_num_components +
831 » » » » MIN (MAX (get_lig_comp (c->buffer->cur()), 1 u), last_num_components); 860 » » » » MIN (MAX (_hb_glyph_info_get_lig_comp (&buff er->cur()), 1u), last_num_components);
832 » set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp); 861 » _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_c omp);
833 } 862 }
834 c->buffer->next_glyph (); 863 buffer->next_glyph ();
835 } 864 }
836 865
837 last_lig_id = get_lig_id (c->buffer->cur()); 866 last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
838 last_num_components = get_lig_num_comps (c->buffer->cur()); 867 last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
839 components_so_far += last_num_components; 868 components_so_far += last_num_components;
840 869
841 /* Skip the base glyph */ 870 /* Skip the base glyph */
842 c->buffer->idx++; 871 buffer->idx++;
843 } 872 }
844 873
845 if (!is_mark_ligature && last_lig_id) { 874 if (!is_mark_ligature && last_lig_id) {
846 /* Re-adjust components for any marks following. */ 875 /* Re-adjust components for any marks following. */
847 for (unsigned int i = c->buffer->idx; i < c->buffer->len; i++) { 876 for (unsigned int i = buffer->idx; i < buffer->len; i++) {
848 if (last_lig_id == get_lig_id (c->buffer->info[i])) { 877 if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
849 unsigned int new_lig_comp = components_so_far - last_num_components + 878 unsigned int new_lig_comp = components_so_far - last_num_components +
850 » » » » MIN (MAX (get_lig_comp (c->buffer->info[i]), 1u), last_num_components); 879 » » » » MIN (MAX (_hb_glyph_info_get_lig_comp (&buff er->info[i]), 1u), last_num_components);
851 » set_lig_props_for_mark (c->buffer->info[i], lig_id, new_lig_comp); 880 » _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig _comp);
852 } else 881 } else
853 break; 882 break;
854 } 883 }
855 } 884 }
856 } 885 }
857 886
858 static inline bool match_backtrack (hb_apply_context_t *c, 887 static inline bool match_backtrack (hb_apply_context_t *c,
859 unsigned int count, 888 unsigned int count,
860 const USHORT backtrack[], 889 const USHORT backtrack[],
861 match_func_t match_func, 890 match_func_t match_func,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 DEFINE_SIZE_STATIC (4); 940 DEFINE_SIZE_STATIC (4);
912 }; 941 };
913 942
914 943
915 template <typename context_t> 944 template <typename context_t>
916 static inline void recurse_lookups (context_t *c, 945 static inline void recurse_lookups (context_t *c,
917 unsigned int lookupCount, 946 unsigned int lookupCount,
918 const LookupRecord lookupRecord[] /* Array o f LookupRecords--in design order */) 947 const LookupRecord lookupRecord[] /* Array o f LookupRecords--in design order */)
919 { 948 {
920 for (unsigned int i = 0; i < lookupCount; i++) 949 for (unsigned int i = 0; i < lookupCount; i++)
921 c->recurse (lookupRecord->lookupListIndex); 950 c->recurse (lookupRecord[i].lookupListIndex);
922 } 951 }
923 952
924 static inline bool apply_lookup (hb_apply_context_t *c, 953 static inline bool apply_lookup (hb_apply_context_t *c,
925 unsigned int count, /* Including the first glyp h */ 954 unsigned int count, /* Including the first glyp h */
926 » » » » const USHORT input[], /* Array of input values- -start with second glyph */ 955 » » » » unsigned int match_positions[MAX_CONTEXT_LENGTH ], /* Including the first glyph */
927 » » » » match_func_t match_func,
928 » » » » const void *match_data,
929 unsigned int lookupCount, 956 unsigned int lookupCount,
930 » » » » const LookupRecord lookupRecord[] /* Array of L ookupRecords--in design order */) 957 » » » » const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
958 » » » » unsigned int match_length)
931 { 959 {
932 TRACE_APPLY (NULL); 960 TRACE_APPLY (NULL);
933 961
934 unsigned int end = c->buffer->len; 962 hb_buffer_t *buffer = c->buffer;
935 if (unlikely (count == 0 || c->buffer->idx + count > end)) 963 unsigned int end;
936 return TRACE_RETURN (false);
937 964
938 /* TODO We don't support lookupRecord arrays that are not increasing: 965 /* All positions are distance from beginning of *output* buffer.
939 * Should be easy for in_place ones at least. */ 966 * Adjust. */
967 {
968 unsigned int bl = buffer->backtrack_len ();
969 end = bl + match_length;
940 970
941 /* Note: If sublookup is reverse, it will underflow after the first loop 971 int delta = bl - buffer->idx;
942 * and we jump out of it. Not entirely disastrous. So we don't check 972 /* Convert positions to new indexing. */
943 * for reverse lookup here. 973 for (unsigned int j = 0; j < count; j++)
944 */ 974 match_positions[j] += delta;
975 }
945 976
946 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx , count - 1); 977 for (unsigned int i = 0; i < lookupCount; i++)
947 skippy_iter.set_match_func (match_func, match_data, input); 978 {
948 uint8_t syllable = c->buffer->cur().syllable(); 979 unsigned int idx = lookupRecord[i].sequenceIndex;
980 if (idx >= count)
981 continue;
949 982
950 unsigned int i = 0; 983 buffer->move_to (match_positions[idx]);
951 if (lookupCount && 0 == lookupRecord->sequenceIndex)
952 {
953 unsigned int old_pos = c->buffer->idx;
954 984
955 /* Apply a lookup */ 985 unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
956 bool done = c->recurse (lookupRecord->lookupListIndex); 986 if (!c->recurse (lookupRecord[i].lookupListIndex))
987 continue;
957 988
958 lookupRecord++; 989 unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len ();
959 lookupCount--; 990 int delta = new_len - orig_len;
960 /* Err, this is wrong if the lookup jumped over some glyphs */
961 i += c->buffer->idx - old_pos;
962 991
963 if (!done) 992 if (!delta)
964 goto not_applied; 993 continue;
965 else 994
995 /* Recursed lookup changed buffer len. Adjust. */
996
997 /* end can't go back past the current match position. */
998 end = MAX ((int) match_positions[idx] + 1, int (end) + delta);
999
1000 unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
1001
1002 if (delta > 0)
966 { 1003 {
967 /* Reinitialize iterator. */ 1004 if (unlikely (delta + count > MAX_CONTEXT_LENGTH))
968 hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1 , count - i); 1005 » break;
969 tmp.set_syllable (syllable);
970 skippy_iter = tmp;
971 }
972 }
973 else
974 {
975 not_applied:
976 /* No lookup applied for this index */
977 c->buffer->next_glyph ();
978 i++;
979 }
980 while (i < count)
981 {
982 if (!skippy_iter.next ()) return TRACE_RETURN (true);
983 while (c->buffer->idx < skippy_iter.idx)
984 c->buffer->next_glyph ();
985
986 if (lookupCount && i == lookupRecord->sequenceIndex)
987 {
988 unsigned int old_pos = c->buffer->idx;
989
990 /* Apply a lookup */
991 bool done = c->recurse (lookupRecord->lookupListIndex);
992
993 lookupRecord++;
994 lookupCount--;
995 /* Err, this is wrong if the lookup jumped over some glyphs */
996 i += c->buffer->idx - old_pos;
997
998 if (!done)
999 » goto not_applied2;
1000 else
1001 {
1002 /* Reinitialize iterator. */
1003 » hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
1004 » tmp.set_syllable (syllable);
1005 » skippy_iter = tmp;
1006 }
1007 } 1006 }
1008 else 1007 else
1009 { 1008 {
1010 not_applied2: 1009 /* NOTE: delta is negative. */
1011 /* No lookup applied for this index */ 1010 delta = MAX (delta, (int) next - (int) count);
1012 c->buffer->next_glyph (); 1011 next -= delta;
1013 i++;
1014 } 1012 }
1013
1014 /* Shift! */
1015 memmove (match_positions + next + delta, match_positions + next,
1016 (count - next) * sizeof (match_positions[0]));
1017 next += delta;
1018 count += delta;
1019
1020 /* Fill in new entries. */
1021 for (unsigned int j = idx + 1; j < next; j++)
1022 match_positions[j] = match_positions[j - 1] + 1;
1023
1024 /* And fixup the rest. */
1025 for (; next < count; next++)
1026 match_positions[next] += delta;
1015 } 1027 }
1016 1028
1029 buffer->move_to (end);
1030
1017 return TRACE_RETURN (true); 1031 return TRACE_RETURN (true);
1018 } 1032 }
1019 1033
1020 1034
1021 1035
1022 /* Contextual lookups */ 1036 /* Contextual lookups */
1023 1037
1024 struct ContextClosureLookupContext 1038 struct ContextClosureLookupContext
1025 { 1039 {
1026 ContextClosureFuncs funcs; 1040 ContextClosureFuncs funcs;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 inputCount, input, 1092 inputCount, input,
1079 lookup_context.funcs.match, lookup_context.match_dat a); 1093 lookup_context.funcs.match, lookup_context.match_dat a);
1080 } 1094 }
1081 static inline bool context_apply_lookup (hb_apply_context_t *c, 1095 static inline bool context_apply_lookup (hb_apply_context_t *c,
1082 unsigned int inputCount, /* Including t he first glyph (not matched) */ 1096 unsigned int inputCount, /* Including t he first glyph (not matched) */
1083 const USHORT input[], /* Array of input values--start with second glyph */ 1097 const USHORT input[], /* Array of input values--start with second glyph */
1084 unsigned int lookupCount, 1098 unsigned int lookupCount,
1085 const LookupRecord lookupRecord[], 1099 const LookupRecord lookupRecord[],
1086 ContextApplyLookupContext &lookup_conte xt) 1100 ContextApplyLookupContext &lookup_conte xt)
1087 { 1101 {
1102 unsigned int match_length = 0;
1103 unsigned int match_positions[MAX_CONTEXT_LENGTH];
1088 return match_input (c, 1104 return match_input (c,
1089 inputCount, input, 1105 inputCount, input,
1090 » » lookup_context.funcs.match, lookup_context.match_data) 1106 » » lookup_context.funcs.match, lookup_context.match_data,
1107 » » &match_length, match_positions)
1091 && apply_lookup (c, 1108 && apply_lookup (c,
1092 » » inputCount, input, 1109 » » inputCount, match_positions,
1093 » » lookup_context.funcs.match, lookup_context.match_data, 1110 » » lookupCount, lookupRecord,
1094 » » lookupCount, lookupRecord); 1111 » » match_length);
1095 } 1112 }
1096 1113
1097 struct Rule 1114 struct Rule
1098 { 1115 {
1099 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &loo kup_context) const 1116 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &loo kup_context) const
1100 { 1117 {
1101 TRACE_CLOSURE (this); 1118 TRACE_CLOSURE (this);
1102 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp ut[0].static_size * (inputCount ? inputCount - 1 : 0)); 1119 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp ut[0].static_size * (inputCount ? inputCount - 1 : 0));
1103 context_closure_lookup (c, 1120 context_closure_lookup (c,
1104 inputCount, input, 1121 inputCount, input,
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
1547 unsigned int lookupCount, 1564 unsigned int lookupCount,
1548 const LookupRecord lookupRecord [], 1565 const LookupRecord lookupRecord [],
1549 ChainContextClosureLookupContex t &lookup_context) 1566 ChainContextClosureLookupContex t &lookup_context)
1550 { 1567 {
1551 if (intersects_array (c, 1568 if (intersects_array (c,
1552 backtrackCount, backtrack, 1569 backtrackCount, backtrack,
1553 lookup_context.funcs.intersects, lookup_context.intersec ts_data[0]) 1570 lookup_context.funcs.intersects, lookup_context.intersec ts_data[0])
1554 && intersects_array (c, 1571 && intersects_array (c,
1555 inputCount ? inputCount - 1 : 0, input, 1572 inputCount ? inputCount - 1 : 0, input,
1556 lookup_context.funcs.intersects, lookup_context.intersec ts_data[1]) 1573 lookup_context.funcs.intersects, lookup_context.intersec ts_data[1])
1557 && intersects_array (c, 1574 && intersects_array (c,
1558 lookaheadCount, lookahead, 1575 lookaheadCount, lookahead,
1559 lookup_context.funcs.intersects, lookup_context.intersect s_data[2])) 1576 lookup_context.funcs.intersects, lookup_context.intersect s_data[2]))
1560 recurse_lookups (c, 1577 recurse_lookups (c,
1561 lookupCount, lookupRecord); 1578 lookupCount, lookupRecord);
1562 } 1579 }
1563 1580
1564 static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_contex t_t *c, 1581 static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_contex t_t *c,
1565 unsigned int backtrackCo unt, 1582 unsigned int backtrackCo unt,
1566 const USHORT backtrack[] , 1583 const USHORT backtrack[] ,
1567 unsigned int inputCount, /* Including the first glyph (not matched) */ 1584 unsigned int inputCount, /* Including the first glyph (not matched) */
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 unsigned int backtrackCount, 1623 unsigned int backtrackCount,
1607 const USHORT backtrack[], 1624 const USHORT backtrack[],
1608 unsigned int inputCount, /* Inclu ding the first glyph (not matched) */ 1625 unsigned int inputCount, /* Inclu ding the first glyph (not matched) */
1609 const USHORT input[], /* Array of input values--start with second glyph */ 1626 const USHORT input[], /* Array of input values--start with second glyph */
1610 unsigned int lookaheadCount, 1627 unsigned int lookaheadCount,
1611 const USHORT lookahead[], 1628 const USHORT lookahead[],
1612 unsigned int lookupCount, 1629 unsigned int lookupCount,
1613 const LookupRecord lookupRecord[] , 1630 const LookupRecord lookupRecord[] ,
1614 ChainContextApplyLookupContext &l ookup_context) 1631 ChainContextApplyLookupContext &l ookup_context)
1615 { 1632 {
1616 unsigned int lookahead_offset = 0; 1633 unsigned int match_length = 0;
1634 unsigned int match_positions[MAX_CONTEXT_LENGTH];
1617 return match_input (c, 1635 return match_input (c,
1618 inputCount, input, 1636 inputCount, input,
1619 lookup_context.funcs.match, lookup_context.match_data[1], 1637 lookup_context.funcs.match, lookup_context.match_data[1],
1620 » » &lookahead_offset) 1638 » » &match_length, match_positions)
1621 && match_backtrack (c, 1639 && match_backtrack (c,
1622 backtrackCount, backtrack, 1640 backtrackCount, backtrack,
1623 lookup_context.funcs.match, lookup_context.match_data[ 0]) 1641 lookup_context.funcs.match, lookup_context.match_data[ 0])
1624 && match_lookahead (c, 1642 && match_lookahead (c,
1625 lookaheadCount, lookahead, 1643 lookaheadCount, lookahead,
1626 lookup_context.funcs.match, lookup_context.match_data[ 2], 1644 lookup_context.funcs.match, lookup_context.match_data[ 2],
1627 » » » lookahead_offset) 1645 » » » match_length)
1628 && apply_lookup (c, 1646 && apply_lookup (c,
1629 » » inputCount, input, 1647 » » inputCount, match_positions,
1630 » » lookup_context.funcs.match, lookup_context.match_data[1], 1648 » » lookupCount, lookupRecord,
1631 » » lookupCount, lookupRecord); 1649 » » match_length);
1632 } 1650 }
1633 1651
1634 struct ChainRule 1652 struct ChainRule
1635 { 1653 {
1636 inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const 1654 inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
1637 { 1655 {
1638 TRACE_CLOSURE (this); 1656 TRACE_CLOSURE (this);
1639 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 1657 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
1640 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 1658 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
1641 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l ookahead); 1659 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l ookahead);
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
2270 lookupList; /* LookupList table */ 2288 lookupList; /* LookupList table */
2271 public: 2289 public:
2272 DEFINE_SIZE_STATIC (10); 2290 DEFINE_SIZE_STATIC (10);
2273 }; 2291 };
2274 2292
2275 2293
2276 } /* namespace OT */ 2294 } /* namespace OT */
2277 2295
2278 2296
2279 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ 2297 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh ('k') | third_party/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698