diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index d87a1380891dce4aa33169ae067d4a0490d4d4e7..ea2e64d2c5719519e23aa6462ac53fa6acd3736d 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -170,6 +170,9 @@ struct hb_ot_layout_t const struct GSUB *gsub; const struct GPOS *gpos; + unsigned int gsub_lookup_count; + unsigned int gpos_lookup_count; + 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 c8f4d6993d2ff91df513395ec060f3a8f8de3540..63f30956af4c21599c78618cff882a49f852501e 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -58,22 +58,22 @@ _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_lookup_count = layout->gsub->get_lookup_count (); + layout->gpos_lookup_count = layout->gpos->get_lookup_count (); + 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))) + if (unlikely ((layout->gsub_lookup_count && !layout->gsub_digests) || + (layout->gpos_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++) + for (unsigned int i = 0; i < layout->gsub_lookup_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++) + for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) layout->gpos->add_coverage (&layout->gpos_digests[i], i); return layout; @@ -405,9 +405,8 @@ hb_ot_layout_would_substitute_lookup (hb_face_t *face, unsigned int glyphs_length, unsigned int lookup_index) { - if (unlikely (glyphs_length < 1 || glyphs_length > 2)) return false; - hb_would_apply_context_t c (face, glyphs[0], glyphs_length == 2 ? glyphs[1] : -1, NULL); - return _get_gsub (face).would_substitute_lookup (&c, lookup_index); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false; + return hb_ot_layout_would_substitute_lookup_fast (face, glyphs, glyphs_length, lookup_index); } hb_bool_t @@ -417,6 +416,7 @@ hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face, unsigned int lookup_index) { if (unlikely (glyphs_length < 1 || glyphs_length > 2)) return false; + if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false; hb_would_apply_context_t c (face, glyphs[0], glyphs_length == 2 ? glyphs[1] : -1, &hb_ot_layout_from_face (face)->gsub_digests[lookup_index]); return hb_ot_layout_from_face (face)->gsub->would_substitute_lookup (&c, lookup_index); } @@ -433,8 +433,8 @@ 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, NULL); - return _get_gsub (face).substitute_lookup (&c, lookup_index); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false; + return hb_ot_layout_substitute_lookup_fast (face, buffer, lookup_index, mask); } hb_bool_t @@ -443,6 +443,7 @@ hb_ot_layout_substitute_lookup_fast (hb_face_t *face, unsigned int lookup_index, hb_mask_t mask) { + if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false; 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); } @@ -484,8 +485,8 @@ 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, NULL); - return _get_gpos (font->face).position_lookup (&c, lookup_index); + if (unlikely (!hb_ot_shaper_face_data_ensure (font->face))) return false; + return hb_ot_layout_position_lookup_fast (font, buffer, lookup_index, mask); } hb_bool_t @@ -494,6 +495,7 @@ hb_ot_layout_position_lookup_fast (hb_font_t *font, unsigned int lookup_index, hb_mask_t mask) { + if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gpos_lookup_count)) return false; 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); } @@ -503,5 +505,3 @@ hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t ze { GPOS::position_finish (font, buffer, zero_width_attached_marks); } - -