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 */,
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.");
*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",
}
static void
-_update_components (hb_subset_plan_t * plan,
- char * glyph_start,
- unsigned int length)
+_update_components (const hb_subset_plan_t *plan,
+ char *glyph_start,
+ unsigned int length)
{
OT::glyf::CompositeGlyphHeader::Iterator iterator;
if (OT::glyf::CompositeGlyphHeader::get_iterator (glyph_start,
}
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,
- hb_vector_t<unsigned int> &instruction_ranges,
+ hb_vector_t<unsigned int> &instruction_ranges,
unsigned int glyf_prime_size,
char *glyf_prime_data /* OUT */,
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))))
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,
// 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,
if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf,
glyphs_to_retain,
+ plan->glyph_map,
plan->drop_hints,
use_short_loca,
&glyf_prime_size,
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;
}
{
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;
+}
}
static void
-_create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
- hb_map_t *glyph_map)
+_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++) {
- glyph_map->set (glyphs[i], i);
+ if (!retain_gids)
+ glyph_map->set (glyphs[i], i);
+ else
+ glyph_map->set (glyphs[i], glyphs[i]);
}
}
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;