src/hb-aat-layout-kerx-table.hh | 106 +++++++++++++++++++++++++++++++++------- src/hb-open-type.hh | 3 + 2 files changed, 91 insertions(+), 18 deletions(-)
New commits: commit ab1f30bd059f1d2270793e9726b60666b328d2b8 Author: Behdad Esfahbod <[email protected]> Date: Wed Oct 10 20:10:20 2018 -0400 [kerx] Implement Format6 Untested. The only Apple font shipping with this format is San Francisco fonts that use this for their kerx variation tables, which we don't support. diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 31b650ad..3cff334a 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -136,7 +136,7 @@ struct KerxSubTableFormat2 unsigned int offset = l + r; const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset); if (unlikely ((const char *) v < (const char *) &array || - (const char *) v + 2 - (const char *) this <= header.length)) + (const char *) v + v->static_size - (const char *) this <= header.length)) return 0; return *v; } @@ -230,6 +230,35 @@ struct KerxSubTableFormat6 inline bool is_long (void) const { return flags & ValuesAreLong; } + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, + unsigned int num_glyphs) const + { + if (is_long ()) + { + const U::Long &t = u.l; + unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); + unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); + unsigned int offset = l + r; + const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32)); + if (unlikely ((const char *) v < (const char *) &t.array || + (const char *) v + v->static_size - (const char *) this <= header.length)) + return 0; + return *v; + } + else + { + const U::Short &t = u.s; + unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); + unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); + unsigned int offset = l + r; + const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD)); + if (unlikely ((const char *) v < (const char *) &t.array || + (const char *) v + v->static_size - (const char *) this <= header.length)) + return 0; + return *v; + } + } + inline bool apply (hb_aat_apply_context_t *c) const { TRACE_APPLY (this); @@ -237,7 +266,10 @@ struct KerxSubTableFormat6 if (!c->plan->requested_kerning) return false; - /* TODO */ + accelerator_t accel (*this, + c->face->get_num_glyphs ()); + hb_kern_machine_t<accelerator_t> machine (accel); + machine.kern (c->font, c->buffer, c->plan->kern_mask); return_trace (true); } @@ -250,33 +282,48 @@ struct KerxSubTableFormat6 ( u.l.rowIndexTable.sanitize (c, this) && u.l.columnIndexTable.sanitize (c, this) && - u.l.kerningArray.sanitize (c, this) + u.l.array.sanitize (c, this) ) : ( u.s.rowIndexTable.sanitize (c, this) && u.s.columnIndexTable.sanitize (c, this) && - u.s.kerningArray.sanitize (c, this) + u.s.array.sanitize (c, this) ))); } + struct accelerator_t + { + const KerxSubTableFormat6 &table; + unsigned int num_glyphs; + + inline accelerator_t (const KerxSubTableFormat6 &table_, + unsigned int num_glyphs_) + : table (table_), num_glyphs (num_glyphs_) {} + + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { + return table.get_kerning (left, right, num_glyphs); + } + }; + protected: KerxSubTableHeader header; HBUINT32 flags; HBUINT16 rowCount; HBUINT16 columnCount; - union + union U { - struct - { - LOffsetTo<Lookup<HBUINT16> > rowIndexTable; - LOffsetTo<Lookup<HBUINT16> > columnIndexTable; - LOffsetTo<FWORD> kerningArray; - } s; - struct + struct Long { LOffsetTo<Lookup<HBUINT32> > rowIndexTable; LOffsetTo<Lookup<HBUINT32> > columnIndexTable; - LOffsetTo<FWORD32> kerningArray; + LOffsetTo<FWORD32> array; } l; + struct Short + { + LOffsetTo<Lookup<HBUINT16> > rowIndexTable; + LOffsetTo<Lookup<HBUINT16> > columnIndexTable; + LOffsetTo<FWORD> array; + } s; } u; public: DEFINE_SIZE_STATIC (32); commit c9a2ce9e05f91730a2150b9214dc6a49f31555c1 Author: Behdad Esfahbod <[email protected]> Date: Wed Oct 10 20:00:44 2018 -0400 [kerx] Move bounds-checking to subtable length itself diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 05b28f3c..31b650ad 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -129,14 +129,14 @@ struct KerxSubTableFormat1 struct KerxSubTableFormat2 { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, - const char *end, unsigned int num_glyphs) const + unsigned int num_glyphs) const { unsigned int l = (this+leftClassTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+rightClassTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset); if (unlikely ((const char *) v < (const char *) &array || - (const char *) v > (const char *) end - 2)) + (const char *) v + 2 - (const char *) this <= header.length)) return 0; return *v; } @@ -149,7 +149,6 @@ struct KerxSubTableFormat2 return false; accelerator_t accel (*this, - c->sanitizer.end, c->face->get_num_glyphs ()); hb_kern_machine_t<accelerator_t> machine (accel); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -170,16 +169,15 @@ struct KerxSubTableFormat2 struct accelerator_t { const KerxSubTableFormat2 &table; - const char *end; unsigned int num_glyphs; inline accelerator_t (const KerxSubTableFormat2 &table_, - const char *end_, unsigned int num_glyphs_) - : table (table_), end (end_), num_glyphs (num_glyphs_) {} + unsigned int num_glyphs_) + : table (table_), num_glyphs (num_glyphs_) {} inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - return table.get_kerning (left, right, end, num_glyphs); + return table.get_kerning (left, right, num_glyphs); } }; commit 22955b23cdeb48e46cdffd0eb906a855a420c4d1 Author: Behdad Esfahbod <[email protected]> Date: Wed Oct 10 19:58:20 2018 -0400 [kerx] Start fleshing out Format6 diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index cd8dc458..05b28f3c 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -225,6 +225,13 @@ struct KerxSubTableFormat4 struct KerxSubTableFormat6 { + enum Flags + { + ValuesAreLong = 0x00000001, + }; + + inline bool is_long (void) const { return flags & ValuesAreLong; } + inline bool apply (hb_aat_apply_context_t *c) const { TRACE_APPLY (this); @@ -241,10 +248,16 @@ struct KerxSubTableFormat6 { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - rowIndexTable.sanitize (c, this) && - columnIndexTable.sanitize (c, this) && - kerningArray.sanitize (c, this) && - kerningVector.sanitize (c, this))); + is_long () ? + ( + u.l.rowIndexTable.sanitize (c, this) && + u.l.columnIndexTable.sanitize (c, this) && + u.l.kerningArray.sanitize (c, this) + ) : ( + u.s.rowIndexTable.sanitize (c, this) && + u.s.columnIndexTable.sanitize (c, this) && + u.s.kerningArray.sanitize (c, this) + ))); } protected: @@ -252,12 +265,23 @@ struct KerxSubTableFormat6 HBUINT32 flags; HBUINT16 rowCount; HBUINT16 columnCount; - LOffsetTo<Lookup<HBUINT16> > rowIndexTable; - LOffsetTo<Lookup<HBUINT16> > columnIndexTable; - LOffsetTo<Lookup<HBUINT16> > kerningArray; - LOffsetTo<Lookup<HBUINT16> > kerningVector; + union + { + struct + { + LOffsetTo<Lookup<HBUINT16> > rowIndexTable; + LOffsetTo<Lookup<HBUINT16> > columnIndexTable; + LOffsetTo<FWORD> kerningArray; + } s; + struct + { + LOffsetTo<Lookup<HBUINT32> > rowIndexTable; + LOffsetTo<Lookup<HBUINT32> > columnIndexTable; + LOffsetTo<FWORD32> kerningArray; + } l; + } u; public: - DEFINE_SIZE_STATIC (36); + DEFINE_SIZE_STATIC (32); }; struct KerxTable diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 9a087336..2eae09d5 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -92,6 +92,9 @@ typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */ /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */ typedef HBINT16 FWORD; +/* 32-bit signed integer (HBINT32) that describes a quantity in FUnits. */ +typedef HBINT32 FWORD32; + /* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */ typedef HBUINT16 UFWORD; commit f6aaad9b4ffb42e6cd8398f6439fe420e393c8f6 Author: Behdad Esfahbod <[email protected]> Date: Wed Oct 10 19:20:06 2018 -0400 [kerx] When rejecting variable kerning, also check for tupleCount diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index c683242f..cd8dc458 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -339,7 +339,8 @@ struct kerx { bool reverse; - if (table->u.header.coverage & (KerxTable::CrossStream | KerxTable::Variation)) + 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 (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
