279 |
279 |
280 /* Special-case to make it in-place and not consider this |
280 /* Special-case to make it in-place and not consider this |
281 * as a "multiplied" substitution. */ |
281 * as a "multiplied" substitution. */ |
282 if (unlikely (count == 1)) |
282 if (unlikely (count == 1)) |
283 { |
283 { |
284 c->replace_glyph (substitute.array[0]); |
284 c->replace_glyph (substitute.arrayZ[0]); |
285 return_trace (true); |
285 return_trace (true); |
286 } |
286 } |
287 /* Spec disallows this, but Uniscribe allows it. |
287 /* Spec disallows this, but Uniscribe allows it. |
288 * https://github.com/harfbuzz/harfbuzz/issues/253 */ |
288 * https://github.com/harfbuzz/harfbuzz/issues/253 */ |
289 else if (unlikely (count == 0)) |
289 else if (unlikely (count == 0)) |
295 unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? |
295 unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? |
296 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; |
296 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; |
297 |
297 |
298 for (unsigned int i = 0; i < count; i++) { |
298 for (unsigned int i = 0; i < count; i++) { |
299 _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); |
299 _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); |
300 c->output_glyph_for_component (substitute.array[i], klass); |
300 c->output_glyph_for_component (substitute.arrayZ[i], klass); |
301 } |
301 } |
302 c->buffer->skip_glyph (); |
302 c->buffer->skip_glyph (); |
303 |
303 |
304 return_trace (true); |
304 return_trace (true); |
305 } |
305 } |
478 for (iter.init (this+coverage); iter.more (); iter.next ()) |
478 for (iter.init (this+coverage); iter.more (); iter.next ()) |
479 { |
479 { |
480 if (unlikely (iter.get_coverage () >= count)) |
480 if (unlikely (iter.get_coverage () >= count)) |
481 break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ |
481 break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ |
482 const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()]; |
482 const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()]; |
483 c->output->add_array (alt_set.array, alt_set.len); |
483 c->output->add_array (alt_set.arrayZ, alt_set.len); |
484 } |
484 } |
485 } |
485 } |
486 |
486 |
487 inline const Coverage &get_coverage (void) const |
487 inline const Coverage &get_coverage (void) const |
488 { |
488 { |
609 } |
609 } |
610 |
610 |
611 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const |
611 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const |
612 { |
612 { |
613 TRACE_COLLECT_GLYPHS (this); |
613 TRACE_COLLECT_GLYPHS (this); |
614 c->input->add_array (component.array, component.len ? component.len - 1 : 0); |
614 c->input->add_array (component.arrayZ, component.len ? component.len - 1 : 0); |
615 c->output->add (ligGlyph); |
615 c->output->add (ligGlyph); |
616 } |
616 } |
617 |
617 |
618 inline bool would_apply (hb_would_apply_context_t *c) const |
618 inline bool would_apply (hb_would_apply_context_t *c) const |
619 { |
619 { |
977 for (unsigned int i = 0; i < count; i++) |
977 for (unsigned int i = 0; i < count; i++) |
978 if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return; |
978 if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return; |
979 |
979 |
980 const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); |
980 const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); |
981 count = substitute.len; |
981 count = substitute.len; |
982 c->output->add_array (substitute.array, substitute.len); |
982 c->output->add_array (substitute.arrayZ, substitute.len); |
983 } |
983 } |
984 |
984 |
985 inline const Coverage &get_coverage (void) const |
985 inline const Coverage &get_coverage (void) const |
986 { |
986 { |
987 return this+coverage; |
987 return this+coverage; |
1005 const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); |
1005 const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); |
1006 const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); |
1006 const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); |
1007 |
1007 |
1008 unsigned int start_index = 0, end_index = 0; |
1008 unsigned int start_index = 0, end_index = 0; |
1009 if (match_backtrack (c, |
1009 if (match_backtrack (c, |
1010 backtrack.len, (HBUINT16 *) backtrack.array, |
1010 backtrack.len, (HBUINT16 *) backtrack.arrayZ, |
1011 match_coverage, this, |
1011 match_coverage, this, |
1012 &start_index) && |
1012 &start_index) && |
1013 match_lookahead (c, |
1013 match_lookahead (c, |
1014 lookahead.len, (HBUINT16 *) lookahead.array, |
1014 lookahead.len, (HBUINT16 *) lookahead.arrayZ, |
1015 match_coverage, this, |
1015 match_coverage, this, |
1016 1, &end_index)) |
1016 1, &end_index)) |
1017 { |
1017 { |
1018 c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); |
1018 c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); |
1019 c->replace_glyph_inplace (substitute[index]); |
1019 c->replace_glyph_inplace (substitute[index]); |
1154 { |
1154 { |
1155 TRACE_APPLY (this); |
1155 TRACE_APPLY (this); |
1156 return_trace (dispatch (c)); |
1156 return_trace (dispatch (c)); |
1157 } |
1157 } |
1158 |
1158 |
1159 inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const |
1159 inline hb_closure_context_t::return_t closure (hb_closure_context_t *c, unsigned int this_index) const |
1160 { |
1160 { |
1161 TRACE_CLOSURE (this); |
1161 TRACE_CLOSURE (this); |
1162 c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>); |
1162 if (!c->should_visit_lookup (this_index)) |
|
1163 return_trace (HB_VOID); |
|
1164 |
|
1165 c->set_recurse_func (dispatch_closure_recurse_func); |
1163 return_trace (dispatch (c)); |
1166 return_trace (dispatch (c)); |
1164 } |
1167 } |
1165 |
1168 |
1166 inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const |
1169 inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const |
1167 { |
1170 { |
1255 component_list)); |
1258 component_list)); |
1256 } |
1259 } |
1257 |
1260 |
1258 template <typename context_t> |
1261 template <typename context_t> |
1259 static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); |
1262 static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); |
|
1263 |
|
1264 static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) |
|
1265 { |
|
1266 if (!c->should_visit_lookup (lookup_index)) |
|
1267 return HB_VOID; |
|
1268 return dispatch_recurse_func (c, lookup_index); |
|
1269 } |
1260 |
1270 |
1261 template <typename context_t> |
1271 template <typename context_t> |
1262 inline typename context_t::return_t dispatch (context_t *c) const |
1272 inline typename context_t::return_t dispatch (context_t *c) const |
1263 { return Lookup::dispatch<SubstLookupSubTable> (c); } |
1273 { return Lookup::dispatch<SubstLookupSubTable> (c); } |
1264 |
1274 |