[layout] Use a buffer digest for GPOS to skip whole lookups

This commit is contained in:
Behdad Esfahbod 2022-11-16 15:59:13 -07:00
parent a053b84cb9
commit 15b6c32599
3 changed files with 33 additions and 12 deletions

View File

@ -3994,8 +3994,8 @@ struct hb_ot_layout_lookup_accelerator_t
}
private:
hb_set_digest_t digest;
private:
hb_accelerate_subtables_context_t::array_t subtables;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
unsigned cache_user_idx = (unsigned) -1;

View File

@ -1867,7 +1867,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
while (buffer->idx < buffer->len && buffer->successful)
{
bool applied = false;
if (accel.may_have (buffer->cur().codepoint) &&
if (accel.digest.may_have (buffer->cur().codepoint) &&
(buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props))
{
@ -1894,7 +1894,7 @@ apply_backward (OT::hb_ot_apply_context_t *c,
hb_buffer_t *buffer = c->buffer;
do
{
if (accel.may_have (buffer->cur().codepoint) &&
if (accel.digest.may_have (buffer->cur().codepoint) &&
(buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props))
ret |= accel.apply (c, false);
@ -1952,6 +1952,13 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
OT::hb_ot_apply_context_t c (table_index, font, buffer);
c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func<OT::hb_ot_apply_context_t>);
hb_set_digest_t digest;
digest.init ();
if (proxy.table_index == 1) /* GPOS */
digest.add_array (&buffer->info[0].codepoint,
buffer->len,
sizeof (buffer->info[0]));
for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++)
{
const stage_map_t *stage = &stages[table_index][stage_index];
@ -1959,16 +1966,22 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
{
unsigned int lookup_index = lookups[table_index][i].index;
if (!buffer->message (font, "start lookup %d", lookup_index)) continue;
c.set_lookup_index (lookup_index);
c.set_lookup_mask (lookups[table_index][i].mask);
c.set_auto_zwj (lookups[table_index][i].auto_zwj);
c.set_auto_zwnj (lookups[table_index][i].auto_zwnj);
c.set_random (lookups[table_index][i].random);
c.set_per_syllable (lookups[table_index][i].per_syllable);
apply_string<Proxy> (&c,
proxy.table.get_lookup (lookup_index),
proxy.accels[lookup_index]);
if (table_index != 1 ||
proxy.accels[lookup_index].digest.may_have (digest))
{
c.set_lookup_index (lookup_index);
c.set_lookup_mask (lookups[table_index][i].mask);
c.set_auto_zwj (lookups[table_index][i].auto_zwj);
c.set_auto_zwnj (lookups[table_index][i].auto_zwnj);
c.set_random (lookups[table_index][i].random);
c.set_per_syllable (lookups[table_index][i].per_syllable);
apply_string<Proxy> (&c,
proxy.table.get_lookup (lookup_index),
proxy.accels[lookup_index]);
}
(void) buffer->message (font, "end lookup %d", lookup_index);
}

View File

@ -111,6 +111,9 @@ struct hb_set_digest_bits_pattern_t
template <typename T>
bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
bool may_have (const hb_set_digest_bits_pattern_t &o) const
{ return mask & o.mask; }
bool may_have (hb_codepoint_t g) const
{ return mask & mask_for (g); }
@ -164,6 +167,11 @@ struct hb_set_digest_combiner_t
template <typename T>
bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); }
bool may_have (const hb_set_digest_combiner_t &o) const
{
return head.may_have (o.head) && tail.may_have (o.tail);
}
bool may_have (hb_codepoint_t g) const
{
return head.may_have (g) && tail.may_have (g);