[subset-cff] Write out charstrings zerocopy to serializer

This commit is contained in:
Behdad Esfahbod 2022-12-01 17:33:53 -07:00
parent 36e1a6339c
commit 6012d3b228
3 changed files with 31 additions and 6 deletions

View File

@ -223,6 +223,7 @@ struct hb_serialize_context_t
this->errors = HB_SERIALIZE_ERROR_NONE;
this->head = this->start;
this->tail = this->end;
this->zerocopy = nullptr;
this->debug_depth = 0;
fini ();
@ -343,8 +344,11 @@ struct hb_serialize_context_t
current = current->next;
obj->tail = head;
obj->next = nullptr;
assert (obj->head <= obj->tail);
unsigned len = obj->tail - obj->head;
head = obj->head; /* Rewind head. */
head = zerocopy ? zerocopy : obj->head; /* Rewind head. */
if (zerocopy)
assert (!share);
if (!len)
{
@ -368,7 +372,13 @@ struct hb_serialize_context_t
}
tail -= len;
memmove (tail, obj->head, len);
if (zerocopy)
{
zerocopy = nullptr;
assert (tail == obj->head);
}
else
memmove (tail, obj->head, len);
obj->head = tail;
obj->tail = tail + len;
@ -580,8 +590,11 @@ struct hb_serialize_context_t
return false;
}
assert (!this->zerocopy);
this->zerocopy = this->head;
assert (this->current->head == this->head);
this->current->head = this->head = this->tail - size;
this->current->head = this->current->tail = this->head = this->tail - size;
return true;
}
@ -721,7 +734,7 @@ struct hb_serialize_context_t
}
public:
char *start, *head, *tail, *end;
char *start, *head, *tail, *end, *zerocopy;
unsigned int debug_depth;
hb_serialize_error_t errors;

View File

@ -742,9 +742,15 @@ static bool _serialize_cff1 (hb_serialize_context_t *c,
/* CharStrings */
{
c->push<CFF1CharStrings> ();
unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings);
if (unlikely (!c->start_zerocopy (total_size)))
return false;
CFF1CharStrings *cs = c->start_embed<CFF1CharStrings> ();
if (unlikely (!cs)) return false;
c->push ();
if (likely (cs->serialize (c, plan.subset_charstrings)))
plan.info.char_strings_link = c->pop_pack (false);
else

View File

@ -361,9 +361,15 @@ static bool _serialize_cff2 (hb_serialize_context_t *c,
/* CharStrings */
{
c->push ();
unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings);
if (unlikely (!c->start_zerocopy (total_size)))
return false;
CFF2CharStrings *cs = c->start_embed<CFF2CharStrings> ();
if (unlikely (!cs)) return false;
c->push ();
if (likely (cs->serialize (c, plan.subset_charstrings)))
plan.info.char_strings_link = c->pop_pack (false);
else