diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 49f3f89d0..f917762dc 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -164,7 +164,7 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, hb_map_t *features, script_langsys_map *langsys_map) { - hb_blob_ptr_t table = hb_sanitize_context_t ().reference_table (plan->source); + hb_blob_ptr_t table = plan->source_table (); hb_tag_t table_tag = table->tableTag; hb_set_t lookup_indices; _collect_layout_indices (plan, @@ -203,14 +203,14 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan, #ifndef HB_NO_VAR static inline void - _collect_layout_variation_indices (hb_face_t *face, - const hb_set_t *glyphset, - const hb_map_t *gpos_lookups, - hb_set_t *layout_variation_indices, - hb_map_t *layout_variation_idx_map) +_collect_layout_variation_indices (hb_subset_plan_t* plan, + const hb_set_t *glyphset, + const hb_map_t *gpos_lookups, + hb_set_t *layout_variation_indices, + hb_map_t *layout_variation_idx_map) { - hb_blob_ptr_t gdef = hb_sanitize_context_t ().reference_table (face); - hb_blob_ptr_t gpos = hb_sanitize_context_t ().reference_table (face); + hb_blob_ptr_t gdef = plan->source_table (); + hb_blob_ptr_t gpos = plan->source_table (); if (!gdef->has_data ()) { @@ -221,7 +221,7 @@ static inline void OT::hb_collect_variation_indices_context_t c (layout_variation_indices, glyphset, gpos_lookups); gdef->collect_variation_indices (&c); - if (hb_ot_layout_has_positioning (face)) + if (hb_ot_layout_has_positioning (plan->source)) gpos->collect_variation_indices (&c); gdef->remap_layout_variation_indices (layout_variation_indices, layout_variation_idx_map); @@ -271,10 +271,10 @@ static void _colr_closure (hb_face_t *face, } static inline void -_math_closure (hb_face_t *face, - hb_set_t *glyphset) +_math_closure (hb_subset_plan_t *plan, + hb_set_t *glyphset) { - hb_blob_ptr_t math = hb_sanitize_context_t ().reference_table (face); + hb_blob_ptr_t math = plan->source_table (); if (math->has_data ()) math->closure_glyphs (glyphset); math.destroy (); @@ -418,7 +418,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ()); hb_set_set (plan->_glyphset_mathed, plan->_glyphset_gsub); - _math_closure (plan->source, plan->_glyphset_mathed); + _math_closure (plan, plan->_glyphset_mathed); _remove_invalid_gids (plan->_glyphset_mathed, plan->source->get_num_glyphs ()); hb_set_t cur_glyphset = *plan->_glyphset_mathed; @@ -446,7 +446,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, #ifndef HB_NO_VAR if (close_over_gdef) - _collect_layout_variation_indices (plan->source, + _collect_layout_variation_indices (plan, plan->_glyphset_gsub, plan->gpos_lookups, plan->layout_variation_indices, @@ -583,6 +583,11 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->layout_variation_indices = hb_set_create (); plan->layout_variation_idx_map = hb_map_create (); + + if ((plan->sanitized_table_cache = hb_object_create>> ())) { + plan->sanitized_table_cache->init_shallow (); + } + if (unlikely (plan->in_error ())) { hb_subset_plan_destroy (plan); return nullptr; @@ -678,6 +683,12 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_free (plan->gpos_langsys); } + if (plan->sanitized_table_cache) { + hb_object_destroy (plan->sanitized_table_cache); + plan->sanitized_table_cache->fini (); + hb_free (plan->sanitized_table_cache); + } + hb_free (plan); } diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index 830c8b9c2..c631ea02e 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -106,8 +106,29 @@ struct hb_subset_plan_t //Old -> New layout item variation store delta set index mapping hb_map_t *layout_variation_idx_map; + hb_hashmap_t>* sanitized_table_cache; + public: + template + hb_blob_ptr_t source_table() + { + if (sanitized_table_cache + && !sanitized_table_cache->in_error () + && sanitized_table_cache->has (T::tableTag)) { + return hb_blob_reference (sanitized_table_cache->get (T::tableTag).get ()); + } + + hb::unique_ptr table_blob {hb_sanitize_context_t ().reference_table (source)}; + hb_blob_t* ret = hb_blob_reference (table_blob.get ()); + + if (likely (sanitized_table_cache)) + sanitized_table_cache->set (T::tableTag, + std::move (table_blob)); + + return ret; + } + bool in_error () const { return !successful; } bool check_success(bool success) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 8cb814dfb..441b6fc0f 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -260,15 +260,15 @@ template static bool _subset (hb_subset_plan_t *plan, hb_vector_t &buf) { - hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table (plan->source); - const TableType *table = source_blob->as (); + hb_blob_ptr_t source_blob = plan->source_table (); + const TableType *table = source_blob.get (); hb_tag_t tag = TableType::tableTag; - if (!source_blob->data) + if (!source_blob.get_blob()->data) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); - hb_blob_destroy (source_blob); + source_blob.destroy (); return false; } @@ -278,23 +278,23 @@ _subset (hb_subset_plan_t *plan, hb_vector_t &buf) TableType::tableTag == HB_OT_TAG_GPOS || TableType::tableTag == HB_OT_TAG_name; - unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob->length, same_size_table); + unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob.get_length (), same_size_table); DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); if (unlikely (!buf.alloc (buf_size))) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); - hb_blob_destroy (source_blob); + source_blob.destroy (); return false; } bool needed = false; hb_serialize_context_t serializer (buf.arrayZ, buf.allocated); { - hb_subset_context_t c (source_blob, plan, &serializer, tag); + hb_subset_context_t c (source_blob.get_blob (), plan, &serializer, tag); needed = _try_subset (table, &buf, &c); } - hb_blob_destroy (source_blob); + source_blob.destroy (); if (serializer.in_error () && !serializer.only_offset_overflow ()) {