[subset] Don't pad glyphs when using long loca.

This commit is contained in:
Garret Rieger 2021-11-26 14:19:39 -08:00 committed by Behdad Esfahbod
parent d9660fd58a
commit 599143824c
16 changed files with 22 additions and 14 deletions

View File

@ -93,22 +93,16 @@ struct glyf
template<typename Iterator, template<typename Iterator,
hb_requires (hb_is_source_of (Iterator, unsigned int))> hb_requires (hb_is_source_of (Iterator, unsigned int))>
static bool static bool
_add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets) _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca)
{ {
unsigned max_offset =
+ padded_offsets
| hb_reduce (hb_add, 0)
;
unsigned num_offsets = padded_offsets.len () + 1; unsigned num_offsets = padded_offsets.len () + 1;
bool use_short_loca = max_offset < 0x1FFFF;
unsigned entry_size = use_short_loca ? 2 : 4; unsigned entry_size = use_short_loca ? 2 : 4;
char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets); char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets);
if (unlikely (!loca_prime_data)) return false; if (unlikely (!loca_prime_data)) return false;
DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d " DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d",
"max_offset %d size %d", entry_size, num_offsets, entry_size * num_offsets);
entry_size, num_offsets, max_offset, entry_size * num_offsets);
if (use_short_loca) if (use_short_loca)
_write_loca (padded_offsets, 1, hb_array ((HBUINT16 *) loca_prime_data, num_offsets)); _write_loca (padded_offsets, 1, hb_array ((HBUINT16 *) loca_prime_data, num_offsets));
@ -151,11 +145,12 @@ struct glyf
template <typename Iterator> template <typename Iterator>
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
Iterator it, Iterator it,
bool use_short_loca,
const hb_subset_plan_t *plan) const hb_subset_plan_t *plan)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
unsigned init_len = c->length (); unsigned init_len = c->length ();
for (const auto &_ : it) _.serialize (c, plan); for (const auto &_ : it) _.serialize (c, use_short_loca, plan);
/* As a special case when all glyph in the font are empty, add a zero byte /* As a special case when all glyph in the font are empty, add a zero byte
* to the table, so that OTS doesnt reject it, and to make the table work * to the table, so that OTS doesnt reject it, and to make the table work
@ -183,16 +178,28 @@ struct glyf
hb_vector_t<SubsetGlyph> glyphs; hb_vector_t<SubsetGlyph> glyphs;
_populate_subset_glyphs (c->plan, &glyphs); _populate_subset_glyphs (c->plan, &glyphs);
glyf_prime->serialize (c->serializer, hb_iter (glyphs), c->plan);
auto padded_offsets = auto padded_offsets =
+ hb_iter (glyphs) + hb_iter (glyphs)
| hb_map (&SubsetGlyph::padded_size) | hb_map (&SubsetGlyph::padded_size)
; ;
unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
bool use_short_loca = max_offset < 0x1FFFF;
glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan);
if (!use_short_loca) {
padded_offsets =
+ hb_iter (glyphs)
| hb_map (&SubsetGlyph::length)
;
}
if (unlikely (c->serializer->in_error ())) return_trace (false); if (unlikely (c->serializer->in_error ())) return_trace (false);
return_trace (c->serializer->check_success (_add_loca_and_head (c->plan, return_trace (c->serializer->check_success (_add_loca_and_head (c->plan,
padded_offsets))); padded_offsets,
use_short_loca)));
} }
template <typename SubsetGlyph> template <typename SubsetGlyph>
@ -1269,13 +1276,14 @@ struct glyf
hb_bytes_t dest_end; /* region of source_glyph to copy second */ hb_bytes_t dest_end; /* region of source_glyph to copy second */
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
bool use_short_loca,
const hb_subset_plan_t *plan) const const hb_subset_plan_t *plan) const
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
hb_bytes_t dest_glyph = dest_start.copy (c); hb_bytes_t dest_glyph = dest_start.copy (c);
dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length); dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
unsigned int pad_length = padding (); unsigned int pad_length = use_short_loca ? padding () : 0;
DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length); DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
HBUINT8 pad; HBUINT8 pad;