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 |