394 return false; |
393 return false; |
395 } |
394 } |
396 |
395 |
397 unsigned int idx; |
396 unsigned int idx; |
398 protected: |
397 protected: |
399 hb_apply_context_t *c; |
398 hb_ot_apply_context_t *c; |
400 matcher_t matcher; |
399 matcher_t matcher; |
401 const USHORT *match_glyph_data; |
400 const HBUINT16 *match_glyph_data; |
402 |
401 |
403 unsigned int num_items; |
402 unsigned int num_items; |
404 unsigned int end; |
403 unsigned int end; |
405 }; |
404 }; |
406 |
405 |
407 |
406 |
408 inline const char *get_name (void) { return "APPLY"; } |
407 inline const char *get_name (void) { return "APPLY"; } |
409 typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); |
408 typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index); |
410 template <typename T> |
409 template <typename T> |
411 inline return_t dispatch (const T &obj) { return obj.apply (this); } |
410 inline return_t dispatch (const T &obj) { return obj.apply (this); } |
412 static return_t default_return_value (void) { return false; } |
411 static return_t default_return_value (void) { return false; } |
413 bool stop_sublookup_iteration (return_t r) const { return r; } |
412 bool stop_sublookup_iteration (return_t r) const { return r; } |
414 return_t recurse (unsigned int lookup_index) |
413 return_t recurse (unsigned int sub_lookup_index) |
415 { |
414 { |
416 if (unlikely (nesting_level_left == 0 || !recurse_func)) |
415 if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0)) |
417 return default_return_value (); |
416 return default_return_value (); |
418 |
417 |
419 nesting_level_left--; |
418 nesting_level_left--; |
420 bool ret = recurse_func (this, lookup_index); |
419 bool ret = recurse_func (this, sub_lookup_index); |
421 nesting_level_left++; |
420 nesting_level_left++; |
422 return ret; |
421 return ret; |
423 } |
422 } |
424 |
423 |
425 skipping_iterator_t iter_input, iter_context; |
424 skipping_iterator_t iter_input, iter_context; |
584 { |
583 { |
585 match_func_t match; |
584 match_func_t match; |
586 }; |
585 }; |
587 |
586 |
588 |
587 |
589 static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) |
588 static inline bool intersects_glyph (hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED) |
590 { |
589 { |
591 return glyphs->has (value); |
590 return glyphs->has (value); |
592 } |
591 } |
593 static inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, const void *data) |
592 static inline bool intersects_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data) |
594 { |
593 { |
595 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); |
594 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); |
596 return class_def.intersects_class (glyphs, value); |
595 return class_def.intersects_class (glyphs, value); |
597 } |
596 } |
598 static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) |
597 static inline bool intersects_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data) |
599 { |
598 { |
600 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; |
599 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; |
601 return (data+coverage).intersects (glyphs); |
600 return (data+coverage).intersects (glyphs); |
602 } |
601 } |
603 |
602 |
604 static inline bool intersects_array (hb_closure_context_t *c, |
603 static inline bool intersects_array (hb_closure_context_t *c, |
605 unsigned int count, |
604 unsigned int count, |
606 const USHORT values[], |
605 const HBUINT16 values[], |
607 intersects_func_t intersects_func, |
606 intersects_func_t intersects_func, |
608 const void *intersects_data) |
607 const void *intersects_data) |
609 { |
608 { |
610 for (unsigned int i = 0; i < count; i++) |
609 for (unsigned int i = 0; i < count; i++) |
611 if (likely (!intersects_func (c->glyphs, values[i], intersects_data))) |
610 if (likely (!intersects_func (c->glyphs, values[i], intersects_data))) |
612 return false; |
611 return false; |
613 return true; |
612 return true; |
614 } |
613 } |
615 |
614 |
616 |
615 |
617 static inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) |
616 static inline void collect_glyph (hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED) |
618 { |
617 { |
619 glyphs->add (value); |
618 glyphs->add (value); |
620 } |
619 } |
621 static inline void collect_class (hb_set_t *glyphs, const USHORT &value, const void *data) |
620 static inline void collect_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data) |
622 { |
621 { |
623 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); |
622 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); |
624 class_def.add_class (glyphs, value); |
623 class_def.add_class (glyphs, value); |
625 } |
624 } |
626 static inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) |
625 static inline void collect_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data) |
627 { |
626 { |
628 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; |
627 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; |
629 (data+coverage).add_coverage (glyphs); |
628 (data+coverage).add_coverage (glyphs); |
630 } |
629 } |
631 static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, |
630 static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, |
632 hb_set_t *glyphs, |
631 hb_set_t *glyphs, |
633 unsigned int count, |
632 unsigned int count, |
634 const USHORT values[], |
633 const HBUINT16 values[], |
635 collect_glyphs_func_t collect_func, |
634 collect_glyphs_func_t collect_func, |
636 const void *collect_data) |
635 const void *collect_data) |
637 { |
636 { |
638 for (unsigned int i = 0; i < count; i++) |
637 for (unsigned int i = 0; i < count; i++) |
639 collect_func (glyphs, values[i], collect_data); |
638 collect_func (glyphs, values[i], collect_data); |
640 } |
639 } |
641 |
640 |
642 |
641 |
643 static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED) |
642 static inline bool match_glyph (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data HB_UNUSED) |
644 { |
643 { |
645 return glyph_id == value; |
644 return glyph_id == value; |
646 } |
645 } |
647 static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data) |
646 static inline bool match_class (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data) |
648 { |
647 { |
649 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); |
648 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); |
650 return class_def.get_class (glyph_id) == value; |
649 return class_def.get_class (glyph_id) == value; |
651 } |
650 } |
652 static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, const void *data) |
651 static inline bool match_coverage (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data) |
653 { |
652 { |
654 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; |
653 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; |
655 return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; |
654 return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; |
656 } |
655 } |
657 |
656 |
658 static inline bool would_match_input (hb_would_apply_context_t *c, |
657 static inline bool would_match_input (hb_would_apply_context_t *c, |
659 unsigned int count, /* Including the first glyph (not matched) */ |
658 unsigned int count, /* Including the first glyph (not matched) */ |
660 const USHORT input[], /* Array of input values--start with second glyph */ |
659 const HBUINT16 input[], /* Array of input values--start with second glyph */ |
661 match_func_t match_func, |
660 match_func_t match_func, |
662 const void *match_data) |
661 const void *match_data) |
663 { |
662 { |
664 if (count != c->len) |
663 if (count != c->len) |
665 return false; |
664 return false; |
668 if (likely (!match_func (c->glyphs[i], input[i - 1], match_data))) |
667 if (likely (!match_func (c->glyphs[i], input[i - 1], match_data))) |
669 return false; |
668 return false; |
670 |
669 |
671 return true; |
670 return true; |
672 } |
671 } |
673 static inline bool match_input (hb_apply_context_t *c, |
672 static inline bool match_input (hb_ot_apply_context_t *c, |
674 unsigned int count, /* Including the first glyph (not matched) */ |
673 unsigned int count, /* Including the first glyph (not matched) */ |
675 const USHORT input[], /* Array of input values--start with second glyph */ |
674 const HBUINT16 input[], /* Array of input values--start with second glyph */ |
676 match_func_t match_func, |
675 match_func_t match_func, |
677 const void *match_data, |
676 const void *match_data, |
678 unsigned int *end_offset, |
677 unsigned int *end_offset, |
679 unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], |
678 unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], |
680 bool *p_is_mark_ligature = nullptr, |
679 bool *p_is_mark_ligature = nullptr, |
892 } |
891 } |
893 } |
892 } |
894 return_trace (true); |
893 return_trace (true); |
895 } |
894 } |
896 |
895 |
897 static inline bool match_backtrack (hb_apply_context_t *c, |
896 static inline bool match_backtrack (hb_ot_apply_context_t *c, |
898 unsigned int count, |
897 unsigned int count, |
899 const USHORT backtrack[], |
898 const HBUINT16 backtrack[], |
900 match_func_t match_func, |
899 match_func_t match_func, |
901 const void *match_data, |
900 const void *match_data, |
902 unsigned int *match_start) |
901 unsigned int *match_start) |
903 { |
902 { |
904 TRACE_APPLY (nullptr); |
903 TRACE_APPLY (nullptr); |
905 |
904 |
906 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; |
905 hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; |
907 skippy_iter.reset (c->buffer->backtrack_len (), count); |
906 skippy_iter.reset (c->buffer->backtrack_len (), count); |
908 skippy_iter.set_match_func (match_func, match_data, backtrack); |
907 skippy_iter.set_match_func (match_func, match_data, backtrack); |
909 |
908 |
910 for (unsigned int i = 0; i < count; i++) |
909 for (unsigned int i = 0; i < count; i++) |
911 if (!skippy_iter.prev ()) |
910 if (!skippy_iter.prev ()) |
914 *match_start = skippy_iter.idx; |
913 *match_start = skippy_iter.idx; |
915 |
914 |
916 return_trace (true); |
915 return_trace (true); |
917 } |
916 } |
918 |
917 |
919 static inline bool match_lookahead (hb_apply_context_t *c, |
918 static inline bool match_lookahead (hb_ot_apply_context_t *c, |
920 unsigned int count, |
919 unsigned int count, |
921 const USHORT lookahead[], |
920 const HBUINT16 lookahead[], |
922 match_func_t match_func, |
921 match_func_t match_func, |
923 const void *match_data, |
922 const void *match_data, |
924 unsigned int offset, |
923 unsigned int offset, |
925 unsigned int *end_index) |
924 unsigned int *end_index) |
926 { |
925 { |
927 TRACE_APPLY (nullptr); |
926 TRACE_APPLY (nullptr); |
928 |
927 |
929 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; |
928 hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; |
930 skippy_iter.reset (c->buffer->idx + offset - 1, count); |
929 skippy_iter.reset (c->buffer->idx + offset - 1, count); |
931 skippy_iter.set_match_func (match_func, match_data, lookahead); |
930 skippy_iter.set_match_func (match_func, match_data, lookahead); |
932 |
931 |
933 for (unsigned int i = 0; i < count; i++) |
932 for (unsigned int i = 0; i < count; i++) |
934 if (!skippy_iter.next ()) |
933 if (!skippy_iter.next ()) |
1134 lookupCount, lookupRecord); |
1137 lookupCount, lookupRecord); |
1135 } |
1138 } |
1136 |
1139 |
1137 static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, |
1140 static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, |
1138 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1141 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1139 const USHORT input[], /* Array of input values--start with second glyph */ |
1142 const HBUINT16 input[], /* Array of input values--start with second glyph */ |
1140 unsigned int lookupCount HB_UNUSED, |
1143 unsigned int lookupCount HB_UNUSED, |
1141 const LookupRecord lookupRecord[] HB_UNUSED, |
1144 const LookupRecord lookupRecord[] HB_UNUSED, |
1142 ContextApplyLookupContext &lookup_context) |
1145 ContextApplyLookupContext &lookup_context) |
1143 { |
1146 { |
1144 return would_match_input (c, |
1147 return would_match_input (c, |
1145 inputCount, input, |
1148 inputCount, input, |
1146 lookup_context.funcs.match, lookup_context.match_data); |
1149 lookup_context.funcs.match, lookup_context.match_data); |
1147 } |
1150 } |
1148 static inline bool context_apply_lookup (hb_apply_context_t *c, |
1151 static inline bool context_apply_lookup (hb_ot_apply_context_t *c, |
1149 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1152 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1150 const USHORT input[], /* Array of input values--start with second glyph */ |
1153 const HBUINT16 input[], /* Array of input values--start with second glyph */ |
1151 unsigned int lookupCount, |
1154 unsigned int lookupCount, |
1152 const LookupRecord lookupRecord[], |
1155 const LookupRecord lookupRecord[], |
1153 ContextApplyLookupContext &lookup_context) |
1156 ContextApplyLookupContext &lookup_context) |
1154 { |
1157 { |
1155 unsigned int match_length = 0; |
1158 unsigned int match_length = 0; |
1192 TRACE_WOULD_APPLY (this); |
1195 TRACE_WOULD_APPLY (this); |
1193 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); |
1196 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); |
1194 return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); |
1197 return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); |
1195 } |
1198 } |
1196 |
1199 |
1197 inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const |
1200 inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const |
1198 { |
1201 { |
1199 TRACE_APPLY (this); |
1202 TRACE_APPLY (this); |
1200 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); |
1203 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); |
1201 return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); |
1204 return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); |
1202 } |
1205 } |
1207 TRACE_SANITIZE (this); |
1210 TRACE_SANITIZE (this); |
1208 return_trace (inputCount.sanitize (c) && |
1211 return_trace (inputCount.sanitize (c) && |
1209 lookupCount.sanitize (c) && |
1212 lookupCount.sanitize (c) && |
1210 c->check_range (inputZ, |
1213 c->check_range (inputZ, |
1211 inputZ[0].static_size * inputCount + |
1214 inputZ[0].static_size * inputCount + |
1212 lookupRecordX[0].static_size * lookupCount)); |
1215 LookupRecord::static_size * lookupCount)); |
1213 } |
1216 } |
1214 |
1217 |
1215 protected: |
1218 protected: |
1216 USHORT inputCount; /* Total number of glyphs in input |
1219 HBUINT16 inputCount; /* Total number of glyphs in input |
1217 * glyph sequence--includes the first |
1220 * glyph sequence--includes the first |
1218 * glyph */ |
1221 * glyph */ |
1219 USHORT lookupCount; /* Number of LookupRecords */ |
1222 HBUINT16 lookupCount; /* Number of LookupRecords */ |
1220 USHORT inputZ[VAR]; /* Array of match inputs--start with |
1223 HBUINT16 inputZ[VAR]; /* Array of match inputs--start with |
1221 * second glyph */ |
1224 * second glyph */ |
1222 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in |
1225 /*LookupRecord lookupRecordX[VAR];*/ /* Array of LookupRecords--in |
1223 * design order */ |
1226 * design order */ |
1224 public: |
1227 public: |
1225 DEFINE_SIZE_ARRAY2 (4, inputZ, lookupRecordX); |
1228 DEFINE_SIZE_ARRAY (4, inputZ); |
1226 }; |
1229 }; |
1227 |
1230 |
1228 struct RuleSet |
1231 struct RuleSet |
1229 { |
1232 { |
1230 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const |
1233 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const |
1508 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); |
1511 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); |
1509 struct ContextApplyLookupContext lookup_context = { |
1512 struct ContextApplyLookupContext lookup_context = { |
1510 {match_coverage}, |
1513 {match_coverage}, |
1511 this |
1514 this |
1512 }; |
1515 }; |
1513 return_trace (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); |
1516 return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); |
1514 } |
1517 } |
1515 |
1518 |
1516 inline const Coverage &get_coverage (void) const |
1519 inline const Coverage &get_coverage (void) const |
1517 { |
1520 { |
1518 return this+coverageZ[0]; |
1521 return this+coverageZ[0]; |
1519 } |
1522 } |
1520 |
1523 |
1521 inline bool apply (hb_apply_context_t *c) const |
1524 inline bool apply (hb_ot_apply_context_t *c) const |
1522 { |
1525 { |
1523 TRACE_APPLY (this); |
1526 TRACE_APPLY (this); |
1524 unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); |
1527 unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); |
1525 if (likely (index == NOT_COVERED)) return_trace (false); |
1528 if (likely (index == NOT_COVERED)) return_trace (false); |
1526 |
1529 |
1527 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); |
1530 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); |
1528 struct ContextApplyLookupContext lookup_context = { |
1531 struct ContextApplyLookupContext lookup_context = { |
1529 {match_coverage}, |
1532 {match_coverage}, |
1530 this |
1533 this |
1531 }; |
1534 }; |
1532 return_trace (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); |
1535 return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); |
1533 } |
1536 } |
1534 |
1537 |
1535 inline bool sanitize (hb_sanitize_context_t *c) const |
1538 inline bool sanitize (hb_sanitize_context_t *c) const |
1536 { |
1539 { |
1537 TRACE_SANITIZE (this); |
1540 TRACE_SANITIZE (this); |
1544 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); |
1547 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); |
1545 return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); |
1548 return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); |
1546 } |
1549 } |
1547 |
1550 |
1548 protected: |
1551 protected: |
1549 USHORT format; /* Format identifier--format = 3 */ |
1552 HBUINT16 format; /* Format identifier--format = 3 */ |
1550 USHORT glyphCount; /* Number of glyphs in the input glyph |
1553 HBUINT16 glyphCount; /* Number of glyphs in the input glyph |
1551 * sequence */ |
1554 * sequence */ |
1552 USHORT lookupCount; /* Number of LookupRecords */ |
1555 HBUINT16 lookupCount; /* Number of LookupRecords */ |
1553 OffsetTo<Coverage> |
1556 OffsetTo<Coverage> |
1554 coverageZ[VAR]; /* Array of offsets to Coverage |
1557 coverageZ[VAR]; /* Array of offsets to Coverage |
1555 * table in glyph sequence order */ |
1558 * table in glyph sequence order */ |
1556 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in |
1559 /*LookupRecord lookupRecordX[VAR];*/ /* Array of LookupRecords--in |
1557 * design order */ |
1560 * design order */ |
1558 public: |
1561 public: |
1559 DEFINE_SIZE_ARRAY2 (6, coverageZ, lookupRecordX); |
1562 DEFINE_SIZE_ARRAY (6, coverageZ); |
1560 }; |
1563 }; |
1561 |
1564 |
1562 struct Context |
1565 struct Context |
1563 { |
1566 { |
1564 template <typename context_t> |
1567 template <typename context_t> |
1604 const void *match_data[3]; |
1607 const void *match_data[3]; |
1605 }; |
1608 }; |
1606 |
1609 |
1607 static inline void chain_context_closure_lookup (hb_closure_context_t *c, |
1610 static inline void chain_context_closure_lookup (hb_closure_context_t *c, |
1608 unsigned int backtrackCount, |
1611 unsigned int backtrackCount, |
1609 const USHORT backtrack[], |
1612 const HBUINT16 backtrack[], |
1610 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1613 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1611 const USHORT input[], /* Array of input values--start with second glyph */ |
1614 const HBUINT16 input[], /* Array of input values--start with second glyph */ |
1612 unsigned int lookaheadCount, |
1615 unsigned int lookaheadCount, |
1613 const USHORT lookahead[], |
1616 const HBUINT16 lookahead[], |
1614 unsigned int lookupCount, |
1617 unsigned int lookupCount, |
1615 const LookupRecord lookupRecord[], |
1618 const LookupRecord lookupRecord[], |
1616 ChainContextClosureLookupContext &lookup_context) |
1619 ChainContextClosureLookupContext &lookup_context) |
1617 { |
1620 { |
1618 if (intersects_array (c, |
1621 if (intersects_array (c, |
1628 lookupCount, lookupRecord); |
1631 lookupCount, lookupRecord); |
1629 } |
1632 } |
1630 |
1633 |
1631 static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, |
1634 static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, |
1632 unsigned int backtrackCount, |
1635 unsigned int backtrackCount, |
1633 const USHORT backtrack[], |
1636 const HBUINT16 backtrack[], |
1634 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1637 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1635 const USHORT input[], /* Array of input values--start with second glyph */ |
1638 const HBUINT16 input[], /* Array of input values--start with second glyph */ |
1636 unsigned int lookaheadCount, |
1639 unsigned int lookaheadCount, |
1637 const USHORT lookahead[], |
1640 const HBUINT16 lookahead[], |
1638 unsigned int lookupCount, |
1641 unsigned int lookupCount, |
1639 const LookupRecord lookupRecord[], |
1642 const LookupRecord lookupRecord[], |
1640 ChainContextCollectGlyphsLookupContext &lookup_context) |
1643 ChainContextCollectGlyphsLookupContext &lookup_context) |
1641 { |
1644 { |
1642 collect_array (c, c->before, |
1645 collect_array (c, c->before, |
1652 lookupCount, lookupRecord); |
1655 lookupCount, lookupRecord); |
1653 } |
1656 } |
1654 |
1657 |
1655 static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c, |
1658 static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c, |
1656 unsigned int backtrackCount, |
1659 unsigned int backtrackCount, |
1657 const USHORT backtrack[] HB_UNUSED, |
1660 const HBUINT16 backtrack[] HB_UNUSED, |
1658 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1661 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1659 const USHORT input[], /* Array of input values--start with second glyph */ |
1662 const HBUINT16 input[], /* Array of input values--start with second glyph */ |
1660 unsigned int lookaheadCount, |
1663 unsigned int lookaheadCount, |
1661 const USHORT lookahead[] HB_UNUSED, |
1664 const HBUINT16 lookahead[] HB_UNUSED, |
1662 unsigned int lookupCount HB_UNUSED, |
1665 unsigned int lookupCount HB_UNUSED, |
1663 const LookupRecord lookupRecord[] HB_UNUSED, |
1666 const LookupRecord lookupRecord[] HB_UNUSED, |
1664 ChainContextApplyLookupContext &lookup_context) |
1667 ChainContextApplyLookupContext &lookup_context) |
1665 { |
1668 { |
1666 return (c->zero_context ? !backtrackCount && !lookaheadCount : true) |
1669 return (c->zero_context ? !backtrackCount && !lookaheadCount : true) |
1667 && would_match_input (c, |
1670 && would_match_input (c, |
1668 inputCount, input, |
1671 inputCount, input, |
1669 lookup_context.funcs.match, lookup_context.match_data[1]); |
1672 lookup_context.funcs.match, lookup_context.match_data[1]); |
1670 } |
1673 } |
1671 |
1674 |
1672 static inline bool chain_context_apply_lookup (hb_apply_context_t *c, |
1675 static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, |
1673 unsigned int backtrackCount, |
1676 unsigned int backtrackCount, |
1674 const USHORT backtrack[], |
1677 const HBUINT16 backtrack[], |
1675 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1678 unsigned int inputCount, /* Including the first glyph (not matched) */ |
1676 const USHORT input[], /* Array of input values--start with second glyph */ |
1679 const HBUINT16 input[], /* Array of input values--start with second glyph */ |
1677 unsigned int lookaheadCount, |
1680 unsigned int lookaheadCount, |
1678 const USHORT lookahead[], |
1681 const HBUINT16 lookahead[], |
1679 unsigned int lookupCount, |
1682 unsigned int lookupCount, |
1680 const LookupRecord lookupRecord[], |
1683 const LookupRecord lookupRecord[], |
1681 ChainContextApplyLookupContext &lookup_context) |
1684 ChainContextApplyLookupContext &lookup_context) |
1682 { |
1685 { |
1683 unsigned int start_index = 0, match_length = 0, end_index = 0; |
1686 unsigned int start_index = 0, match_length = 0, end_index = 0; |
1704 struct ChainRule |
1707 struct ChainRule |
1705 { |
1708 { |
1706 inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const |
1709 inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const |
1707 { |
1710 { |
1708 TRACE_CLOSURE (this); |
1711 TRACE_CLOSURE (this); |
1709 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); |
1712 const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack); |
1710 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
1713 const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); |
1711 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); |
1714 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); |
1712 chain_context_closure_lookup (c, |
1715 chain_context_closure_lookup (c, |
1713 backtrack.len, backtrack.array, |
1716 backtrack.len, backtrack.array, |
1714 input.len, input.array, |
1717 input.len, input.array, |
1715 lookahead.len, lookahead.array, |
1718 lookahead.len, lookahead.array, |
1718 } |
1721 } |
1719 |
1722 |
1720 inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const |
1723 inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const |
1721 { |
1724 { |
1722 TRACE_COLLECT_GLYPHS (this); |
1725 TRACE_COLLECT_GLYPHS (this); |
1723 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); |
1726 const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack); |
1724 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
1727 const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); |
1725 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); |
1728 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); |
1726 chain_context_collect_glyphs_lookup (c, |
1729 chain_context_collect_glyphs_lookup (c, |
1727 backtrack.len, backtrack.array, |
1730 backtrack.len, backtrack.array, |
1728 input.len, input.array, |
1731 input.len, input.array, |
1729 lookahead.len, lookahead.array, |
1732 lookahead.len, lookahead.array, |
1732 } |
1735 } |
1733 |
1736 |
1734 inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const |
1737 inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const |
1735 { |
1738 { |
1736 TRACE_WOULD_APPLY (this); |
1739 TRACE_WOULD_APPLY (this); |
1737 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); |
1740 const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack); |
1738 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
1741 const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); |
1739 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); |
1742 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); |
1740 return_trace (chain_context_would_apply_lookup (c, |
1743 return_trace (chain_context_would_apply_lookup (c, |
1741 backtrack.len, backtrack.array, |
1744 backtrack.len, backtrack.array, |
1742 input.len, input.array, |
1745 input.len, input.array, |
1743 lookahead.len, lookahead.array, lookup.len, |
1746 lookahead.len, lookahead.array, lookup.len, |
1744 lookup.array, lookup_context)); |
1747 lookup.array, lookup_context)); |
1745 } |
1748 } |
1746 |
1749 |
1747 inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const |
1750 inline bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const |
1748 { |
1751 { |
1749 TRACE_APPLY (this); |
1752 TRACE_APPLY (this); |
1750 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); |
1753 const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack); |
1751 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
1754 const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); |
1752 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); |
1755 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); |
1753 return_trace (chain_context_apply_lookup (c, |
1756 return_trace (chain_context_apply_lookup (c, |
1754 backtrack.len, backtrack.array, |
1757 backtrack.len, backtrack.array, |
1755 input.len, input.array, |
1758 input.len, input.array, |
1756 lookahead.len, lookahead.array, lookup.len, |
1759 lookahead.len, lookahead.array, lookup.len, |
1759 |
1762 |
1760 inline bool sanitize (hb_sanitize_context_t *c) const |
1763 inline bool sanitize (hb_sanitize_context_t *c) const |
1761 { |
1764 { |
1762 TRACE_SANITIZE (this); |
1765 TRACE_SANITIZE (this); |
1763 if (!backtrack.sanitize (c)) return_trace (false); |
1766 if (!backtrack.sanitize (c)) return_trace (false); |
1764 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); |
1767 const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack); |
1765 if (!input.sanitize (c)) return_trace (false); |
1768 if (!input.sanitize (c)) return_trace (false); |
1766 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
1769 const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); |
1767 if (!lookahead.sanitize (c)) return_trace (false); |
1770 if (!lookahead.sanitize (c)) return_trace (false); |
1768 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); |
1771 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); |
1769 return_trace (lookup.sanitize (c)); |
1772 return_trace (lookup.sanitize (c)); |
1770 } |
1773 } |
1771 |
1774 |
1772 protected: |
1775 protected: |
1773 ArrayOf<USHORT> |
1776 ArrayOf<HBUINT16> |
1774 backtrack; /* Array of backtracking values |
1777 backtrack; /* Array of backtracking values |
1775 * (to be matched before the input |
1778 * (to be matched before the input |
1776 * sequence) */ |
1779 * sequence) */ |
1777 HeadlessArrayOf<USHORT> |
1780 HeadlessArrayOf<HBUINT16> |
1778 inputX; /* Array of input values (start with |
1781 inputX; /* Array of input values (start with |
1779 * second glyph) */ |
1782 * second glyph) */ |
1780 ArrayOf<USHORT> |
1783 ArrayOf<HBUINT16> |
1781 lookaheadX; /* Array of lookahead values's (to be |
1784 lookaheadX; /* Array of lookahead values's (to be |
1782 * matched after the input sequence) */ |
1785 * matched after the input sequence) */ |
1783 ArrayOf<LookupRecord> |
1786 ArrayOf<LookupRecord> |
1784 lookupX; /* Array of LookupRecords--in |
1787 lookupX; /* Array of LookupRecords--in |
1785 * design order) */ |
1788 * design order) */ |
2067 struct ChainContextClosureLookupContext lookup_context = { |
2070 struct ChainContextClosureLookupContext lookup_context = { |
2068 {intersects_coverage}, |
2071 {intersects_coverage}, |
2069 {this, this, this} |
2072 {this, this, this} |
2070 }; |
2073 }; |
2071 chain_context_closure_lookup (c, |
2074 chain_context_closure_lookup (c, |
2072 backtrack.len, (const USHORT *) backtrack.array, |
2075 backtrack.len, (const HBUINT16 *) backtrack.array, |
2073 input.len, (const USHORT *) input.array + 1, |
2076 input.len, (const HBUINT16 *) input.array + 1, |
2074 lookahead.len, (const USHORT *) lookahead.array, |
2077 lookahead.len, (const HBUINT16 *) lookahead.array, |
2075 lookup.len, lookup.array, |
2078 lookup.len, lookup.array, |
2076 lookup_context); |
2079 lookup_context); |
2077 } |
2080 } |
2078 |
2081 |
2079 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const |
2082 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const |
2107 struct ChainContextApplyLookupContext lookup_context = { |
2110 struct ChainContextApplyLookupContext lookup_context = { |
2108 {match_coverage}, |
2111 {match_coverage}, |
2109 {this, this, this} |
2112 {this, this, this} |
2110 }; |
2113 }; |
2111 return_trace (chain_context_would_apply_lookup (c, |
2114 return_trace (chain_context_would_apply_lookup (c, |
2112 backtrack.len, (const USHORT *) backtrack.array, |
2115 backtrack.len, (const HBUINT16 *) backtrack.array, |
2113 input.len, (const USHORT *) input.array + 1, |
2116 input.len, (const HBUINT16 *) input.array + 1, |
2114 lookahead.len, (const USHORT *) lookahead.array, |
2117 lookahead.len, (const HBUINT16 *) lookahead.array, |
2115 lookup.len, lookup.array, lookup_context)); |
2118 lookup.len, lookup.array, lookup_context)); |
2116 } |
2119 } |
2117 |
2120 |
2118 inline const Coverage &get_coverage (void) const |
2121 inline const Coverage &get_coverage (void) const |
2119 { |
2122 { |
2120 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); |
2123 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); |
2121 return this+input[0]; |
2124 return this+input[0]; |
2122 } |
2125 } |
2123 |
2126 |
2124 inline bool apply (hb_apply_context_t *c) const |
2127 inline bool apply (hb_ot_apply_context_t *c) const |
2125 { |
2128 { |
2126 TRACE_APPLY (this); |
2129 TRACE_APPLY (this); |
2127 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); |
2130 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); |
2128 |
2131 |
2129 unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); |
2132 unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); |
2224 |
2227 |
2225 /* This is called from may_dispatch() above with hb_sanitize_context_t. */ |
2228 /* This is called from may_dispatch() above with hb_sanitize_context_t. */ |
2226 inline bool sanitize (hb_sanitize_context_t *c) const |
2229 inline bool sanitize (hb_sanitize_context_t *c) const |
2227 { |
2230 { |
2228 TRACE_SANITIZE (this); |
2231 TRACE_SANITIZE (this); |
2229 return_trace (c->check_struct (this) && extensionOffset != 0); |
2232 return_trace (c->check_struct (this) && |
|
2233 extensionOffset != 0 && |
|
2234 extensionLookupType != T::LookupSubTable::Extension); |
2230 } |
2235 } |
2231 |
2236 |
2232 protected: |
2237 protected: |
2233 USHORT format; /* Format identifier. Set to 1. */ |
2238 HBUINT16 format; /* Format identifier. Set to 1. */ |
2234 USHORT extensionLookupType; /* Lookup type of subtable referenced |
2239 HBUINT16 extensionLookupType; /* Lookup type of subtable referenced |
2235 * by ExtensionOffset (i.e. the |
2240 * by ExtensionOffset (i.e. the |
2236 * extension subtable). */ |
2241 * extension subtable). */ |
2237 ULONG extensionOffset; /* Offset to the extension subtable, |
2242 HBUINT32 extensionOffset; /* Offset to the extension subtable, |
2238 * of lookup type subtable. */ |
2243 * of lookup type subtable. */ |
2239 public: |
2244 public: |
2240 DEFINE_SIZE_STATIC (8); |
2245 DEFINE_SIZE_STATIC (8); |
2241 }; |
2246 }; |
2242 |
2247 |