From db6e658e8c0c4953c2f026f6a67a5d2fb4bdc204 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 7 Nov 2018 13:33:23 -0500 Subject: [PATCH] [kern/kerx] More towards sharing KernTable --- src/hb-aat-layout-kerx-table.hh | 48 +++++++++++++------------ src/hb-ot-kern-table.hh | 63 ++++++++++++++++++++++----------- 2 files changed, 69 insertions(+), 42 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 2bbd11aac..3a76f0fa4 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -773,16 +773,16 @@ struct KerxSubTableHeader enum Coverage { - Vertical = 0x80000000, /* Set if table has vertical kerning values. */ - CrossStream = 0x40000000, /* Set if table has cross-stream kerning values. */ - Variation = 0x20000000, /* Set if table has variation kerning values. */ - Backwards = 0x10000000, /* If clear, process the glyphs forwards, that - * is, from first to last in the glyph stream. - * If we, process them from last to first. - * This flag only applies to state-table based - * 'kerx' subtables (types 1 and 4). */ - Reserved = 0x0FFFFF00, /* Reserved, set to zero. */ - SubtableType = 0x000000FF, /* Subtable type. */ + Vertical = 0x80000000u, /* Set if table has vertical kerning values. */ + CrossStream = 0x40000000u, /* Set if table has cross-stream kerning values. */ + Variation = 0x20000000u, /* Set if table has variation kerning values. */ + Backwards = 0x10000000u, /* If clear, process the glyphs forwards, that + * is, from first to last in the glyph stream. + * If we, process them from last to first. + * This flag only applies to state-table based + * 'kerx' subtables (types 1 and 4). */ + Reserved = 0x0FFFFF00u, /* Reserved, set to zero. */ + SubtableType= 0x000000FFu, /* Subtable type. */ }; inline bool sanitize (hb_sanitize_context_t *c) const @@ -854,12 +854,16 @@ struct kerx static const hb_tag_t tableTag = HB_AAT_TAG_kerx; static const uint16_t minVersion = 2; + typedef KerxSubTableHeader SubTableHeader; + typedef SubTableHeader::Types Types; + typedef KerxSubTable SubTable; + inline bool has_data (void) const { return version != 0; } inline void apply (hb_aat_apply_context_t *c) const { c->set_lookup_index (0); - const KerxSubTable *st = &firstSubTable; + const SubTable *st = &firstSubTable; unsigned int count = tableCount; for (unsigned int i = 0; i < count; i++) { @@ -871,7 +875,7 @@ struct kerx reverse = bool (st->u.header.coverage & st->u.header.Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); - if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index)) + if (!c->buffer->message (c->font, "start %c%c%c%c subtable %d", HB_UNTAG (tableTag), c->lookup_index)) goto skip; if (reverse) @@ -879,19 +883,17 @@ struct kerx c->sanitizer.set_object (*st); - /* XXX Reverse-kern is not working yet... - * hb_kern_machine_t would need to know that it's reverse-kerning. - * Or better yet, make it work in reverse as well, so we don't have - * to reverse and reverse back? */ + /* XXX Reverse-kern is probably not working yet... + * hb_kern_machine_t would need to know that it's reverse-kerning. */ st->dispatch (c); if (reverse) c->buffer->reverse (); - (void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index); + (void) c->buffer->message (c->font, "end %c%c%c%c subtable %d", HB_UNTAG (tableTag), c->lookup_index); skip: - st = &StructAfter (*st); + st = &StructAfter (*st); c->set_lookup_index (c->lookup_index + 1); } } @@ -899,16 +901,18 @@ struct kerx inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!version.sanitize (c) || version < minVersion || !tableCount.sanitize (c)) + if (unlikely (!version.sanitize (c) || + version < minVersion || + !tableCount.sanitize (c))) return_trace (false); - const KerxSubTable *st = &firstSubTable; + const SubTable *st = &firstSubTable; unsigned int count = tableCount; for (unsigned int i = 0; i < count; i++) { if (!st->sanitize (c)) return_trace (false); - st = &StructAfter (*st); + st = &StructAfter (*st); } return_trace (true); @@ -920,7 +924,7 @@ struct kerx HBUINT16 unused; /* Set to 0. */ HBUINT32 tableCount; /* The number of subtables included in the extended kerning * table. */ - KerxSubTable firstSubTable; /* Subtables. */ + SubTable firstSubTable; /* Subtables. */ /*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */ public: diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 0102bb2c9..0976d16da 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -191,20 +191,34 @@ struct KernTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { - if (st->u.header.coverage & st->u.header.Variation) + bool reverse; + + if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation)) goto skip; if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ()) goto skip; - if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index)) + reverse = T::Types::extended /* TODO remove after kern application is moved earlier. */ && + bool (st->u.header.coverage & st->u.header.Backwards) != + HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); + + if (!c->buffer->message (c->font, "start %c%c%c%c subtable %d", HB_UNTAG (thiz()->tableTag), c->lookup_index)) goto skip; + if (reverse) + c->buffer->reverse (); + c->sanitizer.set_object (*st); + /* XXX Reverse-kern is probably not working yet... + * hb_kern_machine_t would need to know that it's reverse-kerning. */ st->dispatch (c); - (void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index); + if (reverse) + c->buffer->reverse (); + + (void) c->buffer->message (c->font, "end %c%c%c%c subtable %d", HB_UNTAG (thiz()->tableTag), c->lookup_index); skip: st = &StructAfter (*st); @@ -247,11 +261,13 @@ struct KernOTSubTableHeader enum Coverage { Horizontal = 0x01u, - Minimum = 0x02u, + Minimum = 0x02u, CrossStream = 0x04u, - Override = 0x08u, + Override = 0x08u, - Variation = 0x00u, /* Not supported. */ + /* Not supported: */ + Backwards = 0x00u, + Variation = 0x00u, }; inline bool sanitize (hb_sanitize_context_t *c) const @@ -273,15 +289,17 @@ struct KernOT : KernTable { friend struct KernTable; - typedef KernOTSubTableHeader SubTableHeader; - typedef KernSubTable SubTable; - + static const hb_tag_t tableTag = HB_OT_TAG_kern; static const uint16_t minVersion = 0; + typedef KernOTSubTableHeader SubTableHeader; + typedef SubTableHeader::Types Types; + typedef KernSubTable SubTable; + protected: - HBUINT16 version; /* Version--0x0000u */ - HBUINT16 tableCount; /* Number of subtables in the kerning table. */ - KernSubTable firstSubTable; /* Subtables. */ + HBUINT16 version; /* Version--0x0000u */ + HBUINT16 tableCount; /* Number of subtables in the kerning table. */ + SubTable firstSubTable; /* Subtables. */ public: DEFINE_SIZE_MIN (4); }; @@ -297,9 +315,12 @@ struct KernAATSubTableHeader enum Coverage { - Vertical = 0x80u, + Vertical = 0x80u, CrossStream = 0x40u, - Variation = 0x20u, + Variation = 0x20u, + + /* Not supported: */ + Backwards = 0x00u, }; inline bool sanitize (hb_sanitize_context_t *c) const @@ -323,15 +344,17 @@ struct KernAAT : KernTable { friend struct KernTable; - typedef KernAATSubTableHeader SubTableHeader; - typedef KernSubTable SubTable; - + static const hb_tag_t tableTag = HB_OT_TAG_kern; static const uint32_t minVersion = 0x00010000u; + typedef KernAATSubTableHeader SubTableHeader; + typedef SubTableHeader::Types Types; + typedef KernSubTable SubTable; + protected: - HBUINT32 version; /* Version--0x00010000u */ - HBUINT32 tableCount; /* Number of subtables in the kerning table. */ - KernSubTable firstSubTable; /* Subtables. */ + HBUINT32 version; /* Version--0x00010000u */ + HBUINT32 tableCount; /* Number of subtables in the kerning table. */ + SubTable firstSubTable; /* Subtables. */ public: DEFINE_SIZE_MIN (8); };