From 23f364429dc9350ee06146bdf0ff73d7035e1d71 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Fri, 18 Jan 2019 18:33:21 -0800 Subject: [PATCH] [subset] Fix hdmx subsetting when retain gids is enabled. --- src/hb-ot-hdmx-table.hh | 19 +++++++++++-------- src/hb-subset-plan.cc | 10 ++++++++++ src/hb-subset-plan.hh | 16 +++++++++++++++- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index 95229c52..b1ad3eb0 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -57,16 +57,19 @@ struct DeviceRecord } unsigned int len () const - { return this->subset_plan->glyphs.length; } + { return this->subset_plan->num_glyphs; } - const HBUINT8* operator [] (unsigned int i) const + const HBUINT8* operator [] (unsigned int new_gid) const { - if (unlikely (i >= len ())) return nullptr; - hb_codepoint_t gid = this->subset_plan->glyphs [i]; + if (unlikely (new_gid >= len ())) return nullptr; - if (gid >= sizeDeviceRecord - DeviceRecord::min_size) + hb_codepoint_t old_gid; + if (!this->subset_plan->old_gid_for_new_gid (new_gid, &old_gid)) + return &Null(HBUINT8); + + if (old_gid >= sizeDeviceRecord - DeviceRecord::min_size) return nullptr; - return &(this->source_device_record->widthsZ[gid]); + return &(this->source_device_record->widthsZ[old_gid]); } }; @@ -140,7 +143,7 @@ struct hdmx this->version.set (source_hdmx->version); this->numRecords.set (source_hdmx->numRecords); - this->sizeDeviceRecord.set (DeviceRecord::get_size (plan->glyphs.length)); + this->sizeDeviceRecord.set (DeviceRecord::get_size (plan->num_glyphs)); for (unsigned int i = 0; i < source_hdmx->numRecords; i++) { @@ -156,7 +159,7 @@ struct hdmx static size_t get_subsetted_size (const hdmx *source_hdmx, hb_subset_plan_t *plan) { - return min_size + source_hdmx->numRecords * DeviceRecord::get_size (plan->glyphs.length); + return min_size + source_hdmx->numRecords * DeviceRecord::get_size (plan->num_glyphs); } bool subset (hb_subset_plan_t *plan) const diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 63498b75..dd00f4d9 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -159,13 +159,20 @@ static void _create_old_gid_to_new_gid_map (bool retain_gids, const hb_vector_t &glyphs, hb_map_t *glyph_map, /* OUT */ + hb_map_t *reverse_glyph_map, /* OUT */ unsigned int *num_glyphs /* OUT */) { for (unsigned int i = 0; i < glyphs.length; i++) { if (!retain_gids) + { glyph_map->set (glyphs[i], i); + reverse_glyph_map->set (i, glyphs[i]); + } else + { glyph_map->set (glyphs[i], glyphs[i]); + reverse_glyph_map->set (glyphs[i], glyphs[i]); + } } if (!retain_gids || glyphs.length == 0) { @@ -202,6 +209,7 @@ hb_subset_plan_create (hb_face_t *face, plan->dest = hb_face_builder_create (); plan->codepoint_to_glyph = hb_map_create(); plan->glyph_map = hb_map_create(); + plan->reverse_glyph_map = hb_map_create(); plan->glyphset = _populate_gids_to_retain (face, input->unicodes, !plan->drop_layout, @@ -212,6 +220,7 @@ hb_subset_plan_create (hb_face_t *face, _create_old_gid_to_new_gid_map (input->retain_gids, plan->glyphs, plan->glyph_map, + plan->reverse_glyph_map, &plan->num_glyphs); return plan; @@ -233,6 +242,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_face_destroy (plan->dest); hb_map_destroy (plan->codepoint_to_glyph); hb_map_destroy (plan->glyph_map); + hb_map_destroy (plan->reverse_glyph_map); hb_set_destroy (plan->glyphset); free (plan); diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index b8b2c5d3..5a90b7c3 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -45,11 +45,14 @@ struct hb_subset_plan_t // For each cp that we'd like to retain maps to the corresponding gid. hb_set_t *unicodes; + // The glyph subset hb_vector_t glyphs; hb_set_t *glyphset; - hb_map_t *codepoint_to_glyph; + + // Old -> New glyph id mapping hb_map_t *glyph_map; + hb_map_t *reverse_glyph_map; unsigned int num_glyphs; // Plan is only good for a specific source/dest so keep them with it @@ -77,6 +80,17 @@ struct hb_subset_plan_t return true; } + bool old_gid_for_new_gid (hb_codepoint_t new_gid, + hb_codepoint_t *old_gid) const + { + hb_codepoint_t gid = reverse_glyph_map->get (new_gid); + if (gid == HB_MAP_VALUE_INVALID) + return false; + + *old_gid = gid; + return true; + } + bool add_table (hb_tag_t tag, hb_blob_t *contents) -- GitLab