diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index fe4d78c41..02c422a86 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1754,20 +1754,35 @@ struct VarData TRACE_SUBSET (this); if (unlikely (!c->extend_min (*this))) return_trace (false); itemCount.set (remap.get_count ()); - shortCount.set (src->shortCount); - unsigned int row_size = src->get_row_size (); - unsigned int size = src->regionIndices.get_size () - HBUINT16::static_size/*regionIndices.len*/ + (row_size * remap.get_count ()); + /* Optimize short count */ + unsigned int short_count = src->shortCount; + for (; short_count > 0; short_count--) + for (unsigned int i = 0; i < remap.get_count (); i++) + { + unsigned int old = remap.to_old (i); + if (unlikely (old >= src->itemCount)) return_trace (false); + int16_t hi = get_item_delta (old, short_count - 1) & 0xFF00; + if (hi != 0 && hi != 0xFF00) goto found_short; + } + +found_short: + shortCount.set (short_count); + regionIndices.len.set (src->regionIndices.len); + + unsigned int size = src->regionIndices.get_size () - HBUINT16::static_size/*regionIndices.len*/ + (get_row_size () * itemCount); if (unlikely (!c->allocate_size (size))) return_trace (false); - memcpy (®ionIndices, &src->regionIndices, src->regionIndices.get_size ()); - HBUINT8 *p = get_delta_bytes (); - for (unsigned int i = 0; i < remap.get_count (); i++) - { - memcpy (p, src->get_delta_bytes () + (row_size * remap.to_old (i)), row_size); - p += row_size; - } + memcpy (®ionIndices[0], &src->regionIndices[0], src->regionIndices.get_size ()-HBUINT16::static_size); + + for (unsigned int i = 0; i < itemCount; i++) + for (unsigned int r = 0; r < regionIndices.len; r++) + { + hb_codepoint_t old = remap.to_old (i); + if (unlikely (old >= src->itemCount)) return_trace (false); + set_item_delta (i, r, src->get_item_delta (old, r)); + } return_trace (true); } @@ -1782,6 +1797,24 @@ struct VarData HBUINT8 *get_delta_bytes () { return &StructAfter (regionIndices); } + int16_t get_item_delta (unsigned int item, unsigned int region) const + { + const HBINT8 *p = (const HBINT8 *)get_delta_bytes () + item * get_row_size (); + if (region < shortCount) + return ((const HBINT16 *)p)[region]; + else + return (p + HBINT16::static_size * shortCount)[region - shortCount]; + } + + void set_item_delta (unsigned int item, unsigned int region, int16_t delta) + { + HBINT8 *p = (HBINT8 *)get_delta_bytes () + item * get_row_size (); + if (region < shortCount) + ((HBINT16 *)p)[region].set (delta); + else + (p + HBINT16::static_size * shortCount)[region - shortCount].set (delta); + } + protected: HBUINT16 itemCount; HBUINT16 shortCount; diff --git a/src/hb-ot-var-hvar-table.hh b/src/hb-ot-var-hvar-table.hh index 77d96b7cf..19257f6d0 100644 --- a/src/hb-ot-var-hvar-table.hh +++ b/src/hb-ot-var-hvar-table.hh @@ -121,7 +121,16 @@ struct DeltaSetIndexMap struct index_map_subset_plan_t { + enum index_map_index_t { + ADV_INDEX, + LSB_INDEX, + RSB_INDEX, + TSB_INDEX, + VORG_INDEX + }; + void init (const DeltaSetIndexMap &index_map, + unsigned int im_index, hb_bimap_t &outer_remap, hb_vector_t &inner_remaps, const hb_subset_plan_t *plan) @@ -132,14 +141,18 @@ struct index_map_subset_plan_t max_inners.init (); output_map.init (); - /* Identity map */ if (&index_map == &Null(DeltaSetIndexMap)) { - outer_remap.add (0); - hb_codepoint_t old_gid; - for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) - if (plan->old_gid_for_new_gid (gid, &old_gid)) - inner_remaps[0].add (old_gid); + /* Advance width index map is required. If its offset is missing, + * treat it as an indentity map. */ + if (im_index == ADV_INDEX) + { + outer_remap.add (0); + hb_codepoint_t old_gid; + for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) + if (plan->old_gid_for_new_gid (gid, &old_gid)) + inner_remaps[0].add (old_gid); + } return; } @@ -257,7 +270,7 @@ struct hvarvvar_subset_plan_t inner_remaps[i].init (); for (unsigned int i = 0; i < index_maps.length; i++) - index_map_plans[i].init (*index_maps[i], outer_remap, inner_remaps, plan); + index_map_plans[i].init (*index_maps[i], i, outer_remap, inner_remaps, plan); outer_remap.reorder (); for (unsigned int i = 0; i < inner_remaps.length; i++) @@ -294,14 +307,6 @@ struct HVARVVAR static constexpr hb_tag_t HVARTag = HB_OT_TAG_HVAR; static constexpr hb_tag_t VVARTag = HB_OT_TAG_VVAR; - enum index_map_index_t { - ADV_INDEX, - LSB_INDEX, - RSB_INDEX, - TSB_INDEX, - VORG_INDEX - }; - bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -324,17 +329,17 @@ struct HVARVVAR const hb_array_t &im_plans) { TRACE_SUBSET (this); - if (im_plans[ADV_INDEX].is_identity ()) + if (im_plans[index_map_subset_plan_t::ADV_INDEX].is_identity ()) advMap.set (0); - else if (unlikely (!advMap.serialize (c, this).serialize (c, im_plans[ADV_INDEX]))) + else if (unlikely (!advMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::ADV_INDEX]))) return_trace (false); - if (im_plans[LSB_INDEX].is_identity ()) + if (im_plans[index_map_subset_plan_t::LSB_INDEX].is_identity ()) lsbMap.set (0); - else if (unlikely (!lsbMap.serialize (c, this).serialize (c, im_plans[LSB_INDEX]))) + else if (unlikely (!lsbMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::LSB_INDEX]))) return_trace (false); - if (im_plans[RSB_INDEX].is_identity ()) + if (im_plans[index_map_subset_plan_t::RSB_INDEX].is_identity ()) rsbMap.set (0); - else if (unlikely (!rsbMap.serialize (c, this).serialize (c, im_plans[RSB_INDEX]))) + else if (unlikely (!rsbMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::RSB_INDEX]))) return_trace (false); return_trace (true); @@ -424,9 +429,9 @@ struct VVAR : HVARVVAR { TRACE_SUBSET (this); if (unlikely (!HVARVVAR::serialize_index_maps (c, im_plans))) return_trace (false); - if (!im_plans[VORG_INDEX].get_map_count ()) + if (!im_plans[index_map_subset_plan_t::VORG_INDEX].get_map_count ()) vorgMap.set (0); - else if (unlikely (!vorgMap.serialize (c, this).serialize (c, im_plans[VORG_INDEX]))) + else if (unlikely (!vorgMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::VORG_INDEX]))) return_trace (false); return_trace (true); diff --git a/test/api/fonts/AdobeVFPrototype.abc.otf b/test/api/fonts/AdobeVFPrototype.abc.otf index 2cd6965c7..022e6fae5 100644 Binary files a/test/api/fonts/AdobeVFPrototype.abc.otf and b/test/api/fonts/AdobeVFPrototype.abc.otf differ diff --git a/test/api/fonts/AdobeVFPrototype.ac.nohints.otf b/test/api/fonts/AdobeVFPrototype.ac.nohints.otf index fa593f594..63fd0a771 100644 Binary files a/test/api/fonts/AdobeVFPrototype.ac.nohints.otf and b/test/api/fonts/AdobeVFPrototype.ac.nohints.otf differ diff --git a/test/api/fonts/AdobeVFPrototype.ac.nosubrs.nohints.otf b/test/api/fonts/AdobeVFPrototype.ac.nosubrs.nohints.otf index 85e921015..0509ba8e6 100644 Binary files a/test/api/fonts/AdobeVFPrototype.ac.nosubrs.nohints.otf and b/test/api/fonts/AdobeVFPrototype.ac.nosubrs.nohints.otf differ diff --git a/test/api/fonts/AdobeVFPrototype.ac.nosubrs.otf b/test/api/fonts/AdobeVFPrototype.ac.nosubrs.otf index 76f264ec4..8d268686e 100644 Binary files a/test/api/fonts/AdobeVFPrototype.ac.nosubrs.otf and b/test/api/fonts/AdobeVFPrototype.ac.nosubrs.otf differ diff --git a/test/api/fonts/AdobeVFPrototype.ac.otf b/test/api/fonts/AdobeVFPrototype.ac.otf index a3cd02a0e..231c2ac85 100644 Binary files a/test/api/fonts/AdobeVFPrototype.ac.otf and b/test/api/fonts/AdobeVFPrototype.ac.otf differ diff --git a/test/api/fonts/AdobeVFPrototype.ac.retaingids.otf b/test/api/fonts/AdobeVFPrototype.ac.retaingids.otf index 9adddf5ac..e0f0546d4 100644 Binary files a/test/api/fonts/AdobeVFPrototype.ac.retaingids.otf and b/test/api/fonts/AdobeVFPrototype.ac.retaingids.otf differ diff --git a/test/subset/data/expected/full-font/SourceSerifVariable-Roman.default.1FC,21,41,20,62,63.ttf b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.default.1FC,21,41,20,62,63.ttf new file mode 100644 index 000000000..1800da864 Binary files /dev/null and b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.default.1FC,21,41,20,62,63.ttf differ diff --git a/test/subset/data/expected/full-font/SourceSerifVariable-Roman.default.61,62,63.ttf b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.default.61,62,63.ttf new file mode 100644 index 000000000..4b538a87d Binary files /dev/null and b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.default.61,62,63.ttf differ diff --git a/test/subset/data/expected/full-font/SourceSerifVariable-Roman.default.D7,D8,D9,DA,DE.ttf b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.default.D7,D8,D9,DA,DE.ttf new file mode 100644 index 000000000..d579c1fa5 Binary files /dev/null and b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.default.D7,D8,D9,DA,DE.ttf differ diff --git a/test/subset/data/expected/full-font/SourceSerifVariable-Roman.drop-hints.1FC,21,41,20,62,63.ttf b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.drop-hints.1FC,21,41,20,62,63.ttf new file mode 100644 index 000000000..1800da864 Binary files /dev/null and b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.drop-hints.1FC,21,41,20,62,63.ttf differ diff --git a/test/subset/data/expected/full-font/SourceSerifVariable-Roman.drop-hints.61,62,63.ttf b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.drop-hints.61,62,63.ttf new file mode 100644 index 000000000..4b538a87d Binary files /dev/null and b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.drop-hints.61,62,63.ttf differ diff --git a/test/subset/data/expected/full-font/SourceSerifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf new file mode 100644 index 000000000..ead6c9c70 Binary files /dev/null and b/test/subset/data/expected/full-font/SourceSerifVariable-Roman.drop-hints.D7,D8,D9,DA,DE.ttf differ diff --git a/test/subset/data/fonts/SourceSerifVariable-Roman.ttf b/test/subset/data/fonts/SourceSerifVariable-Roman.ttf new file mode 100644 index 000000000..4a738451f Binary files /dev/null and b/test/subset/data/fonts/SourceSerifVariable-Roman.ttf differ diff --git a/test/subset/data/tests/full-font.tests b/test/subset/data/tests/full-font.tests index ff195cead..28ae084f0 100644 --- a/test/subset/data/tests/full-font.tests +++ b/test/subset/data/tests/full-font.tests @@ -1,5 +1,6 @@ FONTS: Roboto-Regular.ttf +SourceSerifVariable-Roman.ttf PROFILES: default.txt