[subset] Glyf by iter now runs but fails tests
This commit is contained in:
parent
f8de063b48
commit
ab3fe5de2b
@ -80,20 +80,35 @@ struct glyf
|
|||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Iterator, typename EntryType>
|
||||||
|
static void
|
||||||
|
_write_loca (Iterator it, unsigned size_denom, char * loca_data)
|
||||||
|
{
|
||||||
|
unsigned int offset = 0;
|
||||||
|
+ it
|
||||||
|
| hb_apply ([&] (hb_bytes_t _) {
|
||||||
|
offset += _.length / size_denom;
|
||||||
|
EntryType *entry = (EntryType *) loca_data;
|
||||||
|
*entry = offset;
|
||||||
|
loca_data += entry->get_size();
|
||||||
|
});
|
||||||
|
EntryType *entry = (EntryType *) loca_data;
|
||||||
|
*entry = offset;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
bool serialize(hb_serialize_context_t *c,
|
bool serialize(hb_serialize_context_t *c,
|
||||||
Iterator it)
|
Iterator it)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
|
||||||
// pad glyphs to 2-byte boundaries to permit short loca
|
// pad glyphs to 2-byte boundaries to permit short loca
|
||||||
HBUINT8 pad;
|
HBUINT8 pad;
|
||||||
|
|
||||||
+ it
|
+ it
|
||||||
| hb_apply ( [&] (hb_bytes_t glyph) {
|
| hb_apply ( [&] (hb_bytes_t glyph) {
|
||||||
glyph.copy(c);
|
glyph.copy(c);
|
||||||
if (glyph.length % 2) c->extend(pad);
|
if (glyph.length % 2) c->embed(pad);
|
||||||
});
|
});
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,53 +122,68 @@ struct glyf
|
|||||||
OT::glyf::accelerator_t glyf;
|
OT::glyf::accelerator_t glyf;
|
||||||
glyf.init (c->plan->source);
|
glyf.init (c->plan->source);
|
||||||
|
|
||||||
// stream new-gids => glyph to keep
|
// make an iterator of per-glyph hb_bytes_t.
|
||||||
// if dropping hints the glyph to keep doesn't have them anymore
|
// unpadded, hints removed if that was requested.
|
||||||
|
unsigned int glyf_padded_size = 0; //
|
||||||
auto it =
|
auto it =
|
||||||
+ hb_iota (c->plan->num_output_glyphs ())
|
+ hb_range (c->plan->num_output_glyphs ())
|
||||||
| hb_map ([&] (hb_codepoint_t new_gid) {
|
| hb_map ([&] (hb_codepoint_t new_gid) {
|
||||||
hb_codepoint_t old_gid;
|
hb_codepoint_t old_gid;
|
||||||
// should never happen fail, ALL old gids should be mapped
|
|
||||||
|
// should never fail, ALL old gids should be mapped
|
||||||
if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid)) return hb_bytes_t ();
|
if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid)) return hb_bytes_t ();
|
||||||
|
|
||||||
unsigned int start_offset, end_offset;
|
unsigned int start_offset, end_offset;
|
||||||
if (unlikely (!(glyf.get_offsets (old_gid, &start_offset, &end_offset) &&
|
if (unlikely (!(glyf.get_offsets (old_gid, &start_offset, &end_offset) &&
|
||||||
glyf.remove_padding (start_offset, &end_offset))))
|
glyf.remove_padding (start_offset, &end_offset))))
|
||||||
{
|
{
|
||||||
// TODO signal irreversible error
|
// TODO signal fatal error
|
||||||
return hb_bytes_t ();
|
return hb_bytes_t ();
|
||||||
}
|
}
|
||||||
hb_bytes_t glyph ((const char *) this, end_offset - start_offset);
|
hb_bytes_t glyph ((const char *) this, end_offset - start_offset);
|
||||||
|
|
||||||
// if dropping hints, find hints region and subtract it
|
// if dropping hints, find hints region and subtract it
|
||||||
if (c->plan->drop_hints) {
|
if (c->plan->drop_hints) {
|
||||||
unsigned int instruction_length;
|
unsigned int instruction_length;
|
||||||
if (!glyf.get_instruction_length (glyph, &instruction_length))
|
if (!glyf.get_instruction_length (glyph, &instruction_length))
|
||||||
{
|
{
|
||||||
// TODO signal irreversible failure
|
// TODO signal fatal error
|
||||||
return hb_bytes_t ();
|
return hb_bytes_t ();
|
||||||
}
|
}
|
||||||
glyph = hb_bytes_t (&glyph, glyph.length - instruction_length);
|
glyph = hb_bytes_t (&glyph, glyph.length - instruction_length);
|
||||||
}
|
}
|
||||||
|
glyf_padded_size += glyph.length + glyph.length % 2;
|
||||||
return glyph;
|
return glyph;
|
||||||
});
|
});
|
||||||
|
|
||||||
glyf_prime->serialize (c->serializer, it);
|
glyf_prime->serialize (c->serializer, it);
|
||||||
|
|
||||||
// we know enough to write loca
|
// TODO whats the right way to serialize loca?
|
||||||
// TODO calculate size, do we need two or four byte loca entries
|
// _subset2 will think these bytes are part of glyf if we write to serializer
|
||||||
unsigned int offset = 0;
|
bool use_short_loca = glyf_padded_size > 131070;
|
||||||
HBUINT16 loca_entry;
|
unsigned int loca_prime_size = (c->plan->num_output_glyphs () + 1) * (use_short_loca ? 2 : 4);
|
||||||
loca *loca_prime = c->serializer->start_embed <loca> ();
|
char *loca_prime_data = (char *) calloc(1, loca_prime_size);
|
||||||
+ hb_enumerate (it)
|
|
||||||
| hb_apply ([&] (hb_pair_t<unsigned, hb_bytes_t> p) {
|
if (use_short_loca)
|
||||||
offset += p.second.length;
|
{
|
||||||
loca_entry = offset / 2;
|
_write_loca <decltype (it), HBUINT16> (it, 2, loca_prime_data);
|
||||||
c->serializer->embed(loca_entry);
|
}
|
||||||
});
|
else
|
||||||
// one for the road
|
{
|
||||||
c->serializer->embed(loca_entry);
|
_write_loca <decltype (it), HBUINT32> (it, 1, loca_prime_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_blob_t * loca_blob = hb_blob_create (loca_prime_data,
|
||||||
|
loca_prime_size,
|
||||||
|
HB_MEMORY_MODE_READONLY,
|
||||||
|
loca_prime_data,
|
||||||
|
free);
|
||||||
|
if (unlikely (! (c->plan->add_table (HB_OT_TAG_loca, loca_blob)
|
||||||
|
&& _add_head_and_set_loca_version(c->plan, use_short_loca))))
|
||||||
|
{
|
||||||
|
// TODO signal fatal error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user