| 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 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 AnchorFormat2 format2; | 329 AnchorFormat2 format2; |
| 330 AnchorFormat3 format3; | 330 AnchorFormat3 format3; |
| 331 } u; | 331 } u; |
| 332 public: | 332 public: |
| 333 DEFINE_SIZE_UNION (2, format); | 333 DEFINE_SIZE_UNION (2, format); |
| 334 }; | 334 }; |
| 335 | 335 |
| 336 | 336 |
| 337 struct AnchorMatrix | 337 struct AnchorMatrix |
| 338 { | 338 { |
| 339 inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned
int cols) const { | 339 inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned
int cols, bool *found) const { |
| 340 *found = false; |
| 340 if (unlikely (row >= rows || col >= cols)) return Null(Anchor); | 341 if (unlikely (row >= rows || col >= cols)) return Null(Anchor); |
| 342 *found = !matrix[row * cols + col].is_null (); |
| 341 return this+matrix[row * cols + col]; | 343 return this+matrix[row * cols + col]; |
| 342 } | 344 } |
| 343 | 345 |
| 344 inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) { | 346 inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) { |
| 345 TRACE_SANITIZE (this); | 347 TRACE_SANITIZE (this); |
| 346 if (!c->check_struct (this)) return TRACE_RETURN (false); | 348 if (!c->check_struct (this)) return TRACE_RETURN (false); |
| 347 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_
RETURN (false); | 349 if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_
RETURN (false); |
| 348 unsigned int count = rows * cols; | 350 unsigned int count = rows * cols; |
| 349 if (!c->check_array (matrix, matrix[0].static_size, count)) return TRACE_RET
URN (false); | 351 if (!c->check_array (matrix, matrix[0].static_size, count)) return TRACE_RET
URN (false); |
| 350 for (unsigned int i = 0; i < count; i++) | 352 for (unsigned int i = 0; i < count; i++) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 inline bool apply (hb_apply_context_t *c, | 387 inline bool apply (hb_apply_context_t *c, |
| 386 unsigned int mark_index, unsigned int glyph_index, | 388 unsigned int mark_index, unsigned int glyph_index, |
| 387 const AnchorMatrix &anchors, unsigned int class_count, | 389 const AnchorMatrix &anchors, unsigned int class_count, |
| 388 unsigned int glyph_pos) const | 390 unsigned int glyph_pos) const |
| 389 { | 391 { |
| 390 TRACE_APPLY (this); | 392 TRACE_APPLY (this); |
| 391 const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index); | 393 const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index); |
| 392 unsigned int mark_class = record.klass; | 394 unsigned int mark_class = record.klass; |
| 393 | 395 |
| 394 const Anchor& mark_anchor = this + record.markAnchor; | 396 const Anchor& mark_anchor = this + record.markAnchor; |
| 395 const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, cl
ass_count); | 397 bool found; |
| 398 const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, cl
ass_count, &found); |
| 399 /* If this subtable doesn't have an anchor for this base and this class, |
| 400 * return false such that the subsequent subtables have a chance at it. */ |
| 401 if (unlikely (!found)) return TRACE_RETURN (false); |
| 396 | 402 |
| 397 hb_position_t mark_x, mark_y, base_x, base_y; | 403 hb_position_t mark_x, mark_y, base_x, base_y; |
| 398 | 404 |
| 399 mark_anchor.get_anchor (c->font, c->buffer->cur().codepoint, &mark_x, &mark_
y); | 405 mark_anchor.get_anchor (c->font, c->buffer->cur().codepoint, &mark_x, &mark_
y); |
| 400 glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &bas
e_x, &base_y); | 406 glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &bas
e_x, &base_y); |
| 401 | 407 |
| 402 hb_glyph_position_t &o = c->buffer->cur_pos(); | 408 hb_glyph_position_t &o = c->buffer->cur_pos(); |
| 403 o.x_offset = base_x - mark_x; | 409 o.x_offset = base_x - mark_x; |
| 404 o.y_offset = base_y - mark_y; | 410 o.y_offset = base_y - mark_y; |
| 405 o.attach_lookback() = c->buffer->idx - glyph_pos; | 411 o.attach_lookback() = c->buffer->idx - glyph_pos; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 USHORT valueCount; /* Number of ValueRecords */ | 512 USHORT valueCount; /* Number of ValueRecords */ |
| 507 ValueRecord values; /* Array of ValueRecords--positioning | 513 ValueRecord values; /* Array of ValueRecords--positioning |
| 508 * values applied to glyphs */ | 514 * values applied to glyphs */ |
| 509 public: | 515 public: |
| 510 DEFINE_SIZE_ARRAY (8, values); | 516 DEFINE_SIZE_ARRAY (8, values); |
| 511 }; | 517 }; |
| 512 | 518 |
| 513 struct SinglePos | 519 struct SinglePos |
| 514 { | 520 { |
| 515 template <typename context_t> | 521 template <typename context_t> |
| 516 inline typename context_t::return_t process (context_t *c) const | 522 inline typename context_t::return_t dispatch (context_t *c) const |
| 517 { | 523 { |
| 518 TRACE_PROCESS (this); | 524 TRACE_DISPATCH (this); |
| 519 switch (u.format) { | 525 switch (u.format) { |
| 520 case 1: return TRACE_RETURN (c->process (u.format1)); | 526 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
| 521 case 2: return TRACE_RETURN (c->process (u.format2)); | 527 case 2: return TRACE_RETURN (c->dispatch (u.format2)); |
| 522 default:return TRACE_RETURN (c->default_return_value ()); | 528 default:return TRACE_RETURN (c->default_return_value ()); |
| 523 } | 529 } |
| 524 } | 530 } |
| 525 | 531 |
| 526 inline bool sanitize (hb_sanitize_context_t *c) { | 532 inline bool sanitize (hb_sanitize_context_t *c) { |
| 527 TRACE_SANITIZE (this); | 533 TRACE_SANITIZE (this); |
| 528 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 534 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
| 529 switch (u.format) { | 535 switch (u.format) { |
| 530 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 536 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
| 531 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | 537 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 { | 589 { |
| 584 TRACE_APPLY (this); | 590 TRACE_APPLY (this); |
| 585 unsigned int len1 = valueFormats[0].get_len (); | 591 unsigned int len1 = valueFormats[0].get_len (); |
| 586 unsigned int len2 = valueFormats[1].get_len (); | 592 unsigned int len2 = valueFormats[1].get_len (); |
| 587 unsigned int record_size = USHORT::static_size * (1 + len1 + len2); | 593 unsigned int record_size = USHORT::static_size * (1 + len1 + len2); |
| 588 | 594 |
| 589 const PairValueRecord *record = CastP<PairValueRecord> (array); | 595 const PairValueRecord *record = CastP<PairValueRecord> (array); |
| 590 unsigned int count = len; | 596 unsigned int count = len; |
| 591 for (unsigned int i = 0; i < count; i++) | 597 for (unsigned int i = 0; i < count; i++) |
| 592 { | 598 { |
| 599 /* TODO bsearch */ |
| 593 if (c->buffer->info[pos].codepoint == record->secondGlyph) | 600 if (c->buffer->info[pos].codepoint == record->secondGlyph) |
| 594 { | 601 { |
| 595 valueFormats[0].apply_value (c->font, c->direction, this, | 602 valueFormats[0].apply_value (c->font, c->direction, this, |
| 596 &record->values[0], c->buffer->cur_pos()); | 603 &record->values[0], c->buffer->cur_pos()); |
| 597 valueFormats[1].apply_value (c->font, c->direction, this, | 604 valueFormats[1].apply_value (c->font, c->direction, this, |
| 598 &record->values[len1], c->buffer->pos[pos])
; | 605 &record->values[len1], c->buffer->pos[pos])
; |
| 599 if (len2) | 606 if (len2) |
| 600 pos++; | 607 pos++; |
| 601 c->buffer->idx = pos; | 608 c->buffer->idx = pos; |
| 602 return TRACE_RETURN (true); | 609 return TRACE_RETURN (true); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 } | 652 } |
| 646 | 653 |
| 647 inline const Coverage &get_coverage (void) const | 654 inline const Coverage &get_coverage (void) const |
| 648 { | 655 { |
| 649 return this+coverage; | 656 return this+coverage; |
| 650 } | 657 } |
| 651 | 658 |
| 652 inline bool apply (hb_apply_context_t *c) const | 659 inline bool apply (hb_apply_context_t *c) const |
| 653 { | 660 { |
| 654 TRACE_APPLY (this); | 661 TRACE_APPLY (this); |
| 655 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff
er->idx, 1); | 662 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->i
dx, 1); |
| 656 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); | 663 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); |
| 657 | 664 |
| 658 unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoi
nt); | 665 unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoi
nt); |
| 659 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 666 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
| 660 | 667 |
| 661 if (!skippy_iter.next ()) return TRACE_RETURN (false); | 668 if (!skippy_iter.next ()) return TRACE_RETURN (false); |
| 662 | 669 |
| 663 return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_i
ter.idx)); | 670 return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_i
ter.idx)); |
| 664 } | 671 } |
| 665 | 672 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 } | 724 } |
| 718 | 725 |
| 719 inline const Coverage &get_coverage (void) const | 726 inline const Coverage &get_coverage (void) const |
| 720 { | 727 { |
| 721 return this+coverage; | 728 return this+coverage; |
| 722 } | 729 } |
| 723 | 730 |
| 724 inline bool apply (hb_apply_context_t *c) const | 731 inline bool apply (hb_apply_context_t *c) const |
| 725 { | 732 { |
| 726 TRACE_APPLY (this); | 733 TRACE_APPLY (this); |
| 727 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff
er->idx, 1); | 734 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->i
dx, 1); |
| 728 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); | 735 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); |
| 729 | 736 |
| 730 unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoi
nt); | 737 unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoi
nt); |
| 731 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 738 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
| 732 | 739 |
| 733 if (!skippy_iter.next ()) return TRACE_RETURN (false); | 740 if (!skippy_iter.next ()) return TRACE_RETURN (false); |
| 734 | 741 |
| 735 unsigned int len1 = valueFormat1.get_len (); | 742 unsigned int len1 = valueFormat1.get_len (); |
| 736 unsigned int len2 = valueFormat2.get_len (); | 743 unsigned int len2 = valueFormat2.get_len (); |
| 737 unsigned int record_len = len1 + len2; | 744 unsigned int record_len = len1 + len2; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 ValueRecord values; /* Matrix of value pairs: | 803 ValueRecord values; /* Matrix of value pairs: |
| 797 * class1-major, class2-minor, | 804 * class1-major, class2-minor, |
| 798 * Each entry has value1 and value2 */ | 805 * Each entry has value1 and value2 */ |
| 799 public: | 806 public: |
| 800 DEFINE_SIZE_ARRAY (16, values); | 807 DEFINE_SIZE_ARRAY (16, values); |
| 801 }; | 808 }; |
| 802 | 809 |
| 803 struct PairPos | 810 struct PairPos |
| 804 { | 811 { |
| 805 template <typename context_t> | 812 template <typename context_t> |
| 806 inline typename context_t::return_t process (context_t *c) const | 813 inline typename context_t::return_t dispatch (context_t *c) const |
| 807 { | 814 { |
| 808 TRACE_PROCESS (this); | 815 TRACE_DISPATCH (this); |
| 809 switch (u.format) { | 816 switch (u.format) { |
| 810 case 1: return TRACE_RETURN (c->process (u.format1)); | 817 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
| 811 case 2: return TRACE_RETURN (c->process (u.format2)); | 818 case 2: return TRACE_RETURN (c->dispatch (u.format2)); |
| 812 default:return TRACE_RETURN (c->default_return_value ()); | 819 default:return TRACE_RETURN (c->default_return_value ()); |
| 813 } | 820 } |
| 814 } | 821 } |
| 815 | 822 |
| 816 inline bool sanitize (hb_sanitize_context_t *c) { | 823 inline bool sanitize (hb_sanitize_context_t *c) { |
| 817 TRACE_SANITIZE (this); | 824 TRACE_SANITIZE (this); |
| 818 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 825 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
| 819 switch (u.format) { | 826 switch (u.format) { |
| 820 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 827 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
| 821 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | 828 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 inline const Coverage &get_coverage (void) const | 872 inline const Coverage &get_coverage (void) const |
| 866 { | 873 { |
| 867 return this+coverage; | 874 return this+coverage; |
| 868 } | 875 } |
| 869 | 876 |
| 870 inline bool apply (hb_apply_context_t *c) const | 877 inline bool apply (hb_apply_context_t *c) const |
| 871 { | 878 { |
| 872 TRACE_APPLY (this); | 879 TRACE_APPLY (this); |
| 873 | 880 |
| 874 /* We don't handle mark glyphs here. */ | 881 /* We don't handle mark glyphs here. */ |
| 875 if (c->property & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return TRACE_RETURN (false)
; | 882 if (c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return T
RACE_RETURN (false); |
| 876 | 883 |
| 877 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buff
er->idx, 1); | 884 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->i
dx, 1); |
| 878 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); | 885 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); |
| 879 | 886 |
| 880 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_cov
erage (c->buffer->cur().codepoint)]; | 887 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_cov
erage (c->buffer->cur().codepoint)]; |
| 881 if (!this_record.exitAnchor) return TRACE_RETURN (false); | 888 if (!this_record.exitAnchor) return TRACE_RETURN (false); |
| 882 | 889 |
| 883 if (!skippy_iter.next ()) return TRACE_RETURN (false); | 890 if (!skippy_iter.next ()) return TRACE_RETURN (false); |
| 884 | 891 |
| 885 const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_cov
erage (c->buffer->info[skippy_iter.idx].codepoint)]; | 892 const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_cov
erage (c->buffer->info[skippy_iter.idx].codepoint)]; |
| 886 if (!next_record.entryAnchor) return TRACE_RETURN (false); | 893 if (!next_record.entryAnchor) return TRACE_RETURN (false); |
| 887 | 894 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 ArrayOf<EntryExitRecord> | 969 ArrayOf<EntryExitRecord> |
| 963 entryExitRecord; /* Array of EntryExit records--in | 970 entryExitRecord; /* Array of EntryExit records--in |
| 964 * Coverage Index order */ | 971 * Coverage Index order */ |
| 965 public: | 972 public: |
| 966 DEFINE_SIZE_ARRAY (6, entryExitRecord); | 973 DEFINE_SIZE_ARRAY (6, entryExitRecord); |
| 967 }; | 974 }; |
| 968 | 975 |
| 969 struct CursivePos | 976 struct CursivePos |
| 970 { | 977 { |
| 971 template <typename context_t> | 978 template <typename context_t> |
| 972 inline typename context_t::return_t process (context_t *c) const | 979 inline typename context_t::return_t dispatch (context_t *c) const |
| 973 { | 980 { |
| 974 TRACE_PROCESS (this); | 981 TRACE_DISPATCH (this); |
| 975 switch (u.format) { | 982 switch (u.format) { |
| 976 case 1: return TRACE_RETURN (c->process (u.format1)); | 983 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
| 977 default:return TRACE_RETURN (c->default_return_value ()); | 984 default:return TRACE_RETURN (c->default_return_value ()); |
| 978 } | 985 } |
| 979 } | 986 } |
| 980 | 987 |
| 981 inline bool sanitize (hb_sanitize_context_t *c) { | 988 inline bool sanitize (hb_sanitize_context_t *c) { |
| 982 TRACE_SANITIZE (this); | 989 TRACE_SANITIZE (this); |
| 983 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 990 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
| 984 switch (u.format) { | 991 switch (u.format) { |
| 985 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 992 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
| 986 default:return TRACE_RETURN (true); | 993 default:return TRACE_RETURN (true); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1015 return this+markCoverage; | 1022 return this+markCoverage; |
| 1016 } | 1023 } |
| 1017 | 1024 |
| 1018 inline bool apply (hb_apply_context_t *c) const | 1025 inline bool apply (hb_apply_context_t *c) const |
| 1019 { | 1026 { |
| 1020 TRACE_APPLY (this); | 1027 TRACE_APPLY (this); |
| 1021 unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur(
).codepoint); | 1028 unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur(
).codepoint); |
| 1022 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); | 1029 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); |
| 1023 | 1030 |
| 1024 /* now we search backwards for a non-mark glyph */ | 1031 /* now we search backwards for a non-mark glyph */ |
| 1025 unsigned int property; | 1032 hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->
idx, 1); |
| 1026 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf
fer->idx, 1); | 1033 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); |
| 1027 do { | 1034 do { |
| 1028 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_R
ETURN (false); | 1035 if (!skippy_iter.prev ()) return TRACE_RETURN (false); |
| 1029 /* We only want to attach to the first of a MultipleSubst sequence. Rejec
t others. */ | 1036 /* We only want to attach to the first of a MultipleSubst sequence. Rejec
t others. */ |
| 1030 if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break; | 1037 if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break; |
| 1031 skippy_iter.reject (); | 1038 skippy_iter.reject (); |
| 1032 } while (1); | 1039 } while (1); |
| 1033 | 1040 |
| 1034 /* The following assertion is too strong, so we've disabled it. */ | 1041 /* The following assertion is too strong, so we've disabled it. */ |
| 1035 if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH)) {/*return TRACE_RETUR
N (false);*/} | 1042 if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PR
OPS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/} |
| 1036 | 1043 |
| 1037 unsigned int base_index = (this+baseCoverage).get_coverage (c->buffer->info
[skippy_iter.idx].codepoint); | 1044 unsigned int base_index = (this+baseCoverage).get_coverage (c->buffer->info
[skippy_iter.idx].codepoint); |
| 1038 if (base_index == NOT_COVERED) return TRACE_RETURN (false); | 1045 if (base_index == NOT_COVERED) return TRACE_RETURN (false); |
| 1039 | 1046 |
| 1040 return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this
+baseArray, classCount, skippy_iter.idx)); | 1047 return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this
+baseArray, classCount, skippy_iter.idx)); |
| 1041 } | 1048 } |
| 1042 | 1049 |
| 1043 inline bool sanitize (hb_sanitize_context_t *c) { | 1050 inline bool sanitize (hb_sanitize_context_t *c) { |
| 1044 TRACE_SANITIZE (this); | 1051 TRACE_SANITIZE (this); |
| 1045 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi
s) && baseCoverage.sanitize (c, this) && | 1052 return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, thi
s) && baseCoverage.sanitize (c, this) && |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1061 OffsetTo<BaseArray> | 1068 OffsetTo<BaseArray> |
| 1062 baseArray; /* Offset to BaseArray table--from | 1069 baseArray; /* Offset to BaseArray table--from |
| 1063 * beginning of MarkBasePos subtable */ | 1070 * beginning of MarkBasePos subtable */ |
| 1064 public: | 1071 public: |
| 1065 DEFINE_SIZE_STATIC (12); | 1072 DEFINE_SIZE_STATIC (12); |
| 1066 }; | 1073 }; |
| 1067 | 1074 |
| 1068 struct MarkBasePos | 1075 struct MarkBasePos |
| 1069 { | 1076 { |
| 1070 template <typename context_t> | 1077 template <typename context_t> |
| 1071 inline typename context_t::return_t process (context_t *c) const | 1078 inline typename context_t::return_t dispatch (context_t *c) const |
| 1072 { | 1079 { |
| 1073 TRACE_PROCESS (this); | 1080 TRACE_DISPATCH (this); |
| 1074 switch (u.format) { | 1081 switch (u.format) { |
| 1075 case 1: return TRACE_RETURN (c->process (u.format1)); | 1082 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
| 1076 default:return TRACE_RETURN (c->default_return_value ()); | 1083 default:return TRACE_RETURN (c->default_return_value ()); |
| 1077 } | 1084 } |
| 1078 } | 1085 } |
| 1079 | 1086 |
| 1080 inline bool sanitize (hb_sanitize_context_t *c) { | 1087 inline bool sanitize (hb_sanitize_context_t *c) { |
| 1081 TRACE_SANITIZE (this); | 1088 TRACE_SANITIZE (this); |
| 1082 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 1089 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
| 1083 switch (u.format) { | 1090 switch (u.format) { |
| 1084 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 1091 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
| 1085 default:return TRACE_RETURN (true); | 1092 default:return TRACE_RETURN (true); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 return this+markCoverage; | 1126 return this+markCoverage; |
| 1120 } | 1127 } |
| 1121 | 1128 |
| 1122 inline bool apply (hb_apply_context_t *c) const | 1129 inline bool apply (hb_apply_context_t *c) const |
| 1123 { | 1130 { |
| 1124 TRACE_APPLY (this); | 1131 TRACE_APPLY (this); |
| 1125 unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur(
).codepoint); | 1132 unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur(
).codepoint); |
| 1126 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); | 1133 if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); |
| 1127 | 1134 |
| 1128 /* now we search backwards for a non-mark glyph */ | 1135 /* now we search backwards for a non-mark glyph */ |
| 1129 unsigned int property; | 1136 hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->
idx, 1); |
| 1130 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf
fer->idx, 1); | 1137 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); |
| 1131 if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RET
URN (false); | 1138 if (!skippy_iter.prev ()) return TRACE_RETURN (false); |
| 1132 | 1139 |
| 1133 /* The following assertion is too strong, so we've disabled it. */ | 1140 /* The following assertion is too strong, so we've disabled it. */ |
| 1134 if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN
(false);*/} | 1141 if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PR
OPS_LIGATURE)) {/*return TRACE_RETURN (false);*/} |
| 1135 | 1142 |
| 1136 unsigned int j = skippy_iter.idx; | 1143 unsigned int j = skippy_iter.idx; |
| 1137 unsigned int lig_index = (this+ligatureCoverage).get_coverage (c->buffer->i
nfo[j].codepoint); | 1144 unsigned int lig_index = (this+ligatureCoverage).get_coverage (c->buffer->i
nfo[j].codepoint); |
| 1138 if (lig_index == NOT_COVERED) return TRACE_RETURN (false); | 1145 if (lig_index == NOT_COVERED) return TRACE_RETURN (false); |
| 1139 | 1146 |
| 1140 const LigatureArray& lig_array = this+ligatureArray; | 1147 const LigatureArray& lig_array = this+ligatureArray; |
| 1141 const LigatureAttach& lig_attach = lig_array[lig_index]; | 1148 const LigatureAttach& lig_attach = lig_array[lig_index]; |
| 1142 | 1149 |
| 1143 /* Find component to attach to */ | 1150 /* Find component to attach to */ |
| 1144 unsigned int comp_count = lig_attach.rows; | 1151 unsigned int comp_count = lig_attach.rows; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 OffsetTo<LigatureArray> | 1189 OffsetTo<LigatureArray> |
| 1183 ligatureArray; /* Offset to LigatureArray table--from | 1190 ligatureArray; /* Offset to LigatureArray table--from |
| 1184 * beginning of MarkLigPos subtable */ | 1191 * beginning of MarkLigPos subtable */ |
| 1185 public: | 1192 public: |
| 1186 DEFINE_SIZE_STATIC (12); | 1193 DEFINE_SIZE_STATIC (12); |
| 1187 }; | 1194 }; |
| 1188 | 1195 |
| 1189 struct MarkLigPos | 1196 struct MarkLigPos |
| 1190 { | 1197 { |
| 1191 template <typename context_t> | 1198 template <typename context_t> |
| 1192 inline typename context_t::return_t process (context_t *c) const | 1199 inline typename context_t::return_t dispatch (context_t *c) const |
| 1193 { | 1200 { |
| 1194 TRACE_PROCESS (this); | 1201 TRACE_DISPATCH (this); |
| 1195 switch (u.format) { | 1202 switch (u.format) { |
| 1196 case 1: return TRACE_RETURN (c->process (u.format1)); | 1203 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
| 1197 default:return TRACE_RETURN (c->default_return_value ()); | 1204 default:return TRACE_RETURN (c->default_return_value ()); |
| 1198 } | 1205 } |
| 1199 } | 1206 } |
| 1200 | 1207 |
| 1201 inline bool sanitize (hb_sanitize_context_t *c) { | 1208 inline bool sanitize (hb_sanitize_context_t *c) { |
| 1202 TRACE_SANITIZE (this); | 1209 TRACE_SANITIZE (this); |
| 1203 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 1210 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
| 1204 switch (u.format) { | 1211 switch (u.format) { |
| 1205 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 1212 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
| 1206 default:return TRACE_RETURN (true); | 1213 default:return TRACE_RETURN (true); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1235 return this+mark1Coverage; | 1242 return this+mark1Coverage; |
| 1236 } | 1243 } |
| 1237 | 1244 |
| 1238 inline bool apply (hb_apply_context_t *c) const | 1245 inline bool apply (hb_apply_context_t *c) const |
| 1239 { | 1246 { |
| 1240 TRACE_APPLY (this); | 1247 TRACE_APPLY (this); |
| 1241 unsigned int mark1_index = (this+mark1Coverage).get_coverage (c->buffer->cu
r().codepoint); | 1248 unsigned int mark1_index = (this+mark1Coverage).get_coverage (c->buffer->cu
r().codepoint); |
| 1242 if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); | 1249 if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); |
| 1243 | 1250 |
| 1244 /* now we search backwards for a suitable mark glyph until a non-mark glyph
*/ | 1251 /* now we search backwards for a suitable mark glyph until a non-mark glyph
*/ |
| 1245 unsigned int property; | 1252 hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->
idx, 1); |
| 1246 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buf
fer->idx, 1); | 1253 skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); |
| 1247 if (!skippy_iter.prev (&property)) return TRACE_RETURN (false); | 1254 if (!skippy_iter.prev ()) return TRACE_RETURN (false); |
| 1248 | 1255 |
| 1249 if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) return TRACE_RETURN (false)
; | 1256 if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PR
OPS_MARK)) { return TRACE_RETURN (false); } |
| 1250 | 1257 |
| 1251 unsigned int j = skippy_iter.idx; | 1258 unsigned int j = skippy_iter.idx; |
| 1252 | 1259 |
| 1253 unsigned int id1 = get_lig_id (c->buffer->cur()); | 1260 unsigned int id1 = get_lig_id (c->buffer->cur()); |
| 1254 unsigned int id2 = get_lig_id (c->buffer->info[j]); | 1261 unsigned int id2 = get_lig_id (c->buffer->info[j]); |
| 1255 unsigned int comp1 = get_lig_comp (c->buffer->cur()); | 1262 unsigned int comp1 = get_lig_comp (c->buffer->cur()); |
| 1256 unsigned int comp2 = get_lig_comp (c->buffer->info[j]); | 1263 unsigned int comp2 = get_lig_comp (c->buffer->info[j]); |
| 1257 | 1264 |
| 1258 if (likely (id1 == id2)) { | 1265 if (likely (id1 == id2)) { |
| 1259 if (id1 == 0) /* Marks belonging to the same base. */ | 1266 if (id1 == 0) /* Marks belonging to the same base. */ |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1301 OffsetTo<Mark2Array> | 1308 OffsetTo<Mark2Array> |
| 1302 mark2Array; /* Offset to Mark2Array table--from | 1309 mark2Array; /* Offset to Mark2Array table--from |
| 1303 * beginning of MarkMarkPos subtable */ | 1310 * beginning of MarkMarkPos subtable */ |
| 1304 public: | 1311 public: |
| 1305 DEFINE_SIZE_STATIC (12); | 1312 DEFINE_SIZE_STATIC (12); |
| 1306 }; | 1313 }; |
| 1307 | 1314 |
| 1308 struct MarkMarkPos | 1315 struct MarkMarkPos |
| 1309 { | 1316 { |
| 1310 template <typename context_t> | 1317 template <typename context_t> |
| 1311 inline typename context_t::return_t process (context_t *c) const | 1318 inline typename context_t::return_t dispatch (context_t *c) const |
| 1312 { | 1319 { |
| 1313 TRACE_PROCESS (this); | 1320 TRACE_DISPATCH (this); |
| 1314 switch (u.format) { | 1321 switch (u.format) { |
| 1315 case 1: return TRACE_RETURN (c->process (u.format1)); | 1322 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
| 1316 default:return TRACE_RETURN (c->default_return_value ()); | 1323 default:return TRACE_RETURN (c->default_return_value ()); |
| 1317 } | 1324 } |
| 1318 } | 1325 } |
| 1319 | 1326 |
| 1320 inline bool sanitize (hb_sanitize_context_t *c) { | 1327 inline bool sanitize (hb_sanitize_context_t *c) { |
| 1321 TRACE_SANITIZE (this); | 1328 TRACE_SANITIZE (this); |
| 1322 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 1329 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
| 1323 switch (u.format) { | 1330 switch (u.format) { |
| 1324 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 1331 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
| 1325 default:return TRACE_RETURN (true); | 1332 default:return TRACE_RETURN (true); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1360 Cursive = 3, | 1367 Cursive = 3, |
| 1361 MarkBase = 4, | 1368 MarkBase = 4, |
| 1362 MarkLig = 5, | 1369 MarkLig = 5, |
| 1363 MarkMark = 6, | 1370 MarkMark = 6, |
| 1364 Context = 7, | 1371 Context = 7, |
| 1365 ChainContext = 8, | 1372 ChainContext = 8, |
| 1366 Extension = 9 | 1373 Extension = 9 |
| 1367 }; | 1374 }; |
| 1368 | 1375 |
| 1369 template <typename context_t> | 1376 template <typename context_t> |
| 1370 inline typename context_t::return_t process (context_t *c, unsigned int lookup
_type) const | 1377 inline typename context_t::return_t dispatch (context_t *c, unsigned int looku
p_type) const |
| 1371 { | 1378 { |
| 1372 TRACE_PROCESS (this); | 1379 TRACE_DISPATCH (this); |
| 1373 switch (lookup_type) { | 1380 switch (lookup_type) { |
| 1374 case Single:» » return TRACE_RETURN (u.single.process (c)); | 1381 case Single:» » return TRACE_RETURN (u.single.dispatch (c)); |
| 1375 case Pair:» » » return TRACE_RETURN (u.pair.process (c)); | 1382 case Pair:» » » return TRACE_RETURN (u.pair.dispatch (c)); |
| 1376 case Cursive:» » return TRACE_RETURN (u.cursive.process (c)); | 1383 case Cursive:» » return TRACE_RETURN (u.cursive.dispatch (c)); |
| 1377 case MarkBase:» » return TRACE_RETURN (u.markBase.process (c)); | 1384 case MarkBase:» » return TRACE_RETURN (u.markBase.dispatch (c)); |
| 1378 case MarkLig:» » return TRACE_RETURN (u.markLig.process (c)); | 1385 case MarkLig:» » return TRACE_RETURN (u.markLig.dispatch (c)); |
| 1379 case MarkMark:» » return TRACE_RETURN (u.markMark.process (c)); | 1386 case MarkMark:» » return TRACE_RETURN (u.markMark.dispatch (c)); |
| 1380 case Context:» » return TRACE_RETURN (u.context.process (c)); | 1387 case Context:» » return TRACE_RETURN (u.context.dispatch (c)); |
| 1381 case ChainContext:» » return TRACE_RETURN (u.chainContext.process (c))
; | 1388 case ChainContext:» » return TRACE_RETURN (u.chainContext.dispatch (c)
); |
| 1382 case Extension:» » return TRACE_RETURN (u.extension.process (c)); | 1389 case Extension:» » return TRACE_RETURN (u.extension.dispatch (c)); |
| 1383 default: return TRACE_RETURN (c->default_return_value ())
; | 1390 default: return TRACE_RETURN (c->default_return_value ())
; |
| 1384 } | 1391 } |
| 1385 } | 1392 } |
| 1386 | 1393 |
| 1387 inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { | 1394 inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { |
| 1388 TRACE_SANITIZE (this); | 1395 TRACE_SANITIZE (this); |
| 1389 if (!u.header.sub_format.sanitize (c)) | 1396 if (!u.header.sub_format.sanitize (c)) |
| 1390 return TRACE_RETURN (false); | 1397 return TRACE_RETURN (false); |
| 1391 switch (lookup_type) { | 1398 switch (lookup_type) { |
| 1392 case Single: return TRACE_RETURN (u.single.sanitize (c)); | 1399 case Single: return TRACE_RETURN (u.single.sanitize (c)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1420 public: | 1427 public: |
| 1421 DEFINE_SIZE_UNION (2, header.sub_format); | 1428 DEFINE_SIZE_UNION (2, header.sub_format); |
| 1422 }; | 1429 }; |
| 1423 | 1430 |
| 1424 | 1431 |
| 1425 struct PosLookup : Lookup | 1432 struct PosLookup : Lookup |
| 1426 { | 1433 { |
| 1427 inline const PosLookupSubTable& get_subtable (unsigned int i) const | 1434 inline const PosLookupSubTable& get_subtable (unsigned int i) const |
| 1428 { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } | 1435 { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } |
| 1429 | 1436 |
| 1430 template <typename context_t> | |
| 1431 inline typename context_t::return_t process (context_t *c) const | |
| 1432 { | |
| 1433 TRACE_PROCESS (this); | |
| 1434 unsigned int lookup_type = get_type (); | |
| 1435 unsigned int count = get_subtable_count (); | |
| 1436 for (unsigned int i = 0; i < count; i++) { | |
| 1437 typename context_t::return_t r = get_subtable (i).process (c, lookup_type)
; | |
| 1438 if (c->stop_sublookup_iteration (r)) | |
| 1439 return TRACE_RETURN (r); | |
| 1440 } | |
| 1441 return TRACE_RETURN (c->default_return_value ()); | |
| 1442 } | |
| 1443 template <typename context_t> | |
| 1444 static inline typename context_t::return_t process_recurse_func (context_t *c,
unsigned int lookup_index); | |
| 1445 | |
| 1446 inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect
_glyphs_context_t *c) const | 1437 inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect
_glyphs_context_t *c) const |
| 1447 { | 1438 { |
| 1448 TRACE_COLLECT_GLYPHS (this); | 1439 TRACE_COLLECT_GLYPHS (this); |
| 1449 c->set_recurse_func (NULL); | 1440 c->set_recurse_func (NULL); |
| 1450 return TRACE_RETURN (process (c)); | 1441 return TRACE_RETURN (dispatch (c)); |
| 1451 } | 1442 } |
| 1452 | 1443 |
| 1453 template <typename set_t> | 1444 template <typename set_t> |
| 1454 inline void add_coverage (set_t *glyphs) const | 1445 inline void add_coverage (set_t *glyphs) const |
| 1455 { | 1446 { |
| 1456 hb_get_coverage_context_t c; | 1447 hb_get_coverage_context_t c; |
| 1457 const Coverage *last = NULL; | 1448 const Coverage *last = NULL; |
| 1458 unsigned int count = get_subtable_count (); | 1449 unsigned int count = get_subtable_count (); |
| 1459 for (unsigned int i = 0; i < count; i++) { | 1450 for (unsigned int i = 0; i < count; i++) { |
| 1460 const Coverage *coverage = &get_subtable (i).process (&c, get_type ()); | 1451 const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); |
| 1461 if (coverage != last) { | 1452 if (coverage != last) { |
| 1462 coverage->add_coverage (glyphs); | 1453 coverage->add_coverage (glyphs); |
| 1463 last = coverage; | 1454 last = coverage; |
| 1464 } | 1455 } |
| 1465 } | 1456 } |
| 1466 } | 1457 } |
| 1467 | 1458 |
| 1468 inline bool apply_once (hb_apply_context_t *c) const | 1459 inline bool apply_once (hb_apply_context_t *c) const |
| 1469 { | 1460 { |
| 1470 TRACE_APPLY (this); | 1461 TRACE_APPLY (this); |
| 1471 if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->proper
ty)) | 1462 if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) |
| 1472 return TRACE_RETURN (false); | 1463 return TRACE_RETURN (false); |
| 1473 return TRACE_RETURN (process (c)); | 1464 return TRACE_RETURN (dispatch (c)); |
| 1474 } | 1465 } |
| 1475 | 1466 |
| 1476 static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_ind
ex); | 1467 static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_ind
ex); |
| 1477 | 1468 |
| 1478 inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest
) const | 1469 inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest
) const |
| 1479 { | 1470 { |
| 1480 bool ret = false; | 1471 bool ret = false; |
| 1481 | 1472 |
| 1482 if (unlikely (!c->buffer->len || !c->lookup_mask)) | 1473 if (unlikely (!c->buffer->len || !c->lookup_mask)) |
| 1483 return false; | 1474 return false; |
| 1484 | 1475 |
| 1485 c->set_recurse_func (apply_recurse_func); | 1476 c->set_recurse_func (apply_recurse_func); |
| 1486 c->set_lookup (*this); | 1477 c->set_lookup (*this); |
| 1487 | 1478 |
| 1488 c->buffer->idx = 0; | 1479 c->buffer->idx = 0; |
| 1489 | 1480 |
| 1490 while (c->buffer->idx < c->buffer->len) | 1481 while (c->buffer->idx < c->buffer->len) |
| 1491 { | 1482 { |
| 1492 if ((c->buffer->cur().mask & c->lookup_mask) && | 1483 if ((c->buffer->cur().mask & c->lookup_mask) && |
| 1493 digest->may_have (c->buffer->cur().codepoint) && | 1484 digest->may_have (c->buffer->cur().codepoint) && |
| 1494 apply_once (c)) | 1485 apply_once (c)) |
| 1495 ret = true; | 1486 ret = true; |
| 1496 else | 1487 else |
| 1497 c->buffer->idx++; | 1488 c->buffer->idx++; |
| 1498 } | 1489 } |
| 1499 | 1490 |
| 1500 return ret; | 1491 return ret; |
| 1501 } | 1492 } |
| 1502 | 1493 |
| 1494 template <typename context_t> |
| 1495 static inline typename context_t::return_t dispatch_recurse_func (context_t *c
, unsigned int lookup_index); |
| 1496 |
| 1497 template <typename context_t> |
| 1498 inline typename context_t::return_t dispatch (context_t *c) const |
| 1499 { |
| 1500 TRACE_DISPATCH (this); |
| 1501 unsigned int lookup_type = get_type (); |
| 1502 unsigned int count = get_subtable_count (); |
| 1503 for (unsigned int i = 0; i < count; i++) { |
| 1504 typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type
); |
| 1505 if (c->stop_sublookup_iteration (r)) |
| 1506 return TRACE_RETURN (r); |
| 1507 } |
| 1508 return TRACE_RETURN (c->default_return_value ()); |
| 1509 } |
| 1510 |
| 1503 inline bool sanitize (hb_sanitize_context_t *c) { | 1511 inline bool sanitize (hb_sanitize_context_t *c) { |
| 1504 TRACE_SANITIZE (this); | 1512 TRACE_SANITIZE (this); |
| 1505 if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); | 1513 if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); |
| 1506 OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTab
le> > (subTable); | 1514 OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTab
le> > (subTable); |
| 1507 return TRACE_RETURN (list.sanitize (c, this, get_type ())); | 1515 return TRACE_RETURN (list.sanitize (c, this, get_type ())); |
| 1508 } | 1516 } |
| 1509 }; | 1517 }; |
| 1510 | 1518 |
| 1511 typedef OffsetListOf<PosLookup> PosLookupList; | 1519 typedef OffsetListOf<PosLookup> PosLookupList; |
| 1512 | 1520 |
| 1513 /* | 1521 /* |
| 1514 * GPOS -- The Glyph Positioning Table | 1522 * GPOS -- The Glyph Positioning Table |
| 1515 */ | 1523 */ |
| 1516 | 1524 |
| 1517 struct GPOS : GSUBGPOS | 1525 struct GPOS : GSUBGPOS |
| 1518 { | 1526 { |
| 1519 static const hb_tag_t Tag = HB_OT_TAG_GPOS; | 1527 static const hb_tag_t Tag = HB_OT_TAG_GPOS; |
| 1520 | 1528 |
| 1521 inline const PosLookup& get_lookup (unsigned int i) const | 1529 inline const PosLookup& get_lookup (unsigned int i) const |
| 1522 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } | 1530 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } |
| 1523 | 1531 |
| 1524 static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); | 1532 static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); |
| 1525 static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_b
ool_t zero_width_attahced_marks); | 1533 static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); |
| 1526 | 1534 |
| 1527 inline bool sanitize (hb_sanitize_context_t *c) { | 1535 inline bool sanitize (hb_sanitize_context_t *c) { |
| 1528 TRACE_SANITIZE (this); | 1536 TRACE_SANITIZE (this); |
| 1529 if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); | 1537 if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); |
| 1530 OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList)
; | 1538 OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList)
; |
| 1531 return TRACE_RETURN (list.sanitize (c, this)); | 1539 return TRACE_RETURN (list.sanitize (c, this)); |
| 1532 } | 1540 } |
| 1533 public: | 1541 public: |
| 1534 DEFINE_SIZE_STATIC (10); | 1542 DEFINE_SIZE_STATIC (10); |
| 1535 }; | 1543 }; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1548 | 1556 |
| 1549 fix_cursive_minor_offset (pos, j, direction); | 1557 fix_cursive_minor_offset (pos, j, direction); |
| 1550 | 1558 |
| 1551 if (HB_DIRECTION_IS_HORIZONTAL (direction)) | 1559 if (HB_DIRECTION_IS_HORIZONTAL (direction)) |
| 1552 pos[i].y_offset += pos[j].y_offset; | 1560 pos[i].y_offset += pos[j].y_offset; |
| 1553 else | 1561 else |
| 1554 pos[i].x_offset += pos[j].x_offset; | 1562 pos[i].x_offset += pos[j].x_offset; |
| 1555 } | 1563 } |
| 1556 | 1564 |
| 1557 static void | 1565 static void |
| 1558 fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t di
rection, hb_bool_t zero_width_attached_marks) | 1566 fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t di
rection) |
| 1559 { | 1567 { |
| 1560 if (likely (!(pos[i].attach_lookback()))) | 1568 if (likely (!(pos[i].attach_lookback()))) |
| 1561 return; | 1569 return; |
| 1562 | 1570 |
| 1563 unsigned int j = i - pos[i].attach_lookback(); | 1571 unsigned int j = i - pos[i].attach_lookback(); |
| 1564 | 1572 |
| 1565 if (zero_width_attached_marks) { | |
| 1566 pos[i].x_advance = 0; | |
| 1567 pos[i].y_advance = 0; | |
| 1568 } | |
| 1569 pos[i].x_offset += pos[j].x_offset; | 1573 pos[i].x_offset += pos[j].x_offset; |
| 1570 pos[i].y_offset += pos[j].y_offset; | 1574 pos[i].y_offset += pos[j].y_offset; |
| 1571 | 1575 |
| 1572 if (HB_DIRECTION_IS_FORWARD (direction)) | 1576 if (HB_DIRECTION_IS_FORWARD (direction)) |
| 1573 for (unsigned int k = j; k < i; k++) { | 1577 for (unsigned int k = j; k < i; k++) { |
| 1574 pos[i].x_offset -= pos[k].x_advance; | 1578 pos[i].x_offset -= pos[k].x_advance; |
| 1575 pos[i].y_offset -= pos[k].y_advance; | 1579 pos[i].y_offset -= pos[k].y_advance; |
| 1576 } | 1580 } |
| 1577 else | 1581 else |
| 1578 for (unsigned int k = j + 1; k < i + 1; k++) { | 1582 for (unsigned int k = j + 1; k < i + 1; k++) { |
| 1579 pos[i].x_offset += pos[k].x_advance; | 1583 pos[i].x_offset += pos[k].x_advance; |
| 1580 pos[i].y_offset += pos[k].y_advance; | 1584 pos[i].y_offset += pos[k].y_advance; |
| 1581 } | 1585 } |
| 1582 } | 1586 } |
| 1583 | 1587 |
| 1584 void | 1588 void |
| 1585 GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) | 1589 GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
| 1586 { | 1590 { |
| 1587 buffer->clear_positions (); | 1591 buffer->clear_positions (); |
| 1588 | 1592 |
| 1589 unsigned int count = buffer->len; | 1593 unsigned int count = buffer->len; |
| 1590 for (unsigned int i = 0; i < count; i++) | 1594 for (unsigned int i = 0; i < count; i++) |
| 1591 buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0; | 1595 buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0; |
| 1592 } | 1596 } |
| 1593 | 1597 |
| 1594 void | 1598 void |
| 1595 GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t
zero_width_attached_marks) | 1599 GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
| 1596 { | 1600 { |
| 1597 unsigned int len; | 1601 unsigned int len; |
| 1598 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); | 1602 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); |
| 1599 hb_direction_t direction = buffer->props.direction; | 1603 hb_direction_t direction = buffer->props.direction; |
| 1600 | 1604 |
| 1601 /* Handle cursive connections */ | 1605 /* Handle cursive connections */ |
| 1602 for (unsigned int i = 0; i < len; i++) | 1606 for (unsigned int i = 0; i < len; i++) |
| 1603 fix_cursive_minor_offset (pos, i, direction); | 1607 fix_cursive_minor_offset (pos, i, direction); |
| 1604 | 1608 |
| 1605 /* Handle attachments */ | 1609 /* Handle attachments */ |
| 1606 for (unsigned int i = 0; i < len; i++) | 1610 for (unsigned int i = 0; i < len; i++) |
| 1607 fix_mark_attachment (pos, i, direction, zero_width_attached_marks); | 1611 fix_mark_attachment (pos, i, direction); |
| 1608 | 1612 |
| 1609 HB_BUFFER_DEALLOCATE_VAR (buffer, syllable); | 1613 HB_BUFFER_DEALLOCATE_VAR (buffer, syllable); |
| 1610 HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props); | 1614 HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props); |
| 1611 HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props); | 1615 HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props); |
| 1612 } | 1616 } |
| 1613 | 1617 |
| 1614 | 1618 |
| 1615 /* Out-of-class implementation for methods recursing */ | 1619 /* Out-of-class implementation for methods recursing */ |
| 1616 | 1620 |
| 1617 template <typename context_t> | 1621 template <typename context_t> |
| 1618 inline typename context_t::return_t PosLookup::process_recurse_func (context_t *
c, unsigned int lookup_index) | 1622 inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t
*c, unsigned int lookup_index) |
| 1619 { | 1623 { |
| 1620 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); | 1624 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); |
| 1621 const PosLookup &l = gpos.get_lookup (lookup_index); | 1625 const PosLookup &l = gpos.get_lookup (lookup_index); |
| 1622 return l.process (c); | 1626 return l.dispatch (c); |
| 1623 } | 1627 } |
| 1624 | 1628 |
| 1625 inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int l
ookup_index) | 1629 inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int l
ookup_index) |
| 1626 { | 1630 { |
| 1627 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); | 1631 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); |
| 1628 const PosLookup &l = gpos.get_lookup (lookup_index); | 1632 const PosLookup &l = gpos.get_lookup (lookup_index); |
| 1629 unsigned int saved_lookup_props = c->lookup_props; | 1633 unsigned int saved_lookup_props = c->lookup_props; |
| 1630 unsigned int saved_property = c->property; | |
| 1631 c->set_lookup (l); | 1634 c->set_lookup (l); |
| 1632 bool ret = l.apply_once (c); | 1635 bool ret = l.apply_once (c); |
| 1633 c->lookup_props = saved_lookup_props; | 1636 c->lookup_props = saved_lookup_props; |
| 1634 c->property = saved_property; | |
| 1635 return ret; | 1637 return ret; |
| 1636 } | 1638 } |
| 1637 | 1639 |
| 1638 | 1640 |
| 1639 #undef attach_lookback | 1641 #undef attach_lookback |
| 1640 #undef cursive_chain | 1642 #undef cursive_chain |
| 1641 | 1643 |
| 1642 | 1644 |
| 1643 } /* namespace OT */ | 1645 } /* namespace OT */ |
| 1644 | 1646 |
| 1645 | 1647 |
| 1646 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ | 1648 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ |
| OLD | NEW |