diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 95e8fb84d..e4ea60e31 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -2170,18 +2170,18 @@ struct RuleSet ; } - /* This version is optimized for speed by matching the first component - * of the rule here, instead of calling into the matching code. + /* This version is optimized for speed by matching the first & second + * components of the rule here, instead of calling into the matching code. * * Replicated from LigatureSet::apply(). */ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; - skippy_iter.reset (c->buffer->idx, 1); + skippy_iter.reset (c->buffer->idx, 2); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); - unsigned unsafe_to; - hb_glyph_info_t *first = nullptr; - bool matched = skippy_iter.next (&unsafe_to); + unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0; + hb_glyph_info_t *first = nullptr, *second = nullptr; + bool matched = skippy_iter.next (); if (likely (matched)) { first = &c->buffer->info[skippy_iter.idx]; @@ -2207,6 +2207,12 @@ struct RuleSet ) ; } + matched = skippy_iter.next (); + if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))) + { + second = &c->buffer->info[skippy_iter.idx]; + unsafe_to2 = skippy_iter.idx + 1; + } bool unsafe_to_concat = false; @@ -2220,15 +2226,34 @@ struct RuleSet (!lookup_context.funcs.match || lookup_context.funcs.match (*first, input.arrayZ[0], lookup_context.match_data))) { - if (r.apply (c, lookup_context)) + if (!second || + (r.inputCount <= 2 || + (!lookup_context.funcs.match || + lookup_context.funcs.match (*second, input.arrayZ[1], lookup_context.match_data))) + ) { - if (unsafe_to_concat) - c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to); - return_trace (true); + if (r.apply (c, lookup_context)) + { + if (unsafe_to_concat) + c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to); + return_trace (true); + } + } + else + { + if (second) + { + unsafe_to_concat = true; + unsafe_to = unsafe_to2; + } } } else - unsafe_to_concat = true; + { + unsafe_to_concat = true; + if (unsafe_to == (unsigned) -1) + unsafe_to = unsafe_to1; + } } if (likely (unsafe_to_concat)) c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to); @@ -3324,22 +3349,22 @@ struct ChainRuleSet ; } - /* This version is optimized for speed by matching the first component - * of the rule here, instead of calling into the matching code. + /* This version is optimized for speed by matching the first & second + * components of the rule here, instead of calling into the matching code. * * Replicated from LigatureSet::apply(). */ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; - skippy_iter.reset (c->buffer->idx, 1); + skippy_iter.reset (c->buffer->idx, 2); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); - unsigned unsafe_to; - hb_glyph_info_t *first = nullptr; - bool matched = skippy_iter.next (&unsafe_to); + unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0; + hb_glyph_info_t *first = nullptr, *second = nullptr; + bool matched = skippy_iter.next (); if (likely (matched)) { first = &c->buffer->info[skippy_iter.idx]; - unsafe_to = skippy_iter.idx + 1; + unsafe_to1 = skippy_iter.idx + 1; if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) { @@ -3361,6 +3386,12 @@ struct ChainRuleSet ) ; } + matched = skippy_iter.next (); + if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))) + { + second = &c->buffer->info[skippy_iter.idx]; + unsafe_to2 = skippy_iter.idx + 1; + } bool unsafe_to_concat = false; @@ -3378,15 +3409,36 @@ struct ChainRuleSet (!lookahead.len || !lookup_context.funcs.match[2] || lookup_context.funcs.match[2] (*first, lookahead.arrayZ[0], lookup_context.match_data[2]))) { - if (r.apply (c, lookup_context)) + if (!second || + (input.lenP1 > 2 ? + (!lookup_context.funcs.match[1] || + lookup_context.funcs.match[1] (*second, input.arrayZ[1], lookup_context.match_data[1])) + : + (lookahead.len <= 2 - input.lenP1 || !lookup_context.funcs.match[2] || + lookup_context.funcs.match[2] (*second, lookahead.arrayZ[2 - input.lenP1], lookup_context.match_data[2])))) + { + if (r.apply (c, lookup_context)) + { + if (unsafe_to_concat) + c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to); + return_trace (true); + } + } + else { - if (unsafe_to_concat) - c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to); - return_trace (true); + if (second) + { + unsafe_to_concat = true; + unsafe_to = unsafe_to2; + } } } else - unsafe_to_concat = true; + { + unsafe_to_concat = true; + if (unsafe_to == (unsigned) -1) + unsafe_to = unsafe_to1; + } } if (likely (unsafe_to_concat)) c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);