From 6012d3b228bc30397ab46eda48776fb414043315 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 1 Dec 2022 17:33:53 -0700 Subject: [PATCH] [subset-cff] Write out charstrings zerocopy to serializer --- src/hb-serialize.hh | 21 +++++++++++++++++---- src/hb-subset-cff1.cc | 8 +++++++- src/hb-subset-cff2.cc | 8 +++++++- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 3a67362d2..d92519910 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -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; diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index d46e102f2..538f28f5a 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -742,9 +742,15 @@ static bool _serialize_cff1 (hb_serialize_context_t *c, /* CharStrings */ { + c->push (); + + unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings); + if (unlikely (!c->start_zerocopy (total_size))) + return false; + CFF1CharStrings *cs = c->start_embed (); 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 diff --git a/src/hb-subset-cff2.cc b/src/hb-subset-cff2.cc index 837e0c674..ac7ea4e33 100644 --- a/src/hb-subset-cff2.cc +++ b/src/hb-subset-cff2.cc @@ -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 (); 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