From: Qunxin Liu Date: Tue, 16 Apr 2019 18:20:58 +0000 (-0700) Subject: [subset] update name table subsetting with new serializer X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9ad14f56b6cf2a345104b3a897b52a1f4c0f33a5;p=platform%2Fupstream%2FlibHarfBuzzSharp.git [subset] update name table subsetting with new serializer --- diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index cdb8dba..fde808c 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -95,28 +95,6 @@ struct NameRecord return UNSUPPORTED; } - bool serialize (hb_serialize_context_t *c, const NameRecord& origin_namerecord, unsigned int *new_offset) - { - TRACE_SERIALIZE (this); - - if (unlikely (!c->allocate_size (NameRecord::static_size))) - { - DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for NameRecord: %d.", - NameRecord::static_size); - return_trace (false); - } - - this->platformID = origin_namerecord.platformID; - this->encodingID = origin_namerecord.encodingID; - this->languageID = origin_namerecord.languageID; - this->nameID = origin_namerecord.nameID; - this->length = origin_namerecord.length; - this->offset = *new_offset; - *new_offset += origin_namerecord.length; - - return_trace (true); - } - bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -208,36 +186,32 @@ struct name return result; } - bool serialize (hb_serialize_context_t *c, - const name *source_name, - const hb_subset_plan_t *plan, - const hb_vector_t& name_record_idx_to_retain) + bool serialize_name_record (hb_serialize_context_t *c, + const name *source_name, + const hb_vector_t& name_record_idx_to_retain) { - TRACE_SERIALIZE (this); - - if (unlikely (!c->extend_min ((*this)))) return_trace (false); - - this->format = source_name->format; - this->count = name_record_idx_to_retain.length; - this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size; - - //write new NameRecord - unsigned int new_offset = 0; for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) { unsigned int idx = name_record_idx_to_retain[i]; if (unlikely (idx >= source_name->count)) { DEBUG_MSG (SUBSET, nullptr, "Invalid index: %d.", idx); - return_trace (false); + return false; } - const NameRecord &namerec = source_name->nameRecordZ[idx]; - - if (!c->start_embed ()->serialize (c, namerec, &new_offset)) - return_trace (false); + c->push (); + if (!c->embed (source_name->nameRecordZ[idx])) + return false; } + return true; + } + + bool serialize_strings (hb_serialize_context_t *c, + const name *source_name, + const hb_subset_plan_t *plan, + const hb_vector_t& name_record_idx_to_retain) + { hb_face_t *face = plan->source; accelerator_t acc; acc.init (face); @@ -246,16 +220,18 @@ struct name { unsigned int idx = name_record_idx_to_retain[i]; unsigned int size = acc.get_name (idx).get_size (); - char *new_pos = c->allocate_size (size); + c->push (); + char *new_pos = c->allocate_size (size); + if (unlikely (new_pos == nullptr)) { acc.fini (); - DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %d.", - size); - return_trace (false); + DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %u.", + size); + return false; } - + const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ; unsigned int name_record_offset = source_name->nameRecordZ[idx].offset; @@ -263,6 +239,57 @@ struct name } acc.fini (); + return true; + } + + bool pack_record_and_strings (name *dest_name_unpacked, + hb_serialize_context_t *c, + unsigned length) + { + hb_hashmap_t id_str_idx_map; + for (int i = length-1; i >= 0; i--) + { + unsigned objidx = c->pop_pack (); + id_str_idx_map.set ((unsigned)i, objidx); + } + + const void *base = & (dest_name_unpacked->nameRecordZ[length]); + for (int i = length-1; i >= 0; i--) + { + unsigned str_idx = id_str_idx_map.get ((unsigned)i); + NameRecord& namerecord = dest_name_unpacked->nameRecordZ[i]; + c->add_link (namerecord.offset, str_idx, base); + c->pop_pack (); + } + + if (c->in_error ()) + return false; + + return true; + } + + bool serialize (hb_serialize_context_t *c, + const name *source_name, + const hb_subset_plan_t *plan, + const hb_vector_t& name_record_idx_to_retain) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->extend_min ((*this)))) return_trace (false); + + this->format = source_name->format; + this->count = name_record_idx_to_retain.length; + this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size; + + + if (!serialize_name_record (c, source_name, name_record_idx_to_retain)) + return_trace (false); + + if (!serialize_strings (c, source_name, plan, name_record_idx_to_retain)) + return_trace (false); + + if (!pack_record_and_strings (this, c, name_record_idx_to_retain.length)) + return_trace (false); return_trace (true); } @@ -289,13 +316,10 @@ struct name c.end_serialize (); return false; } + c.end_serialize (); - hb_blob_t *name_prime_blob = hb_blob_create ((const char *) dest, - dest_size, - HB_MEMORY_MODE_READONLY, - dest, - free); + hb_blob_t *name_prime_blob = c.copy_blob (); bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob); hb_blob_destroy (name_prime_blob);