[OT] More serialize. Implements all basic GSUB subtables
This commit is contained in:
parent
1b38b4e817
commit
a930c68e9c
|
@ -428,6 +428,40 @@ struct hb_serialize_context_t
|
||||||
bool ran_out_of_room;
|
bool ran_out_of_room;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct Supplier
|
||||||
|
{
|
||||||
|
/* For automatic wrapping of bare arrays */
|
||||||
|
inline Supplier (const Type *array)
|
||||||
|
{
|
||||||
|
head = array;
|
||||||
|
len = (unsigned int) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Supplier (const Type *array, unsigned int len_)
|
||||||
|
{
|
||||||
|
head = array;
|
||||||
|
len = len_;
|
||||||
|
}
|
||||||
|
inline const Type operator [] (unsigned int i) const
|
||||||
|
{
|
||||||
|
if (unlikely (i >= len)) return Type ();
|
||||||
|
return head[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void advance (unsigned int count) {
|
||||||
|
if (unlikely (count > len))
|
||||||
|
count = len;
|
||||||
|
len -= count;
|
||||||
|
head += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int len;
|
||||||
|
const Type *head;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -687,7 +721,7 @@ struct GenericArrayOf
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const Type *items,
|
Supplier<Type> &items,
|
||||||
unsigned int items_len)
|
unsigned int items_len)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
|
@ -697,6 +731,7 @@ struct GenericArrayOf
|
||||||
unsigned int count = items_len;
|
unsigned int count = items_len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
array[i].set (items[i]);
|
array[i].set (items[i]);
|
||||||
|
items.advance (items_len);
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,6 +838,22 @@ struct HeadlessArrayOf
|
||||||
inline unsigned int get_size (void) const
|
inline unsigned int get_size (void) const
|
||||||
{ return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
|
{ return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
|
||||||
|
|
||||||
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
|
Supplier<Type> &items,
|
||||||
|
unsigned int items_len)
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE ();
|
||||||
|
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
||||||
|
len.set (items_len); /* TODO(serialize) Overflow? */
|
||||||
|
if (unlikely (!c->extend (*this))) return TRACE_RETURN (false);
|
||||||
|
if (unlikely (!items_len)) return TRACE_RETURN (true);
|
||||||
|
unsigned int count = items_len;
|
||||||
|
for (unsigned int i = 1; i < count; i++)
|
||||||
|
array[i-1].set (items[i]);
|
||||||
|
items.advance (items_len - 1);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool sanitize_shallow (hb_sanitize_context_t *c) {
|
inline bool sanitize_shallow (hb_sanitize_context_t *c) {
|
||||||
return c->check_struct (this)
|
return c->check_struct (this)
|
||||||
&& c->check_array (this, Type::static_size, len);
|
&& c->check_array (this, Type::static_size, len);
|
||||||
|
|
|
@ -356,7 +356,7 @@ struct CoverageFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
unsigned int num_glyphs)
|
unsigned int num_glyphs)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
|
@ -365,6 +365,7 @@ struct CoverageFormat1
|
||||||
if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false);
|
if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false);
|
||||||
for (unsigned int i = 0; i < num_glyphs; i++)
|
for (unsigned int i = 0; i < num_glyphs; i++)
|
||||||
glyphArray[i].set (glyphs[i]);
|
glyphArray[i].set (glyphs[i]);
|
||||||
|
glyphs.advance (num_glyphs);
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +421,7 @@ struct CoverageFormat2
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
unsigned int num_glyphs)
|
unsigned int num_glyphs)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
|
@ -446,6 +447,7 @@ struct CoverageFormat2
|
||||||
} else {
|
} else {
|
||||||
rangeRecord[range].end = glyphs[i];
|
rangeRecord[range].end = glyphs[i];
|
||||||
}
|
}
|
||||||
|
glyphs.advance (num_glyphs);
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,7 +528,7 @@ struct Coverage
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
unsigned int num_glyphs)
|
unsigned int num_glyphs)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct SingleSubstFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
unsigned int num_glyphs,
|
unsigned int num_glyphs,
|
||||||
int delta)
|
int delta)
|
||||||
{
|
{
|
||||||
|
@ -137,8 +137,8 @@ struct SingleSubstFormat2
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
const USHORT *substitutes,
|
Supplier<GlyphID> &substitutes,
|
||||||
unsigned int num_glyphs)
|
unsigned int num_glyphs)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
|
@ -201,8 +201,8 @@ struct SingleSubst
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
const USHORT *substitutes,
|
Supplier<GlyphID> &substitutes,
|
||||||
unsigned int num_glyphs)
|
unsigned int num_glyphs)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
|
@ -277,7 +277,7 @@ struct Sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
unsigned int num_glyphs)
|
unsigned int num_glyphs)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
|
@ -331,19 +331,20 @@ struct MultipleSubstFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
unsigned int *substitute_len_list,
|
Supplier<unsigned int> &substitute_len_list,
|
||||||
unsigned int num_glyphs,
|
unsigned int num_glyphs,
|
||||||
const USHORT *substitute_glyphs_list)
|
Supplier<GlyphID> &substitute_glyphs_list)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
||||||
if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
|
if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
|
||||||
if (unlikely (!sequence.serialize (c, num_glyphs))) return TRACE_RETURN (false);
|
if (unlikely (!sequence.serialize (c, num_glyphs))) return TRACE_RETURN (false);
|
||||||
for (unsigned int i = 0; i < num_glyphs; i++) {
|
for (unsigned int i = 0; i < num_glyphs; i++)
|
||||||
if (unlikely (!sequence[i].serialize (c, this).serialize (c, substitute_glyphs_list, substitute_len_list[i]))) return TRACE_RETURN (false);
|
if (unlikely (!sequence[i].serialize (c, this).serialize (c,
|
||||||
substitute_glyphs_list += substitute_len_list[i];
|
substitute_glyphs_list,
|
||||||
}
|
substitute_len_list[i]))) return TRACE_RETURN (false);
|
||||||
|
substitute_len_list.advance (num_glyphs);
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,10 +398,10 @@ struct MultipleSubst
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
unsigned int *substitute_len_list,
|
Supplier<unsigned int> &substitute_len_list,
|
||||||
unsigned int num_glyphs,
|
unsigned int num_glyphs,
|
||||||
const USHORT *substitute_glyphs_list)
|
Supplier<GlyphID> &substitute_glyphs_list)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
|
if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
|
||||||
|
@ -486,19 +487,20 @@ struct AlternateSubstFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
unsigned int *alternate_len_list,
|
Supplier<unsigned int> &alternate_len_list,
|
||||||
unsigned int num_glyphs,
|
unsigned int num_glyphs,
|
||||||
const USHORT *alternate_glyphs_list)
|
Supplier<GlyphID> &alternate_glyphs_list)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
||||||
if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
|
if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
|
||||||
if (unlikely (!alternateSet.serialize (c, num_glyphs))) return TRACE_RETURN (false);
|
if (unlikely (!alternateSet.serialize (c, num_glyphs))) return TRACE_RETURN (false);
|
||||||
for (unsigned int i = 0; i < num_glyphs; i++) {
|
for (unsigned int i = 0; i < num_glyphs; i++)
|
||||||
if (unlikely (!alternateSet[i].serialize (c, this).serialize (c, alternate_glyphs_list, alternate_len_list[i]))) return TRACE_RETURN (false);
|
if (unlikely (!alternateSet[i].serialize (c, this).serialize (c,
|
||||||
alternate_glyphs_list += alternate_len_list[i];
|
alternate_glyphs_list,
|
||||||
}
|
alternate_len_list[i]))) return TRACE_RETURN (false);
|
||||||
|
alternate_len_list.advance (num_glyphs);
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,10 +554,10 @@ struct AlternateSubst
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const USHORT *glyphs,
|
Supplier<GlyphID> &glyphs,
|
||||||
unsigned int *alternate_len_list,
|
Supplier<unsigned int> &alternate_len_list,
|
||||||
unsigned int num_glyphs,
|
unsigned int num_glyphs,
|
||||||
const USHORT *alternate_glyphs_list)
|
Supplier<GlyphID> &alternate_glyphs_list)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE ();
|
TRACE_SERIALIZE ();
|
||||||
if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
|
if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
|
||||||
|
@ -646,6 +648,18 @@ struct Ligature
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
|
GlyphID ligature,
|
||||||
|
Supplier<GlyphID> &components, /* Starting from second */
|
||||||
|
unsigned int num_components /* Including first component */)
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE ();
|
||||||
|
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
||||||
|
ligGlyph.set (ligature);
|
||||||
|
if (unlikely (!component.serialize (c, components, num_components))) return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
TRACE_SANITIZE ();
|
TRACE_SANITIZE ();
|
||||||
|
@ -701,6 +715,24 @@ struct LigatureSet
|
||||||
return TRACE_RETURN (false);
|
return TRACE_RETURN (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
|
Supplier<GlyphID> &ligatures,
|
||||||
|
Supplier<unsigned int> &component_count_list,
|
||||||
|
unsigned int num_ligatures,
|
||||||
|
Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE ();
|
||||||
|
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
||||||
|
if (unlikely (!ligature.serialize (c, num_ligatures))) return TRACE_RETURN (false);
|
||||||
|
for (unsigned int i = 0; i < num_ligatures; i++)
|
||||||
|
if (unlikely (!ligature[i].serialize (c, this).serialize (c,
|
||||||
|
ligatures[i],
|
||||||
|
component_list,
|
||||||
|
component_count_list[i]))) return TRACE_RETURN (false);
|
||||||
|
component_count_list.advance (num_ligatures);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
TRACE_SANITIZE ();
|
TRACE_SANITIZE ();
|
||||||
|
@ -753,6 +785,28 @@ struct LigatureSubstFormat1
|
||||||
return TRACE_RETURN (lig_set.apply (c));
|
return TRACE_RETURN (lig_set.apply (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
|
Supplier<GlyphID> &first_glyphs,
|
||||||
|
Supplier<unsigned int> &ligature_per_first_glyph_count_list,
|
||||||
|
unsigned int num_first_glyphs,
|
||||||
|
Supplier<GlyphID> &ligatures_list,
|
||||||
|
Supplier<unsigned int> &component_count_list,
|
||||||
|
Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE ();
|
||||||
|
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
||||||
|
if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return TRACE_RETURN (false);
|
||||||
|
if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return TRACE_RETURN (false);
|
||||||
|
for (unsigned int i = 0; i < num_first_glyphs; i++)
|
||||||
|
if (unlikely (!ligatureSet[i].serialize (c, this).serialize (c,
|
||||||
|
ligatures_list,
|
||||||
|
component_count_list,
|
||||||
|
ligature_per_first_glyph_count_list[i],
|
||||||
|
component_list))) return TRACE_RETURN (false);
|
||||||
|
ligature_per_first_glyph_count_list.advance (num_first_glyphs);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
TRACE_SANITIZE ();
|
TRACE_SANITIZE ();
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
|
||||||
|
@ -810,6 +864,25 @@ struct LigatureSubst
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
|
Supplier<GlyphID> &first_glyphs,
|
||||||
|
Supplier<unsigned int> &ligature_per_first_glyph_count_list,
|
||||||
|
unsigned int num_first_glyphs,
|
||||||
|
Supplier<GlyphID> &ligatures_list,
|
||||||
|
Supplier<unsigned int> &component_count_list,
|
||||||
|
Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE ();
|
||||||
|
if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
|
||||||
|
unsigned int format = 1;
|
||||||
|
u.format.set (format);
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return TRACE_RETURN (u.format1.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs,
|
||||||
|
ligatures_list, component_count_list, component_list));
|
||||||
|
default:return TRACE_RETURN (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
TRACE_SANITIZE ();
|
TRACE_SANITIZE ();
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||||
|
|
Loading…
Reference in New Issue