diff --git a/src/hb-bimap.hh b/src/hb-bimap.hh index 8e8c98871..9edefd971 100644 --- a/src/hb-bimap.hh +++ b/src/hb-bimap.hh @@ -83,9 +83,15 @@ struct hb_bimap_t unsigned int get_population () const { return forw_map.get_population (); } + protected: hb_map_t forw_map; hb_map_t back_map; + + public: + auto keys () const HB_AUTO_RETURN (+ forw_map.keys()) + auto values () const HB_AUTO_RETURN (+ forw_map.values()) + auto iter () const HB_AUTO_RETURN (+ forw_map.iter()) }; /* Inremental bimap: only lhs is given, rhs is incrementally assigned */ @@ -108,6 +114,9 @@ struct hb_inc_bimap_t : hb_bimap_t hb_codepoint_t skip () { return next_value++; } + hb_codepoint_t skip (unsigned count) + { return next_value += count; } + hb_codepoint_t get_next_value () const { return next_value; } diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 9d1c10582..ad8a6e0be 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -2501,10 +2501,9 @@ struct VarData { for (r = 0; r < src_word_count; r++) { - for (unsigned int i = 0; i < inner_map.get_next_value (); i++) + for (unsigned old_gid : inner_map.keys()) { - unsigned int old = inner_map.backward (i); - int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size); + int32_t delta = src->get_item_delta_fast (old_gid, r, src_delta_bytes, src_row_size); if (delta < -65536 || 65535 < delta) { has_long = true; @@ -2521,10 +2520,9 @@ struct VarData bool short_circuit = src_long_words == has_long && src_word_count <= r; delta_sz[r] = kZero; - for (unsigned int i = 0; i < inner_map.get_next_value (); i++) + for (unsigned old_gid : inner_map.keys()) { - unsigned int old = inner_map.backward (i); - int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size); + int32_t delta = src->get_item_delta_fast (old_gid, r, src_delta_bytes, src_row_size); if (delta < min_threshold || max_threshold < delta) { delta_sz[r] = kWord; @@ -2585,8 +2583,8 @@ struct VarData { unsigned int region = regionIndices.arrayZ[r]; if (region_indices.has (region)) continue; - for (unsigned int i = 0; i < inner_map.get_next_value (); i++) - if (get_item_delta_fast (inner_map.backward (i), r, delta_bytes, row_size) != 0) + for (hb_codepoint_t old_gid : inner_map.keys()) + if (get_item_delta_fast (old_gid, r, delta_bytes, row_size) != 0) { region_indices.add (region); break; diff --git a/src/hb-ot-var-hvar-table.hh b/src/hb-ot-var-hvar-table.hh index 00a8e1f0b..461b2b9cd 100644 --- a/src/hb-ot-var-hvar-table.hh +++ b/src/hb-ot-var-hvar-table.hh @@ -185,12 +185,8 @@ struct hvarvvar_subset_plan_t { retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS; outer_map.add (0); - for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) - { - hb_codepoint_t old_gid; - if (plan->old_gid_for_new_gid (gid, &old_gid)) - inner_sets[0]->add (old_gid); - } + for (hb_codepoint_t old_gid : plan->glyphset()->iter()) + inner_sets[0]->add (old_gid); hb_set_union (adv_set, inner_sets[0]); } @@ -202,10 +198,12 @@ struct hvarvvar_subset_plan_t if (retain_adv_map) { for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) + { if (inner_sets[0]->has (gid)) inner_maps[0].add (gid); else inner_maps[0].skip (); + } } else { diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-4575222591520768 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-4575222591520768 new file mode 100644 index 000000000..a225a279f Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-4575222591520768 differ diff --git a/test/subset/data/expected/variable/Fraunces.retain-gids.26,66,69,124,125.ttf b/test/subset/data/expected/variable/Fraunces.retain-gids.26,66,69,124,125.ttf new file mode 100644 index 000000000..310bc67b7 Binary files /dev/null and b/test/subset/data/expected/variable/Fraunces.retain-gids.26,66,69,124,125.ttf differ diff --git a/test/subset/data/expected/variable/Fraunces.retain-gids.61.ttf b/test/subset/data/expected/variable/Fraunces.retain-gids.61.ttf new file mode 100644 index 000000000..c77d9f16b Binary files /dev/null and b/test/subset/data/expected/variable/Fraunces.retain-gids.61.ttf differ diff --git a/test/subset/data/tests/variable.tests b/test/subset/data/tests/variable.tests index bda5875ce..2d803af80 100644 --- a/test/subset/data/tests/variable.tests +++ b/test/subset/data/tests/variable.tests @@ -3,6 +3,7 @@ Fraunces.ttf PROFILES: default.txt +retain-gids.txt SUBSETS: a