[subset] Fix hdmx subsetting when retain gids is enabled.
This commit is contained in:
parent
2da1654aef
commit
23f364429d
|
@ -57,16 +57,19 @@ struct DeviceRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int len () const
|
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;
|
if (unlikely (new_gid >= len ())) return nullptr;
|
||||||
hb_codepoint_t gid = this->subset_plan->glyphs [i];
|
|
||||||
|
|
||||||
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 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->version.set (source_hdmx->version);
|
||||||
this->numRecords.set (source_hdmx->numRecords);
|
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++)
|
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)
|
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
|
bool subset (hb_subset_plan_t *plan) const
|
||||||
|
|
|
@ -159,13 +159,20 @@ static void
|
||||||
_create_old_gid_to_new_gid_map (bool retain_gids,
|
_create_old_gid_to_new_gid_map (bool retain_gids,
|
||||||
const hb_vector_t<hb_codepoint_t> &glyphs,
|
const hb_vector_t<hb_codepoint_t> &glyphs,
|
||||||
hb_map_t *glyph_map, /* OUT */
|
hb_map_t *glyph_map, /* OUT */
|
||||||
|
hb_map_t *reverse_glyph_map, /* OUT */
|
||||||
unsigned int *num_glyphs /* OUT */)
|
unsigned int *num_glyphs /* OUT */)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < glyphs.length; i++) {
|
for (unsigned int i = 0; i < glyphs.length; i++) {
|
||||||
if (!retain_gids)
|
if (!retain_gids)
|
||||||
|
{
|
||||||
glyph_map->set (glyphs[i], i);
|
glyph_map->set (glyphs[i], i);
|
||||||
|
reverse_glyph_map->set (i, glyphs[i]);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
glyph_map->set (glyphs[i], glyphs[i]);
|
glyph_map->set (glyphs[i], glyphs[i]);
|
||||||
|
reverse_glyph_map->set (glyphs[i], glyphs[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!retain_gids || glyphs.length == 0)
|
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->dest = hb_face_builder_create ();
|
||||||
plan->codepoint_to_glyph = hb_map_create();
|
plan->codepoint_to_glyph = hb_map_create();
|
||||||
plan->glyph_map = hb_map_create();
|
plan->glyph_map = hb_map_create();
|
||||||
|
plan->reverse_glyph_map = hb_map_create();
|
||||||
plan->glyphset = _populate_gids_to_retain (face,
|
plan->glyphset = _populate_gids_to_retain (face,
|
||||||
input->unicodes,
|
input->unicodes,
|
||||||
!plan->drop_layout,
|
!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,
|
_create_old_gid_to_new_gid_map (input->retain_gids,
|
||||||
plan->glyphs,
|
plan->glyphs,
|
||||||
plan->glyph_map,
|
plan->glyph_map,
|
||||||
|
plan->reverse_glyph_map,
|
||||||
&plan->num_glyphs);
|
&plan->num_glyphs);
|
||||||
|
|
||||||
return plan;
|
return plan;
|
||||||
|
@ -233,6 +242,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
|
||||||
hb_face_destroy (plan->dest);
|
hb_face_destroy (plan->dest);
|
||||||
hb_map_destroy (plan->codepoint_to_glyph);
|
hb_map_destroy (plan->codepoint_to_glyph);
|
||||||
hb_map_destroy (plan->glyph_map);
|
hb_map_destroy (plan->glyph_map);
|
||||||
|
hb_map_destroy (plan->reverse_glyph_map);
|
||||||
hb_set_destroy (plan->glyphset);
|
hb_set_destroy (plan->glyphset);
|
||||||
|
|
||||||
free (plan);
|
free (plan);
|
||||||
|
|
|
@ -45,11 +45,14 @@ struct hb_subset_plan_t
|
||||||
// For each cp that we'd like to retain maps to the corresponding gid.
|
// For each cp that we'd like to retain maps to the corresponding gid.
|
||||||
hb_set_t *unicodes;
|
hb_set_t *unicodes;
|
||||||
|
|
||||||
|
// The glyph subset
|
||||||
hb_vector_t<hb_codepoint_t> glyphs;
|
hb_vector_t<hb_codepoint_t> glyphs;
|
||||||
hb_set_t *glyphset;
|
hb_set_t *glyphset;
|
||||||
|
|
||||||
hb_map_t *codepoint_to_glyph;
|
hb_map_t *codepoint_to_glyph;
|
||||||
|
|
||||||
|
// Old -> New glyph id mapping
|
||||||
hb_map_t *glyph_map;
|
hb_map_t *glyph_map;
|
||||||
|
hb_map_t *reverse_glyph_map;
|
||||||
unsigned int num_glyphs;
|
unsigned int num_glyphs;
|
||||||
|
|
||||||
// Plan is only good for a specific source/dest so keep them with it
|
// 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;
|
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
|
bool
|
||||||
add_table (hb_tag_t tag,
|
add_table (hb_tag_t tag,
|
||||||
hb_blob_t *contents)
|
hb_blob_t *contents)
|
||||||
|
|
Loading…
Reference in New Issue