|
|
|
@ -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> (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<unsigned int>& name_record_idx_to_retain) |
|
|
|
|
bool serialize_name_record (hb_serialize_context_t *c, |
|
|
|
|
const name *source_name, |
|
|
|
|
const hb_vector_t<unsigned int>& 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<NameRecord> ()->serialize (c, namerec, &new_offset)) |
|
|
|
|
return_trace (false); |
|
|
|
|
c->push<NameRecord> (); |
|
|
|
|
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<unsigned int>& 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<char> (size); |
|
|
|
|
|
|
|
|
|
c->push<char> (); |
|
|
|
|
char *new_pos = c->allocate_size<char> (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<unsigned, unsigned, -1, 0> 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<HBUINT16> (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<unsigned int>& 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); |
|
|
|
|
|
|
|
|
|