提交 9ad14f56 编写于 作者: Q Qunxin Liu 提交者: Garret Rieger

[subset] update name table subsetting with new serializer

上级 6faac8df
...@@ -95,28 +95,6 @@ struct NameRecord ...@@ -95,28 +95,6 @@ struct NameRecord
return UNSUPPORTED; 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 bool sanitize (hb_sanitize_context_t *c, const void *base) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
...@@ -208,36 +186,32 @@ struct name ...@@ -208,36 +186,32 @@ struct name
return result; return result;
} }
bool serialize (hb_serialize_context_t *c, bool serialize_name_record (hb_serialize_context_t *c,
const name *source_name, const name *source_name,
const hb_subset_plan_t *plan, const hb_vector_t<unsigned int>& name_record_idx_to_retain)
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++) for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++)
{ {
unsigned int idx = name_record_idx_to_retain[i]; unsigned int idx = name_record_idx_to_retain[i];
if (unlikely (idx >= source_name->count)) if (unlikely (idx >= source_name->count))
{ {
DEBUG_MSG (SUBSET, nullptr, "Invalid index: %d.", idx); DEBUG_MSG (SUBSET, nullptr, "Invalid index: %d.", idx);
return_trace (false); return false;
} }
const NameRecord &namerec = source_name->nameRecordZ[idx]; c->push<NameRecord> ();
if (!c->embed (source_name->nameRecordZ[idx]))
if (!c->start_embed<NameRecord> ()->serialize (c, namerec, &new_offset)) return false;
return_trace (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; hb_face_t *face = plan->source;
accelerator_t acc; accelerator_t acc;
acc.init (face); acc.init (face);
...@@ -246,16 +220,18 @@ struct name ...@@ -246,16 +220,18 @@ struct name
{ {
unsigned int idx = name_record_idx_to_retain[i]; unsigned int idx = name_record_idx_to_retain[i];
unsigned int size = acc.get_name (idx).get_size (); 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)) if (unlikely (new_pos == nullptr))
{ {
acc.fini (); acc.fini ();
DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %d.", DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %u.",
size); size);
return_trace (false); return false;
} }
const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ; const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ;
unsigned int name_record_offset = source_name->nameRecordZ[idx].offset; unsigned int name_record_offset = source_name->nameRecordZ[idx].offset;
...@@ -263,6 +239,57 @@ struct name ...@@ -263,6 +239,57 @@ struct name
} }
acc.fini (); 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); return_trace (true);
} }
...@@ -289,13 +316,10 @@ struct name ...@@ -289,13 +316,10 @@ struct name
c.end_serialize (); c.end_serialize ();
return false; return false;
} }
c.end_serialize (); c.end_serialize ();
hb_blob_t *name_prime_blob = hb_blob_create ((const char *) dest, hb_blob_t *name_prime_blob = c.copy_blob ();
dest_size,
HB_MEMORY_MODE_READONLY,
dest,
free);
bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob); bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob);
hb_blob_destroy (name_prime_blob); hb_blob_destroy (name_prime_blob);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册