mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-14 17:13:40 +00:00
[instancer] add serialize () for gvar
This commit is contained in:
parent
3c86b096a9
commit
746b112faf
3 changed files with 120 additions and 1 deletions
|
@ -975,6 +975,7 @@ struct TupleVariationData
|
|||
tuple_vars.fini ();
|
||||
}
|
||||
|
||||
explicit operator bool () const { return bool (tuple_vars); }
|
||||
unsigned get_var_count () const
|
||||
{
|
||||
unsigned count = tuple_vars.length;
|
||||
|
@ -1517,9 +1518,12 @@ struct TupleVariationData
|
|||
|
||||
bool serialize (hb_serialize_context_t *c,
|
||||
bool is_gvar,
|
||||
tuple_variations_t& tuple_variations) const
|
||||
const tuple_variations_t& tuple_variations) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
/* empty tuple variations, just return and skip serialization. */
|
||||
if (!tuple_variations) return_trace (true);
|
||||
|
||||
auto *out = c->start_embed (this);
|
||||
if (unlikely (!c->extend_min (out))) return_trace (false);
|
||||
|
||||
|
|
|
@ -131,6 +131,7 @@ struct cvar
|
|||
TupleVariationData::tuple_variations_t& tuple_variations) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (!tuple_variations) return_trace (false);
|
||||
if (unlikely (!c->embed (version))) return_trace (false);
|
||||
|
||||
return_trace (tupleVariationData.serialize (c, false, tuple_variations));
|
||||
|
|
|
@ -58,6 +58,15 @@ struct glyph_variations_t
|
|||
unsigned compiled_shared_tuples_count () const
|
||||
{ return shared_tuples_count; }
|
||||
|
||||
unsigned compiled_byte_size () const
|
||||
{
|
||||
unsigned byte_size = 0;
|
||||
for (const auto& _ : glyph_variations)
|
||||
byte_size += _.get_compiled_byte_size ();
|
||||
|
||||
return byte_size;
|
||||
}
|
||||
|
||||
bool create_from_glyphs_var_data (unsigned axis_count,
|
||||
const hb_array_t<const F2DOT14> shared_tuples,
|
||||
const hb_subset_plan_t *plan,
|
||||
|
@ -218,6 +227,66 @@ struct glyph_variations_t
|
|||
else if (has_b) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
template<typename Iterator,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
bool serialize_glyph_var_data (hb_serialize_context_t *c,
|
||||
Iterator it,
|
||||
bool long_offset,
|
||||
unsigned num_glyphs,
|
||||
char* glyph_var_data_offsets /* OUT: glyph var data offsets array */) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
|
||||
if (long_offset)
|
||||
{
|
||||
((HBUINT32 *) glyph_var_data_offsets)[0] = 0;
|
||||
glyph_var_data_offsets += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
((HBUINT16 *) glyph_var_data_offsets)[0] = 0;
|
||||
glyph_var_data_offsets += 2;
|
||||
}
|
||||
unsigned glyph_offset = 0;
|
||||
hb_codepoint_t last_gid = 0;
|
||||
unsigned idx = 0;
|
||||
|
||||
TupleVariationData* cur_glyph = c->start_embed<TupleVariationData> ();
|
||||
if (!cur_glyph) return_trace (false);
|
||||
for (auto &_ : it)
|
||||
{
|
||||
hb_codepoint_t gid = _.first;
|
||||
if (long_offset)
|
||||
for (; last_gid < gid; last_gid++)
|
||||
((HBUINT32 *) glyph_var_data_offsets)[last_gid] = glyph_offset;
|
||||
else
|
||||
for (; last_gid < gid; last_gid++)
|
||||
((HBUINT16 *) glyph_var_data_offsets)[last_gid] = glyph_offset / 2;
|
||||
|
||||
if (idx >= glyph_variations.length) return_trace (false);
|
||||
if (!cur_glyph->serialize (c, true, glyph_variations[idx])) return_trace (false);
|
||||
TupleVariationData* next_glyph = c->start_embed<TupleVariationData> ();
|
||||
glyph_offset += (char *) next_glyph - (char *) cur_glyph;
|
||||
|
||||
if (long_offset)
|
||||
((HBUINT32 *) glyph_var_data_offsets)[gid] = glyph_offset;
|
||||
else
|
||||
((HBUINT16 *) glyph_var_data_offsets)[gid] = glyph_offset / 2;
|
||||
|
||||
last_gid++;
|
||||
idx++;
|
||||
cur_glyph = next_glyph;
|
||||
}
|
||||
|
||||
if (long_offset)
|
||||
for (; last_gid < num_glyphs; last_gid++)
|
||||
((HBUINT32 *) glyph_var_data_offsets)[last_gid] = glyph_offset;
|
||||
else
|
||||
for (; last_gid < num_glyphs; last_gid++)
|
||||
((HBUINT16 *) glyph_var_data_offsets)[last_gid] = glyph_offset / 2;
|
||||
return_trace (true);
|
||||
}
|
||||
};
|
||||
|
||||
struct gvar
|
||||
|
@ -264,6 +333,51 @@ struct gvar
|
|||
return glyph_vars.create_from_glyphs_var_data (axisCount, shared_tuples, plan, new_gid_var_data_map);
|
||||
}
|
||||
|
||||
template<typename Iterator,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
bool serialize (hb_serialize_context_t *c,
|
||||
const glyph_variations_t& glyph_vars,
|
||||
Iterator it,
|
||||
unsigned axis_count,
|
||||
unsigned num_glyphs) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
gvar *out = c->allocate_min<gvar> ();
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
out->version.major = 1;
|
||||
out->version.minor = 0;
|
||||
out->axisCount = axis_count;
|
||||
out->glyphCountX = hb_min (0xFFFFu, num_glyphs);
|
||||
|
||||
unsigned glyph_var_data_size = glyph_vars.compiled_byte_size ();
|
||||
bool long_offset = glyph_var_data_size & ~0xFFFFu;
|
||||
out->flags = long_offset ? 1 : 0;
|
||||
|
||||
HBUINT8 *glyph_var_data_offsets = c->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1), false);
|
||||
if (!glyph_var_data_offsets) return_trace (false);
|
||||
|
||||
/* shared tuples */
|
||||
unsigned shared_tuple_count = glyph_vars.compiled_shared_tuples_count ();
|
||||
out->sharedTupleCount = shared_tuple_count;
|
||||
|
||||
if (!shared_tuple_count)
|
||||
out->sharedTuples = 0;
|
||||
else
|
||||
{
|
||||
hb_array_t<const char> shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c);
|
||||
if (!shared_tuples.arrayZ) return_trace (false);
|
||||
out->sharedTuples = shared_tuples.arrayZ - (char *) out;
|
||||
}
|
||||
|
||||
char *glyph_var_data = c->start_embed<char> ();
|
||||
if (!glyph_var_data) return_trace (false);
|
||||
out->dataZ = glyph_var_data - (char *) out;
|
||||
|
||||
return_trace (glyph_vars.serialize_glyph_var_data (c, it, long_offset, num_glyphs,
|
||||
(char *) glyph_var_data_offsets));
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
|
|
Loading…
Add table
Reference in a new issue