| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 */ |
| OLD | NEW |