Add retain_gids option to subset input. Update glyf and loca handling to respect retain_gids.
This commit is contained in:
parent
fe53292310
commit
b7f971884e
|
@ -32,6 +32,7 @@
|
|||
static bool
|
||||
_calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
|
||||
hb_vector_t<hb_codepoint_t> &glyph_ids,
|
||||
const hb_map_t *glyph_map,
|
||||
hb_bool_t drop_hints,
|
||||
bool *use_short_loca /* OUT */,
|
||||
unsigned int *glyf_size /* OUT */,
|
||||
|
@ -39,9 +40,12 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
|
|||
hb_vector_t<unsigned int> *instruction_ranges /* OUT */)
|
||||
{
|
||||
unsigned int total = 0;
|
||||
hb_codepoint_t max_new_gid = 0;
|
||||
for (unsigned int i = 0; i < glyph_ids.length; i++)
|
||||
{
|
||||
hb_codepoint_t next_glyph = glyph_ids[i];
|
||||
hb_codepoint_t next_glyph_new_gid = glyph_map->get (next_glyph);
|
||||
max_new_gid = MAX (max_new_gid, next_glyph_new_gid);
|
||||
if (!instruction_ranges->resize (instruction_ranges->length + 2))
|
||||
{
|
||||
DEBUG_MSG(SUBSET, nullptr, "Failed to resize instruction_ranges.");
|
||||
|
@ -79,7 +83,7 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
|
|||
|
||||
*glyf_size = total;
|
||||
*use_short_loca = (total <= 131070);
|
||||
*loca_size = (glyph_ids.length + 1)
|
||||
*loca_size = (max_new_gid + 2)
|
||||
* (*use_short_loca ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32));
|
||||
|
||||
DEBUG_MSG(SUBSET, nullptr, "preparing to subset glyf: final size %d, loca size %d, using %s loca",
|
||||
|
@ -117,7 +121,7 @@ _write_loca_entry (unsigned int id,
|
|||
}
|
||||
|
||||
static void
|
||||
_update_components (hb_subset_plan_t * plan,
|
||||
_update_components (const hb_subset_plan_t *plan,
|
||||
char *glyph_start,
|
||||
unsigned int length)
|
||||
{
|
||||
|
@ -153,7 +157,7 @@ static bool _remove_composite_instruction_flag (char *glyf_prime, unsigned int l
|
|||
}
|
||||
|
||||
static bool
|
||||
_write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
||||
_write_glyf_and_loca_prime (const hb_subset_plan_t *plan,
|
||||
const OT::glyf::accelerator_t &glyf,
|
||||
const char *glyf_data,
|
||||
bool use_short_loca,
|
||||
|
@ -163,12 +167,27 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
|||
unsigned int loca_prime_size,
|
||||
char *loca_prime_data /* OUT */)
|
||||
{
|
||||
hb_vector_t<hb_codepoint_t> &glyph_ids = plan->glyphs;
|
||||
const hb_vector_t<hb_codepoint_t> &glyph_ids = plan->glyphs;
|
||||
const hb_map_t *glyph_map = plan->glyph_map;
|
||||
char *glyf_prime_data_next = glyf_prime_data;
|
||||
|
||||
bool success = true;
|
||||
hb_codepoint_t gid = 0;
|
||||
for (unsigned int i = 0; i < glyph_ids.length; i++)
|
||||
{
|
||||
while (gid < glyph_map->get (glyph_ids[i]))
|
||||
{
|
||||
// If we are retaining existing gids then there will potentially be gaps
|
||||
// in the loca table between glyphs. Fill in this gap with glyphs that have
|
||||
// no outlines.
|
||||
success = success && _write_loca_entry (gid,
|
||||
glyf_prime_data_next - glyf_prime_data,
|
||||
use_short_loca,
|
||||
loca_prime_data,
|
||||
loca_prime_size);
|
||||
gid++;
|
||||
}
|
||||
|
||||
unsigned int start_offset, end_offset;
|
||||
if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset) &&
|
||||
glyf.remove_padding (start_offset, &end_offset))))
|
||||
|
@ -204,7 +223,7 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
|||
memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2);
|
||||
}
|
||||
|
||||
success = success && _write_loca_entry (i,
|
||||
success = success && _write_loca_entry (gid,
|
||||
glyf_prime_data_next - glyf_prime_data,
|
||||
use_short_loca,
|
||||
loca_prime_data,
|
||||
|
@ -213,9 +232,10 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
|||
|
||||
// TODO: don't align to two bytes if using long loca.
|
||||
glyf_prime_data_next += length + (length % 2); // Align to 2 bytes for short loca.
|
||||
gid++;
|
||||
}
|
||||
|
||||
success = success && _write_loca_entry (glyph_ids.length,
|
||||
success = success && _write_loca_entry (gid,
|
||||
glyf_prime_data_next - glyf_prime_data,
|
||||
use_short_loca,
|
||||
loca_prime_data,
|
||||
|
@ -241,6 +261,7 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf,
|
|||
|
||||
if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf,
|
||||
glyphs_to_retain,
|
||||
plan->glyph_map,
|
||||
plan->drop_hints,
|
||||
use_short_loca,
|
||||
&glyf_prime_size,
|
||||
|
|
|
@ -44,7 +44,10 @@ hb_subset_input_create_or_fail ()
|
|||
|
||||
input->unicodes = hb_set_create ();
|
||||
input->glyphs = hb_set_create ();
|
||||
input->drop_hints = false;
|
||||
input->drop_layout = true;
|
||||
input->desubroutinize = false;
|
||||
input->retain_gids = false;
|
||||
|
||||
return input;
|
||||
}
|
||||
|
@ -144,3 +147,27 @@ hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input)
|
|||
{
|
||||
return subset_input->desubroutinize;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_input_set_retain_gids:
|
||||
* @subset_input: a subset_input.
|
||||
* @retain_gids: If true the subsetter will not renumber glyph ids.
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
HB_EXTERN void
|
||||
hb_subset_input_set_retain_gids (hb_subset_input_t *subset_input,
|
||||
hb_bool_t retain_gids)
|
||||
{
|
||||
subset_input->retain_gids = retain_gids;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_subset_input_get_retain_gids:
|
||||
* Returns: value of retain_gids.
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_subset_input_get_retain_gids (hb_subset_input_t *subset_input)
|
||||
{
|
||||
return subset_input->retain_gids;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ struct hb_subset_input_t
|
|||
bool drop_hints : 1;
|
||||
bool drop_layout : 1;
|
||||
bool desubroutinize : 1;
|
||||
bool retain_gids : 1;
|
||||
/* TODO
|
||||
*
|
||||
* features
|
||||
|
|
|
@ -156,11 +156,15 @@ _populate_gids_to_retain (hb_face_t *face,
|
|||
}
|
||||
|
||||
static void
|
||||
_create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
|
||||
_create_old_gid_to_new_gid_map (bool retain_gids,
|
||||
const hb_vector_t<hb_codepoint_t> &glyphs,
|
||||
hb_map_t *glyph_map)
|
||||
{
|
||||
for (unsigned int i = 0; i < glyphs.length; i++) {
|
||||
if (!retain_gids)
|
||||
glyph_map->set (glyphs[i], i);
|
||||
else
|
||||
glyph_map->set (glyphs[i], glyphs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +199,9 @@ hb_subset_plan_create (hb_face_t *face,
|
|||
plan->unicodes,
|
||||
plan->codepoint_to_glyph,
|
||||
&plan->glyphs);
|
||||
_create_old_gid_to_new_gid_map (plan->glyphs,
|
||||
|
||||
_create_old_gid_to_new_gid_map (input->retain_gids,
|
||||
plan->glyphs,
|
||||
plan->glyph_map);
|
||||
|
||||
return plan;
|
||||
|
|
|
@ -72,6 +72,12 @@ hb_subset_input_set_desubroutinize (hb_subset_input_t *subset_input,
|
|||
HB_EXTERN hb_bool_t
|
||||
hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_subset_input_set_retain_gids (hb_subset_input_t *subset_input,
|
||||
hb_bool_t retain_gids);
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_subset_input_get_retain_gids (hb_subset_input_t *subset_input);
|
||||
|
||||
/* hb_subset () */
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_subset (hb_face_t *source, hb_subset_input_t *input);
|
||||
|
|
Loading…
Reference in New Issue