diff --git a/src/OT/Color/COLR/COLR.hh b/src/OT/Color/COLR/COLR.hh index 42b332658..d84e07039 100644 --- a/src/OT/Color/COLR/COLR.hh +++ b/src/OT/Color/COLR/COLR.hh @@ -160,7 +160,10 @@ struct hb_colrv1_closure_context_t : { palette_indices->add (palette_index); } void add_var_idxes (unsigned first_var_idx, unsigned num_idxes) - { variation_indices->add_range (first_var_idx, first_var_idx + num_idxes - 1); } + { + if (!num_idxes || first_var_idx == VarIdx::NO_VARIATION) return; + variation_indices->add_range (first_var_idx, first_var_idx + num_idxes - 1); + } public: const void *base; @@ -252,6 +255,7 @@ struct Variable void closurev1 (hb_colrv1_closure_context_t* c) const { + c->num_var_idxes = 0; // update c->num_var_idxes during value closure value.closurev1 (c); c->add_var_idxes (varIdxBase, c->num_var_idxes); @@ -2041,8 +2045,15 @@ struct COLR void closure_forV1 (hb_set_t *glyphset, hb_set_t *layer_indices, hb_set_t *palette_indices, - hb_set_t *variation_indices) const - { colr->closure_forV1 (glyphset, layer_indices, palette_indices, variation_indices); } + hb_set_t *variation_indices, + hb_set_t *delta_set_indices) const + { colr->closure_forV1 (glyphset, layer_indices, palette_indices, variation_indices, delta_set_indices); } + + bool has_var_store () const + { return colr->has_var_store (); } + + const ItemVariationStore &get_var_store () const + { return colr->get_var_store (); } private: hb_blob_ptr_t colr; @@ -2080,7 +2091,8 @@ struct COLR void closure_forV1 (hb_set_t *glyphset, hb_set_t *layer_indices, hb_set_t *palette_indices, - hb_set_t *variation_indices) const + hb_set_t *variation_indices, + hb_set_t *delta_set_indices) const { if (version != 1) return; hb_barrier (); @@ -2104,6 +2116,17 @@ struct COLR c.glyphs = glyphset; for (const ClipRecord &clip_record : cliplist.clips.iter()) clip_record.closurev1 (&c, &cliplist); + + // if a DeltaSetIndexMap is included, collected variation indices are + // actually delta set indices, we need to map them into variation indices + if (has_delta_set_index_map ()) + { + const DeltaSetIndexMap &var_idx_map = this+varIdxMap; + delta_set_indices->set (*variation_indices); + variation_indices->clear (); + for (unsigned delta_set_idx : *delta_set_indices) + variation_indices->add (var_idx_map.map (delta_set_idx)); + } } const LayerList& get_layerList () const @@ -2112,6 +2135,15 @@ struct COLR const BaseGlyphList& get_baseglyphList () const { return (this+baseGlyphList); } + bool has_var_store () const + { return version >= 1 && varStore != 0; } + + bool has_delta_set_index_map () const + { return version >= 1 && varIdxMap != 0; } + + const ItemVariationStore &get_var_store () const + { return (version == 0 || varStore == 0) ? Null (ItemVariationStore) : this+varStore; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/src/OT/Layout/GDEF/GDEF.hh b/src/OT/Layout/GDEF/GDEF.hh index 317b96c71..45baeb4ec 100644 --- a/src/OT/Layout/GDEF/GDEF.hh +++ b/src/OT/Layout/GDEF/GDEF.hh @@ -1022,47 +1022,6 @@ struct GDEF void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { get_lig_caret_list ().collect_variation_indices (c); } - void remap_layout_variation_indices (const hb_set_t *layout_variation_indices, - const hb_vector_t& normalized_coords, - bool calculate_delta, /* not pinned at default */ - bool no_variations, /* all axes pinned */ - hb_hashmap_t> *layout_variation_idx_delta_map /* OUT */) const - { - if (!has_var_store ()) return; - const ItemVariationStore &var_store = get_var_store (); - float *store_cache = var_store.create_cache (); - - unsigned new_major = 0, new_minor = 0; - unsigned last_major = (layout_variation_indices->get_min ()) >> 16; - for (unsigned idx : layout_variation_indices->iter ()) - { - int delta = 0; - if (calculate_delta) - delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, - normalized_coords.length, store_cache)); - - if (no_variations) - { - layout_variation_idx_delta_map->set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); - continue; - } - - uint16_t major = idx >> 16; - if (major >= var_store.get_sub_table_count ()) break; - if (major != last_major) - { - new_minor = 0; - ++new_major; - } - - unsigned new_idx = (new_major << 16) + new_minor; - layout_variation_idx_delta_map->set (idx, hb_pair_t (new_idx, delta)); - ++new_minor; - last_major = major; - } - var_store.destroy_cache (store_cache); - } - protected: union { FixedVersion<> version; /* Version identifier */ diff --git a/src/hb-subset-plan-member-list.hh b/src/hb-subset-plan-member-list.hh index 74416b92f..4651f14d8 100644 --- a/src/hb-subset-plan-member-list.hh +++ b/src/hb-subset-plan-member-list.hh @@ -102,6 +102,8 @@ HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(, colrv1_varstore_inner_maps) //Old layout item variation index -> (New varidx, delta) mapping HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E()>), layout_variation_idx_delta_map) diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 865041a3e..1d032ec4d 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -398,13 +398,56 @@ _get_hb_font_with_variations (const hb_subset_plan_t *plan) return font; } +static inline void +_remap_variation_indices (const OT::ItemVariationStore &var_store, + const hb_set_t &variation_indices, + const hb_vector_t& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ + hb_hashmap_t> &variation_idx_delta_map /* OUT */) +{ + if (&var_store == &Null (OT::ItemVariationStore)) return; + unsigned subtable_count = var_store.get_sub_table_count (); + float *store_cache = var_store.create_cache (); + + unsigned new_major = 0, new_minor = 0; + unsigned last_major = (variation_indices.get_min ()) >> 16; + for (unsigned idx : variation_indices) + { + int delta = 0; + if (calculate_delta) + delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, + normalized_coords.length, store_cache)); + + if (no_variations) + { + variation_idx_delta_map.set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); + continue; + } + + uint16_t major = idx >> 16; + if (major >= subtable_count) break; + if (major != last_major) + { + new_minor = 0; + ++new_major; + } + + unsigned new_idx = (new_major << 16) + new_minor; + variation_idx_delta_map.set (idx, hb_pair_t (new_idx, delta)); + ++new_minor; + last_major = major; + } + var_store.destroy_cache (store_cache); +} + static inline void _collect_layout_variation_indices (hb_subset_plan_t* plan) { hb_blob_ptr_t gdef = plan->source_table (); hb_blob_ptr_t gpos = plan->source_table (); - if (!gdef->has_data ()) + if (!gdef->has_data () || !gdef->has_var_store ()) { gdef.destroy (); gpos.destroy (); @@ -420,13 +463,13 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan) if (hb_ot_layout_has_positioning (plan->source)) gpos->collect_variation_indices (&c); - gdef->remap_layout_variation_indices (&varidx_set, - plan->normalized_coords, - !plan->pinned_at_default, - plan->all_axes_pinned, - &plan->layout_variation_idx_delta_map); + _remap_variation_indices (gdef->get_var_store (), + varidx_set, plan->normalized_coords, + !plan->pinned_at_default, + plan->all_axes_pinned, + plan->layout_variation_idx_delta_map); - unsigned subtable_count = gdef->has_var_store () ? gdef->get_var_store ().get_sub_table_count () : 0; + unsigned subtable_count = gdef->get_var_store ().get_sub_table_count (); _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps); gdef.destroy (); @@ -434,31 +477,6 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan) } #ifndef HB_NO_BASE -/* used by BASE table only, delta is always set to 0 in the output map */ -static inline void -_remap_variation_indices (const hb_set_t& indices, - unsigned subtable_count, - hb_hashmap_t>& variation_idx_delta_map /* OUT */) -{ - unsigned new_major = 0, new_minor = 0; - unsigned last_major = (indices.get_min ()) >> 16; - for (unsigned idx : indices) - { - uint16_t major = idx >> 16; - if (major >= subtable_count) break; - if (major != last_major) - { - new_minor = 0; - ++new_major; - } - - unsigned new_idx = (new_major << 16) + new_minor; - variation_idx_delta_map.set (idx, hb_pair_t (new_idx, 0)); - ++new_minor; - last_major = major; - } -} - static inline void _collect_base_variation_indices (hb_subset_plan_t* plan) { @@ -474,9 +492,13 @@ _collect_base_variation_indices (hb_subset_plan_t* plan) unsigned subtable_count = base->get_var_store ().get_sub_table_count (); base.destroy (); - _remap_variation_indices (varidx_set, subtable_count, plan->base_variation_idx_map); + /* TODO: support instancing for BASE table */ + _remap_variation_indices (base->get_var_store (), varidx_set, + plan->normalized_coords, + false, false, plan->base_variation_idx_map); _generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); } + #endif #endif @@ -489,12 +511,10 @@ _cmap_closure (hb_face_t *face, cmap.table->closure_glyphs (unicodes, glyphset); } -static void _colr_closure (hb_face_t *face, - hb_map_t *layers_map, - hb_map_t *palettes_map, +static void _colr_closure (hb_subset_plan_t* plan, hb_set_t *glyphs_colred) { - OT::COLR::accelerator_t colr (face); + OT::COLR::accelerator_t colr (plan->source); if (!colr.is_valid ()) return; hb_set_t palette_indices, layer_indices; @@ -506,12 +526,17 @@ static void _colr_closure (hb_face_t *face, glyphs_colred->union_ (glyphset_colrv0); //closure for COLRv1 - hb_set_t variation_indices; - colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices, &variation_indices); + hb_set_t variation_indices, delta_set_indices; + colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices, &variation_indices, &delta_set_indices); colr.closure_V0palette_indices (glyphs_colred, &palette_indices); - _remap_indexes (&layer_indices, layers_map); - _remap_palette_indexes (&palette_indices, palettes_map); + _remap_indexes (&layer_indices, &plan->colrv1_layers); + _remap_palette_indexes (&palette_indices, &plan->colr_palettes); + + if (!colr.has_var_store ()) return; + + unsigned subtable_count = colr.get_var_store ().get_sub_table_count (); + _generate_varstore_inner_maps (variation_indices, subtable_count, plan->colrv1_varstore_inner_maps); } static inline void @@ -822,7 +847,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, hb_set_t cur_glyphset = plan->_glyphset_mathed; if (!drop_tables->has (HB_OT_TAG_COLR)) { - _colr_closure (plan->source, &plan->colrv1_layers, &plan->colr_palettes, &cur_glyphset); + _colr_closure (plan, &cur_glyphset); _remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ()); }