[subset] Fix hdmx subsetting when retain gids is enabled.

This commit is contained in:
Garret Rieger 2019-01-18 18:33:21 -08:00
parent 2da1654aef
commit 23f364429d
3 changed files with 36 additions and 9 deletions

View File

@ -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

View File

@ -159,13 +159,20 @@ static void
_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 @@ 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);

View File

@ -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<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 @@ 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)