gvar::subset()

This commit is contained in:
Michiharu Ariza 2019-02-26 16:54:00 -08:00
parent eddbc9d0db
commit 0b1ae2385b
1 changed files with 71 additions and 10 deletions

View File

@ -150,10 +150,75 @@ struct gvar
{ return sanitize_shallow (c); } { return sanitize_shallow (c); }
bool subset (hb_subset_context_t *c) const bool subset (hb_subset_context_t *c) const
{ return true; } // TOOD {
TRACE_SUBSET (this);
gvar *out = c->serializer->allocate_min<gvar> ();
if (unlikely (!out)) return_trace (false);
out->version.major.set (1);
out->version.minor.set (0);
out->axisCount.set (axisCount);
out->sharedTupleCount.set (sharedTupleCount);
unsigned int num_glyphs = c->plan->num_output_glyphs ();
out->glyphCount.set (num_glyphs);
unsigned int subset_data_size = 0;
for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
{
unsigned int old_gid;
if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue;
subset_data_size += get_data_length (old_gid);
}
bool long_offset = subset_data_size & ~0xFFFFu;
out->flags.set (long_offset? 1: 0);
HBUINT8 *subset_offsets = c->serializer->allocate_size<HBUINT8> ((long_offset?HBUINT32::static_size: HBUINT16::static_size) * (num_glyphs+1));
if (!subset_offsets) return_trace (false);
char *subset_data = c->serializer->allocate_size<char>(subset_data_size);
if (!subset_data) return_trace (false);
out->dataZ.set (subset_data - (char *)out);
unsigned int glyph_offset = 0;
for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
{
unsigned int old_gid;
unsigned int length = c->plan->old_gid_for_new_gid (gid, &old_gid)? get_data_length (old_gid): 0;
if (long_offset)
((HBUINT32 *)subset_offsets)[gid].set (glyph_offset);
else
((HBUINT16 *)subset_offsets)[gid].set (glyph_offset / 2);
if (length > 0) memcpy (subset_data, get_glyph_var_data (old_gid), length);
subset_data += length;
glyph_offset += length;
}
if (long_offset)
((HBUINT32 *)subset_offsets)[num_glyphs].set (glyph_offset);
else
((HBUINT16 *)subset_offsets)[num_glyphs].set (glyph_offset / 2);
/* shared tuples */
if (!sharedTupleCount || !sharedTuples)
out->sharedTuples.set (0);
else
{
unsigned int shared_tuple_size = F2DOT14::static_size * axisCount * sharedTupleCount;
F2DOT14 *tuples = c->serializer->allocate_size<F2DOT14> (shared_tuple_size);
if (!tuples) return_trace (false);
out->sharedTuples.set ((char *)tuples - (char *)out);
memcpy (tuples, &(this+sharedTuples), shared_tuple_size);
}
return_trace (true);
}
protected: protected:
const GlyphVarData *get_glyph_var_data (unsigned int gid, unsigned int *length/*OUT*/) const const GlyphVarData *get_glyph_var_data (unsigned int gid) const
{ {
unsigned int start_offset = get_offset (gid); unsigned int start_offset = get_offset (gid);
unsigned int end_offset = get_offset (gid+1); unsigned int end_offset = get_offset (gid+1);
@ -161,17 +226,10 @@ struct gvar
if ((start_offset == end_offset) || if ((start_offset == end_offset) ||
unlikely ((start_offset > get_offset (glyphCount)) || unlikely ((start_offset > get_offset (glyphCount)) ||
(start_offset + GlyphVarData::min_size > end_offset))) (start_offset + GlyphVarData::min_size > end_offset)))
{
*length = 0;
return &Null(GlyphVarData); return &Null(GlyphVarData);
}
const GlyphVarData *var_data = &(((unsigned char *)this+start_offset)+dataZ); const GlyphVarData *var_data = &(((unsigned char *)this+start_offset)+dataZ);
if (unlikely (!var_data->check_size (axisCount, end_offset - start_offset))) if (unlikely (!var_data->check_size (axisCount, end_offset - start_offset)))
{
*length = 0;
return &Null (GlyphVarData); return &Null (GlyphVarData);
}
*length = end_offset - start_offset;
return var_data; return var_data;
} }
@ -185,6 +243,9 @@ struct gvar
return get_short_offset_array ()[gid] * 2; return get_short_offset_array ()[gid] * 2;
} }
unsigned int get_data_length (unsigned int gid) const
{ return get_offset (gid+1) - get_offset (gid); }
const HBUINT32 *get_long_offset_array () const { return (const HBUINT32 *)&offsetZ; } const HBUINT32 *get_long_offset_array () const { return (const HBUINT32 *)&offsetZ; }
const HBUINT16 *get_short_offset_array () const { return (const HBUINT16 *)&offsetZ; } const HBUINT16 *get_short_offset_array () const { return (const HBUINT16 *)&offsetZ; }
@ -192,7 +253,7 @@ struct gvar
FixedVersion<> version; /* Version of gvar table. Set to 0x00010000u. */ FixedVersion<> version; /* Version of gvar table. Set to 0x00010000u. */
HBUINT16 axisCount; HBUINT16 axisCount;
HBUINT16 sharedTupleCount; HBUINT16 sharedTupleCount;
LOffsetTo<F2DOT14> sharedTuples; /* Actually LOffsetTo<UnsizedArrayOf<Tupple>> */ LOffsetTo<F2DOT14> sharedTuples; /* LOffsetTo<UnsizedArrayOf<Tupple>> */
HBUINT16 glyphCount; HBUINT16 glyphCount;
HBUINT16 flags; HBUINT16 flags;
LOffsetTo<GlyphVarData> dataZ; /* Array of GlyphVarData */ LOffsetTo<GlyphVarData> dataZ; /* Array of GlyphVarData */