const hb_subset_plan_t *plan)
{
TRACE_SERIALIZE (this);
- // pad glyphs to 2-byte boundaries to permit short loca
+
HBUINT8 pad;
pad = 0;
+ it
}
_fix_component_gids (plan, dest_glyph);
+ if (plan->drop_hints)
+ {
+ // we copied the glyph w/o instructions, just need to zero instruction length
+ _zero_instruction_length (dest_glyph);
+ }
});
// Things old impl did we now don't:
- // TODO set instruction length to 0 where appropriate
// TODO _remove_composite_instruction_flag
return_trace (true);
// make an iterator of per-glyph hb_bytes_t.
// unpadded, hints removed if that was requested.
+
+ // TODO log shows we redo a bunch of the work here; should sink this at end?
+
auto glyphs =
+ hb_range (c->plan->num_output_glyphs ())
| hb_map ([&] (hb_codepoint_t new_gid) {
}
hb_bytes_t glyph (((const char *) this) + start_offset, end_offset - start_offset);
- // if dropping hints, find hints region and subtract it
- unsigned int instruction_length = 0;
+ // if dropping hints, find hints region and chop it off the end
if (c->plan->drop_hints) {
+ unsigned int instruction_length = 0;
if (!glyf.get_instruction_length (glyph, &instruction_length))
{
// TODO signal fatal error
DEBUG_MSG(SUBSET, nullptr, "Unable to read instruction length for new_gid %d", new_gid);
return hb_bytes_t ();
}
+ DEBUG_MSG(SUBSET, nullptr, "new_gid %d drop %d instruction bytes from %d byte glyph", new_gid, instruction_length, glyph.length);
glyph = hb_bytes_t (&glyph, glyph.length - instruction_length);
}
}
}
+ static void
+ _zero_instruction_length (hb_bytes_t glyph)
+ {
+ const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
+ int16_t num_contours = (int16_t) glyph_header.numberOfContours;
+ if (num_contours > 0)
+ {
+ const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (&glyph, GlyphHeader::static_size + 2 * num_contours);
+ (HBUINT16 &) instruction_length = 0;
+ }
+ }
+
static bool
_add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
{
unsigned int * length /* OUT */) const
{
/* Empty glyph; no instructions. */
- if (glyph.get_size() < GlyphHeader::static_size)
+ if (glyph.length < GlyphHeader::static_size)
{
*length = 0;
- return true;
+ // only 0 byte glyphs are healthy when missing GlyphHeader
+ return glyph.length == 0;
}
- unsigned int start = glyph.length;
- unsigned int end = glyph.length;
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
int16_t num_contours = (int16_t) glyph_header.numberOfContours;
if (num_contours < 0)
{
+ unsigned int start = glyph.length;
+ unsigned int end = glyph.length;
CompositeGlyphHeader::Iterator composite_it;
if (unlikely (!CompositeGlyphHeader::get_iterator (&glyph, glyph.length, &composite_it))) return false;
const CompositeGlyphHeader *last;
DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside %d byte buffer", start, glyph.length);
return false;
}
+ *length = end - start;
}
else
{
return false;
}
- const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
- unsigned int start = instruction_length_offset + 2;
- unsigned int end = start + (uint16_t) instruction_length;
- if (unlikely (end > glyph.length)) // Out of bounds of the current glyph
+ const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (&glyph, instruction_length_offset);
+ if (unlikely (instruction_length_offset + instruction_length > glyph.length)) // Out of bounds of the current glyph
{
DEBUG_MSG(SUBSET, nullptr, "The instructions array overruns the glyph's boundaries.");
return false;
}
+ *length = (uint16_t) instruction_length;
}
- *length = end - start;
return true;
}