[gsubgpos] Also match second component in (Chain)RuleSet::apply()

Another 40% speedup in shaping Gulzar-Regular.
pull/4337/head
Behdad Esfahbod 2 years ago
parent 02b00d7743
commit b5de54e1d4
  1. 98
      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);

Loading…
Cancel
Save