diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 6e9ed16d3..36d61ee37 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -678,6 +678,20 @@ struct GenericArrayOf inline unsigned int get_size (void) const { return len.static_size + len * Type::static_size; } + inline bool serialize (hb_serialize_context_t *c, + const Type *items, + unsigned int items_len) + { + TRACE_SERIALIZE (); + if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); + len.set (items_len); /* TODO may overflow */ + if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); + unsigned int count = items_len; + for (unsigned int i = 0; i < count; i++) + array[i].set (items[i]); + return TRACE_RETURN (true); + } + inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index d5a7883a7..6c5e42332 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -530,7 +530,7 @@ struct Coverage unsigned int num_glyphs) { TRACE_SERIALIZE (); - if (unlikely (c->extend_min (*this))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); unsigned int num_ranges = 1; for (unsigned int i = 1; i < num_glyphs; i++) if (glyphs[i - 1] + 1 != glyphs[i]) diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index ea28bcc2c..c50b20690 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -75,12 +75,12 @@ struct SingleSubstFormat1 inline bool serialize (hb_serialize_context_t *c, const USHORT *glyphs, unsigned int num_glyphs, - SHORT delta) + unsigned int delta) { TRACE_SERIALIZE (); 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); - deltaGlyphID.set (delta); + deltaGlyphID.set (delta); /* TODO overflow? */ return TRACE_RETURN (true); } @@ -136,6 +136,18 @@ struct SingleSubstFormat2 return TRACE_RETURN (true); } + inline bool serialize (hb_serialize_context_t *c, + const USHORT *glyphs, + const USHORT *substitutes, + unsigned int num_glyphs) + { + TRACE_SERIALIZE (); + 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 (!substitute.serialize (c, substitutes, num_glyphs))) return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (); return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c)); @@ -188,6 +200,33 @@ struct SingleSubst } } + inline bool serialize (hb_serialize_context_t *c, + const USHORT *glyphs, + const USHORT *substitutes, + unsigned int num_glyphs) + { + TRACE_SERIALIZE (); + if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); + unsigned int format = 2; + unsigned int delta; + if (num_glyphs) { + format = 1; + /* TODO check for wrap-around */ + delta = substitutes[0] - glyphs[0]; + for (unsigned int i = 1; i < num_glyphs; i++) + if (delta != substitutes[i] - glyphs[i]) { + format = 2; + break; + } + } + u.format.set (format); + switch (u.format) { + case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs, delta)); + case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, substitutes, num_glyphs)); + default:return TRACE_RETURN (false); + } + } + inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (); if (!u.format.sanitize (c)) return TRACE_RETURN (false);