mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-13 08:42:59 +00:00
[aat] For short words, use buffer digest to skip morx subtables
Shows 3 / 4% speedup in en-words test case with Helvetica Neue.
This commit is contained in:
parent
687c218fcb
commit
3ff9ebc868
2 changed files with 40 additions and 0 deletions
|
@ -60,6 +60,7 @@ struct hb_aat_apply_context_t :
|
|||
const ankr *ankr_table;
|
||||
const OT::GDEF *gdef_table;
|
||||
const hb_sorted_vector_t<hb_aat_map_t::range_flags_t> *range_flags = nullptr;
|
||||
hb_set_digest_t buffer_digest = hb_set_digest_t::full ();
|
||||
hb_set_digest_t machine_glyph_set = hb_set_digest_t::full ();
|
||||
hb_set_digest_t left_set = hb_set_digest_t::full ();
|
||||
hb_set_digest_t right_set = hb_set_digest_t::full ();
|
||||
|
@ -927,6 +928,14 @@ struct StateTableDriver
|
|||
machine (machine_),
|
||||
num_glyphs (face_->get_num_glyphs ()) {}
|
||||
|
||||
template <typename context_t>
|
||||
bool is_idempotent_on_all_out_of_bounds (context_t *c, hb_aat_apply_context_t *ac)
|
||||
{
|
||||
const auto entry = machine.get_entry (StateTableT::STATE_START_OF_TEXT, CLASS_OUT_OF_BOUNDS);
|
||||
return !c->is_actionable (ac->buffer, this, entry) &&
|
||||
machine.new_state (entry.newState) == StateTableT::STATE_START_OF_TEXT;
|
||||
}
|
||||
|
||||
template <typename context_t, typename set_t = hb_set_digest_t>
|
||||
void drive (context_t *c, hb_aat_apply_context_t *ac)
|
||||
{
|
||||
|
|
|
@ -170,6 +170,11 @@ struct RearrangementSubtable
|
|||
driver_context_t dc (this);
|
||||
|
||||
StateTableDriver<Types, EntryData> driver (machine, c->face);
|
||||
|
||||
if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) &&
|
||||
!c->buffer_digest.may_have (c->machine_glyph_set))
|
||||
return_trace (false);
|
||||
|
||||
driver.drive (&dc, c);
|
||||
|
||||
return_trace (dc.ret);
|
||||
|
@ -267,6 +272,7 @@ struct ContextualSubtable
|
|||
{
|
||||
buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len));
|
||||
buffer->info[mark].codepoint = *replacement;
|
||||
c->buffer_digest.add (*replacement);
|
||||
if (has_glyph_classes)
|
||||
_hb_glyph_info_set_glyph_props (&buffer->info[mark],
|
||||
gdef.get_glyph_props (*replacement));
|
||||
|
@ -296,6 +302,7 @@ struct ContextualSubtable
|
|||
if (replacement)
|
||||
{
|
||||
buffer->info[idx].codepoint = *replacement;
|
||||
c->buffer_digest.add (*replacement);
|
||||
if (has_glyph_classes)
|
||||
_hb_glyph_info_set_glyph_props (&buffer->info[idx],
|
||||
gdef.get_glyph_props (*replacement));
|
||||
|
@ -328,6 +335,11 @@ struct ContextualSubtable
|
|||
driver_context_t dc (this, c);
|
||||
|
||||
StateTableDriver<Types, EntryData> driver (machine, c->face);
|
||||
|
||||
if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) &&
|
||||
!c->buffer_digest.may_have (c->machine_glyph_set))
|
||||
return_trace (false);
|
||||
|
||||
driver.drive (&dc, c);
|
||||
|
||||
return_trace (dc.ret);
|
||||
|
@ -586,6 +598,11 @@ struct LigatureSubtable
|
|||
driver_context_t dc (this, c);
|
||||
|
||||
StateTableDriver<Types, EntryData> driver (machine, c->face);
|
||||
|
||||
if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) &&
|
||||
!c->buffer_digest.may_have (c->machine_glyph_set))
|
||||
return_trace (false);
|
||||
|
||||
driver.drive (&dc, c);
|
||||
|
||||
return_trace (dc.ret);
|
||||
|
@ -654,6 +671,7 @@ struct NoncontextualSubtable
|
|||
if (replacement)
|
||||
{
|
||||
info[i].codepoint = *replacement;
|
||||
c->buffer_digest.add (*replacement);
|
||||
if (has_glyph_classes)
|
||||
_hb_glyph_info_set_glyph_props (&info[i],
|
||||
gdef.get_glyph_props (*replacement));
|
||||
|
@ -788,6 +806,9 @@ struct InsertionSubtable
|
|||
if (unlikely (!buffer->copy_glyph ())) return;
|
||||
/* TODO We ignore KashidaLike setting. */
|
||||
if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
c->buffer_digest.add (glyphs[i]);
|
||||
ret = true;
|
||||
if (buffer->idx < buffer->len && !before)
|
||||
buffer->skip_glyph ();
|
||||
|
||||
|
@ -853,6 +874,11 @@ struct InsertionSubtable
|
|||
driver_context_t dc (this, c);
|
||||
|
||||
StateTableDriver<Types, EntryData> driver (machine, c->face);
|
||||
|
||||
if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) &&
|
||||
!c->buffer_digest.may_have (c->machine_glyph_set))
|
||||
return_trace (false);
|
||||
|
||||
driver.drive (&dc, c);
|
||||
|
||||
return_trace (dc.ret);
|
||||
|
@ -1348,6 +1374,11 @@ struct mortmorx
|
|||
|
||||
c->buffer->unsafe_to_concat ();
|
||||
|
||||
if (c->buffer->len < 16)
|
||||
c->buffer_digest = c->buffer->digest ();
|
||||
else
|
||||
c->buffer_digest = hb_set_digest_t::full ();
|
||||
|
||||
c->set_lookup_index (0);
|
||||
const Chain<Types> *chain = &firstChain;
|
||||
unsigned int count = chainCount;
|
||||
|
|
Loading…
Add table
Reference in a new issue