[GSUB/GPOS] Use Coverage digests as gatekeeper
Gives me a good 10% speedup for the Devanagari test case. Less so for less lookup-intensive tests. For the Devanagari test case, the false positive rate of the GSUB digest is 4%.
This commit is contained in:
parent
a878c58a8f
commit
1336ecdf8e
|
@ -1551,27 +1551,15 @@ struct PosLookup : Lookup
|
|||
|
||||
c->buffer->idx = 0;
|
||||
|
||||
/* Fast path for lookups with one coverage only (which is most). */
|
||||
const Coverage *coverage = get_coverage ();
|
||||
if (coverage)
|
||||
while (c->buffer->idx < c->buffer->len)
|
||||
{
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) &&
|
||||
coverage->get_coverage (c->buffer->cur().codepoint) != NOT_COVERED &&
|
||||
apply_once (c))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->idx++;
|
||||
}
|
||||
else
|
||||
while (c->buffer->idx < c->buffer->len)
|
||||
{
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) &&
|
||||
apply_once (c))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->idx++;
|
||||
}
|
||||
while (c->buffer->idx < c->buffer->len)
|
||||
{
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) &&
|
||||
c->digest->may_have (c->buffer->cur().codepoint) &&
|
||||
apply_once (c))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->idx++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1219,28 +1219,15 @@ struct SubstLookup : Lookup
|
|||
c->buffer->clear_output ();
|
||||
c->buffer->idx = 0;
|
||||
|
||||
/* Fast path for lookups with one coverage only (which is most). */
|
||||
const Coverage *coverage = get_coverage ();
|
||||
if (coverage)
|
||||
while (c->buffer->idx < c->buffer->len)
|
||||
{
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) &&
|
||||
coverage->get_coverage (c->buffer->cur().codepoint) != NOT_COVERED &&
|
||||
apply_once (c))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->next_glyph ();
|
||||
}
|
||||
else
|
||||
while (c->buffer->idx < c->buffer->len)
|
||||
{
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) &&
|
||||
apply_once (c))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->next_glyph ();
|
||||
|
||||
}
|
||||
while (c->buffer->idx < c->buffer->len)
|
||||
{
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) &&
|
||||
c->digest->may_have (c->buffer->cur().codepoint) &&
|
||||
apply_once (c))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->next_glyph ();
|
||||
}
|
||||
if (ret)
|
||||
c->buffer->swap_buffers ();
|
||||
}
|
||||
|
@ -1250,7 +1237,9 @@ struct SubstLookup : Lookup
|
|||
c->buffer->idx = c->buffer->len - 1;
|
||||
do
|
||||
{
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) && apply_once (c))
|
||||
if ((c->buffer->cur().mask & c->lookup_mask) &&
|
||||
c->digest->may_have (c->buffer->cur().codepoint) &&
|
||||
apply_once (c))
|
||||
ret = true;
|
||||
else
|
||||
c->buffer->idx--;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "hb-buffer-private.hh"
|
||||
#include "hb-ot-layout-gdef-table.hh"
|
||||
#include "hb-set-private.hh"
|
||||
|
||||
|
||||
|
||||
|
@ -109,12 +110,14 @@ struct hb_apply_context_t
|
|||
unsigned int debug_depth;
|
||||
const GDEF &gdef;
|
||||
bool has_glyph_classes;
|
||||
const hb_set_digest_t *digest;
|
||||
|
||||
|
||||
hb_apply_context_t (hb_font_t *font_,
|
||||
hb_face_t *face_,
|
||||
hb_buffer_t *buffer_,
|
||||
hb_mask_t lookup_mask_) :
|
||||
hb_mask_t lookup_mask_,
|
||||
const hb_set_digest_t *digest_) :
|
||||
font (font_), face (face_), buffer (buffer_),
|
||||
direction (buffer_->props.direction),
|
||||
lookup_mask (lookup_mask_),
|
||||
|
@ -123,7 +126,8 @@ struct hb_apply_context_t
|
|||
gdef (hb_ot_layout_from_face (face_) &&
|
||||
!HB_SHAPER_DATA_IS_INVALID (hb_ot_layout_from_face (face_)) ?
|
||||
*hb_ot_layout_from_face (face_)->gdef : Null(GDEF)),
|
||||
has_glyph_classes (gdef.has_glyph_classes ()) {}
|
||||
has_glyph_classes (gdef.has_glyph_classes ()),
|
||||
digest (digest_) {}
|
||||
|
||||
void set_lookup (const Lookup &l) {
|
||||
lookup_props = l.get_props ();
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "hb-font-private.hh"
|
||||
#include "hb-buffer-private.hh"
|
||||
#include "hb-set-private.hh"
|
||||
|
||||
|
||||
/* buffer var allocations, used during the GSUB/GPOS processing */
|
||||
|
@ -168,6 +169,9 @@ struct hb_ot_layout_t
|
|||
const struct GDEF *gdef;
|
||||
const struct GSUB *gsub;
|
||||
const struct GPOS *gpos;
|
||||
|
||||
hb_set_digest_t *gsub_digests;
|
||||
hb_set_digest_t *gpos_digests;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -58,6 +58,24 @@ _hb_ot_layout_create (hb_face_t *face)
|
|||
layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GPOS));
|
||||
layout->gpos = Sanitizer<GPOS>::lock_instance (layout->gpos_blob);
|
||||
|
||||
layout->gsub_digests = (hb_set_digest_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_set_digest_t));
|
||||
layout->gpos_digests = (hb_set_digest_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_set_digest_t));
|
||||
|
||||
if (unlikely ((layout->gsub->get_lookup_count() && !layout->gsub_digests) ||
|
||||
(layout->gpos->get_lookup_count() && !layout->gpos_digests)))
|
||||
{
|
||||
_hb_ot_layout_destroy (layout);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int count;
|
||||
count = layout->gsub->get_lookup_count();
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
layout->gsub->add_coverage (&layout->gsub_digests[i], i);
|
||||
count = layout->gpos->get_lookup_count();
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
layout->gpos->add_coverage (&layout->gpos_digests[i], i);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
|
@ -68,6 +86,9 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
|
|||
hb_blob_destroy (layout->gsub_blob);
|
||||
hb_blob_destroy (layout->gpos_blob);
|
||||
|
||||
free (layout->gsub_digests);
|
||||
free (layout->gpos_digests);
|
||||
|
||||
free (layout);
|
||||
}
|
||||
|
||||
|
@ -412,7 +433,7 @@ hb_ot_layout_substitute_lookup (hb_face_t *face,
|
|||
unsigned int lookup_index,
|
||||
hb_mask_t mask)
|
||||
{
|
||||
hb_apply_context_t c (NULL, face, buffer, mask);
|
||||
hb_apply_context_t c (NULL, face, buffer, mask, NULL);
|
||||
return _get_gsub (face).substitute_lookup (&c, lookup_index);
|
||||
}
|
||||
|
||||
|
@ -422,7 +443,7 @@ hb_ot_layout_substitute_lookup_fast (hb_face_t *face,
|
|||
unsigned int lookup_index,
|
||||
hb_mask_t mask)
|
||||
{
|
||||
hb_apply_context_t c (NULL, face, buffer, mask);
|
||||
hb_apply_context_t c (NULL, face, buffer, mask, &hb_ot_layout_from_face (face)->gsub_digests[lookup_index]);
|
||||
return hb_ot_layout_from_face (face)->gsub->substitute_lookup (&c, lookup_index);
|
||||
}
|
||||
|
||||
|
@ -463,7 +484,7 @@ hb_ot_layout_position_lookup (hb_font_t *font,
|
|||
unsigned int lookup_index,
|
||||
hb_mask_t mask)
|
||||
{
|
||||
hb_apply_context_t c (font, font->face, buffer, mask);
|
||||
hb_apply_context_t c (font, font->face, buffer, mask, NULL);
|
||||
return _get_gpos (font->face).position_lookup (&c, lookup_index);
|
||||
}
|
||||
|
||||
|
@ -473,7 +494,7 @@ hb_ot_layout_position_lookup_fast (hb_font_t *font,
|
|||
unsigned int lookup_index,
|
||||
hb_mask_t mask)
|
||||
{
|
||||
hb_apply_context_t c (font, font->face, buffer, mask);
|
||||
hb_apply_context_t c (font, font->face, buffer, mask, &hb_ot_layout_from_face (font->face)->gpos_digests[lookup_index]);
|
||||
return hb_ot_layout_from_face (font->face)->gpos->position_lookup (&c, lookup_index);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue