src/hb-aat-layout-ankr-table.hh | 6 ++-- src/hb-aat-layout-common.hh | 55 +++++++++++++++++++++++++++++++++++++--- src/hb-aat-layout-kerx-table.hh | 37 +++++++++++++++++++++----- src/hb-machinery.hh | 4 ++ src/hb-open-type.hh | 3 ++ 5 files changed, 92 insertions(+), 13 deletions(-)
New commits: commit 29d877518fc2c29083cd7b955b422087966235f7 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Oct 19 16:06:54 2018 -0700 [kerx] Implement variation-kerning tables (without the variation part) SFSNDisplay uses these. We just apply the default kern without variations right now. But at least makes the default kern work. diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 9727e396..64257809 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -45,6 +45,21 @@ namespace AAT { using namespace OT; +static inline int +kerxTupleKern (int value, + unsigned int tupleCount, + const void *base, + hb_aat_apply_context_t *c) +{ + if (likely (!tupleCount)) return value; + + unsigned int offset = value; + const FWORD *pv = &StructAtOffset<FWORD> (base, offset); + if (unlikely (!pv->sanitize (&c->sanitizer))) return 0; + return *pv; +} + + struct KerxSubTableHeader { inline bool sanitize (hb_sanitize_context_t *c) const @@ -65,6 +80,7 @@ struct KerxSubTableFormat0 { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { + if (header.tupleCount) return 0; /* TODO kerxTupleKern */ hb_glyph_pair_t pair = {left, right}; int i = pairs.bsearch (pair); return i == -1 ? 0 : pairs[i].get_kerning (); @@ -201,6 +217,9 @@ struct KerxSubTableFormat1 if (!c->plan->requested_kerning) return false; + if (header.tupleCount) + return_trace (false); /* TODO kerxTupleKern */ + driver_context_t dc (this, c); StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face); @@ -236,7 +255,7 @@ struct KerxSubTableFormat2 unsigned int offset = l + r; const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; - return *v; + return kerxTupleKern (*v, header.tupleCount, this, c); } inline bool apply (hb_aat_apply_context_t *c) const @@ -482,7 +501,7 @@ struct KerxSubTableFormat6 if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; - return *v; + return kerxTupleKern (*v, header.tupleCount, &(this+vector), c); } else { @@ -492,7 +511,7 @@ struct KerxSubTableFormat6 unsigned int offset = l + r; const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; - return *v; + return kerxTupleKern (*v, header.tupleCount, &(this+vector), c); } } @@ -523,7 +542,9 @@ struct KerxSubTableFormat6 u.s.rowIndexTable.sanitize (c, this) && u.s.columnIndexTable.sanitize (c, this) && c->check_range (this, u.s.array) - )))); + )) && + (header.tupleCount == 0 || + c->check_range (this, vector)))); } struct accelerator_t @@ -559,8 +580,9 @@ struct KerxSubTableFormat6 LOffsetTo<UnsizedArrayOf<FWORD>, false> array; } s; } u; + LOffsetTo<UnsizedArrayOf<FWORD>, false> vector; public: - DEFINE_SIZE_STATIC (32); + DEFINE_SIZE_STATIC (36); }; struct KerxTable @@ -642,9 +664,8 @@ struct kerx { bool reverse; - if (table->u.header.coverage & (KerxTable::CrossStream | KerxTable::Variation) || - table->u.header.tupleCount) - goto skip; /* We do NOT handle cross-stream or variation kerning. */ + if (table->u.header.coverage & (KerxTable::CrossStream)) + goto skip; /* We do NOT handle cross-stream. */ if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != bool (table->u.header.coverage & KerxTable::Vertical)) commit f7c0b4319c6f82f1e0020a0029469d8953a7a161 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Oct 19 15:23:49 2018 -0700 [aat] Implement LookupFormat10 diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh index 2e3ed275..5f7656d2 100644 --- a/src/hb-aat-layout-ankr-table.hh +++ b/src/hb-aat-layout-ankr-table.hh @@ -63,8 +63,10 @@ struct ankr unsigned int num_glyphs, const char *end) const { - unsigned int offset = (this+lookupTable).get_value_or_null (glyph_id, num_glyphs); - const GlyphAnchors &anchors = StructAtOffset<GlyphAnchors> (&(this+anchorData), offset); + const Offset<HBUINT16, false> *offset = (this+lookupTable).get_value (glyph_id, num_glyphs); + if (!offset) + return Null(Anchor); + const GlyphAnchors &anchors = StructAtOffset<GlyphAnchors> (&(this+anchorData), *offset); /* TODO Use sanitizer; to avoid overflows and more. */ if (unlikely ((const char *) &anchors + anchors.get_size () > end)) return Null(Anchor); diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 89ed91f2..60724c18 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -247,6 +247,48 @@ struct LookupFormat8 }; template <typename T> +struct LookupFormat10 +{ + friend struct Lookup<T>; + + private: + inline const typename T::type get_value_or_null (hb_codepoint_t glyph_id) const + { + if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount)) + return Null(T); + + const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize]; + + unsigned int v = 0; + unsigned int count = valueSize; + for (unsigned int i = 0; i < count; i++) + v = (v << 8) | *p++; + + return v; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + valueSize <= 4 && + valueArrayZ.sanitize (c, glyphCount * valueSize)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 8 */ + HBUINT16 valueSize; /* Byte size of each value. */ + GlyphID firstGlyph; /* First glyph index included in the trimmed array. */ + HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last + * glyph minus the value of firstGlyph plus 1). */ + UnsizedArrayOf<HBUINT8> + valueArrayZ; /* The lookup values (indexed by the glyph index + * minus the value of firstGlyph). */ + public: + DEFINE_SIZE_ARRAY (6, valueArrayZ); +}; + +template <typename T> struct Lookup { inline const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const @@ -261,10 +303,15 @@ struct Lookup } } - inline const T& get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + inline const typename T::type get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { - const T *v = get_value (glyph_id, num_glyphs); - return v ? *v : Null(T); + switch (u.format) { + /* Format 10 cannot return a pointer. */ + case 10: return u.format10.get_value_or_null (glyph_id); + default: + const T *v = get_value (glyph_id, num_glyphs); + return v ? *v : Null(T); + } } inline bool sanitize (hb_sanitize_context_t *c) const @@ -277,6 +324,7 @@ struct Lookup case 4: return_trace (u.format4.sanitize (c)); case 6: return_trace (u.format6.sanitize (c)); case 8: return_trace (u.format8.sanitize (c)); + case 10: return_trace (u.format10.sanitize (c)); default:return_trace (true); } } @@ -289,6 +337,7 @@ struct Lookup LookupFormat4<T> format4; LookupFormat6<T> format6; LookupFormat8<T> format8; + LookupFormat10<T> format10; } u; public: DEFINE_SIZE_UNION (2, format); diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 717abea9..ae34c92f 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -652,6 +652,7 @@ template <typename Type> struct BEInt<Type, 1> { public: + typedef Type type; inline void set (Type V) { v = V; @@ -666,6 +667,7 @@ template <typename Type> struct BEInt<Type, 2> { public: + typedef Type type; inline void set (Type V) { v[0] = (V >> 8) & 0xFF; @@ -682,6 +684,7 @@ template <typename Type> struct BEInt<Type, 3> { public: + typedef Type type; inline void set (Type V) { v[0] = (V >> 16) & 0xFF; @@ -700,6 +703,7 @@ template <typename Type> struct BEInt<Type, 4> { public: + typedef Type type; inline void set (Type V) { v[0] = (V >> 24) & 0xFF; diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 9d2e1fa7..08e72064 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -56,6 +56,7 @@ namespace OT { template <typename Type, unsigned int Size> struct IntType { + typedef Type type; inline void set (Type i) { v.set (i); } inline operator Type(void) const { return v; } inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; } @@ -161,6 +162,8 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, Index); template <typename Type, bool has_null=true> struct Offset : Type { + typedef Type type; + inline bool is_null (void) const { return has_null && 0 == *this; } inline void *serialize (hb_serialize_context_t *c, const void *base) _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz