[subset] Fix hdmx subsetting when retain gids is enabled.
diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh
index 95229c5..b1ad3eb 100644
--- a/src/hb-ot-hdmx-table.hh
+++ b/src/hb-ot-hdmx-table.hh
@@ -57,16 +57,19 @@
}
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 @@
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 @@
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 63498b7..dd00f4d 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -159,13 +159,20 @@
_create_old_gid_to_new_gid_map (bool retain_gids,
const hb_vector_t<hb_codepoint_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 @@
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 @@
_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_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 b8b2c5d..5a90b7c 100644
--- a/src/hb-subset-plan.hh
+++ b/src/hb-subset-plan.hh
@@ -45,11 +45,14 @@
// For each cp that we'd like to retain maps to the corresponding gid.
hb_set_t *unicodes;
+ // The glyph subset
hb_vector_t<hb_codepoint_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 @@
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)