diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 3b0b8819e..34b97239b 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -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; } diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index ca91a2597..182f780f8 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -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--; diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 1f205147e..7a3f32eaa 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -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 (); diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index fdbeb5b22..d87a13808 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -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; }; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 0d0dfa0b5..b680d9cb4 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -58,6 +58,24 @@ _hb_ot_layout_create (hb_face_t *face) layout->gpos_blob = Sanitizer::sanitize (hb_face_reference_table (face, HB_OT_TAG_GPOS)); layout->gpos = Sanitizer::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); }