From 213fa3bf711dae5028e3d041e305cdd35223de77 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 6 Nov 2018 12:07:15 -0500 Subject: [PATCH] [kern] Refactor to include header in each subtable type --- src/hb-ot-kern-table.hh | 189 +++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 98 deletions(-) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index e9d7e3018..1073530d6 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -155,6 +155,7 @@ struct KernPair DEFINE_SIZE_STATIC (6); }; +template struct KernSubTableFormat0 { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const @@ -186,11 +187,13 @@ struct KernSubTableFormat0 } protected: - BinSearchArrayOf pairs; /* Array of kerning pairs. */ + KernSubTableHeader header; + BinSearchArrayOf pairs; /* Array of kerning pairs. */ public: - DEFINE_SIZE_ARRAY (8, pairs); + DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 8, pairs); }; +template struct KernSubTableFormat1 { typedef void EntryData; @@ -309,10 +312,11 @@ struct KernSubTableFormat1 } protected: + KernSubTableHeader header; AAT::StateTable machine; OffsetTo, HBUINT16, false> kernAction; public: - DEFINE_SIZE_STATIC (10); + DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 10); }; struct KernClassTable @@ -333,6 +337,7 @@ struct KernClassTable DEFINE_SIZE_ARRAY (4, classes); }; +template struct KernSubTableFormat2 { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, @@ -393,20 +398,19 @@ struct KernSubTableFormat2 } protected: - HBUINT16 rowWidth; /* The width, in bytes, of a row in the table. */ - OffsetTo - leftClassTable; /* Offset from beginning of this subtable to - * left-hand class table. */ - OffsetTo - rightClassTable;/* Offset from beginning of this subtable to - * right-hand class table. */ - OffsetTo - array; /* Offset from beginning of this subtable to - * the start of the kerning array. */ + KernSubTableHeader header; + HBUINT16 rowWidth; /* The width, in bytes, of a row in the table. */ + OffsetTo leftClassTable; /* Offset from beginning of this subtable to + * left-hand class table. */ + OffsetTo rightClassTable;/* Offset from beginning of this subtable to + * right-hand class table. */ + OffsetTo array; /* Offset from beginning of this subtable to + * the start of the kerning array. */ public: - DEFINE_SIZE_MIN (8); + DEFINE_SIZE_MIN (KernSubTableHeader::static_size + 8); }; +template struct KernSubTableFormat3 { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const @@ -448,44 +452,52 @@ struct KernSubTableFormat3 } protected: - HBUINT16 glyphCount; /* The number of glyphs in this font. */ - HBUINT8 kernValueCount; /* The number of kerning values. */ - HBUINT8 leftClassCount; /* The number of left-hand classes. */ - HBUINT8 rightClassCount;/* The number of right-hand classes. */ - HBUINT8 flags; /* Set to zero (reserved for future use). */ - UnsizedArrayOf - kernValueZ; /* The kerning values. - * Length kernValueCount. */ + KernSubTableHeader header; + HBUINT16 glyphCount; /* The number of glyphs in this font. */ + HBUINT8 kernValueCount; /* The number of kerning values. */ + HBUINT8 leftClassCount; /* The number of left-hand classes. */ + HBUINT8 rightClassCount;/* The number of right-hand classes. */ + HBUINT8 flags; /* Set to zero (reserved for future use). */ + UnsizedArrayOf kernValueZ; /* The kerning values. + * Length kernValueCount. */ #if 0 - UnsizedArrayOf - leftClass; /* The left-hand classes. - * Length glyphCount. */ - UnsizedArrayOf - RightClass; /* The right-hand classes. - * Length glyphCount. */ - UnsizedArrayOf - kernIndex; /* The indices into the kernValue array. - * Length leftClassCount * rightClassCount */ + UnsizedArrayOfleftClass; /* The left-hand classes. + * Length glyphCount. */ + UnsizedArrayOfrightClass; /* The right-hand classes. + * Length glyphCount. */ + UnsizedArrayOfkernIndex; /* The indices into the kernValue array. + * Length leftClassCount * rightClassCount */ #endif public: - DEFINE_SIZE_ARRAY (6, kernValueZ); + DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ); }; +template struct KernSubTable { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int format) const + inline unsigned int get_size (void) const { return u.header.length; } + + inline bool is_simple (void) const + { return !(u.header.coverage & (u.header.CrossStream | u.header.Variation)); } + + inline bool is_horizontal (void) const + { return (u.header.coverage & u.header.Direction) == u.header.DirectionHorizontal; } + + inline bool is_override (void) const + { return bool (u.header.coverage & u.header.Override); } + + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - switch (format) { + switch (u.header.format) { /* This method hooks up to hb_font_t's get_h_kerning. Only support Format0. */ case 0: return u.format0.get_kerning (left, right); default:return 0; } } - inline void apply (AAT::hb_aat_apply_context_t *c, unsigned int format) const + inline void apply (AAT::hb_aat_apply_context_t *c) const { - /* TODO Switch to dispatch(). */ - switch (format) { + switch (u.header.format) { case 0: u.format0.apply (c); return; case 1: u.format1.apply (c); return; case 2: u.format2.apply (c); return; @@ -494,10 +506,13 @@ struct KernSubTable } } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - switch (format) { + if (unlikely (!u.header.sanitize (c) || + u.header.length < u.header.min_size || + !c->check_range (this, u.header.length))) return_trace (false); + switch (u.header.format) { case 0: return_trace (u.format0.sanitize (c)); case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -508,49 +523,17 @@ struct KernSubTable protected: union { - KernSubTableFormat0 format0; - KernSubTableFormat1 format1; - KernSubTableFormat2 format2; - KernSubTableFormat3 format3; + KernSubTableHeader header; + KernSubTableFormat0 format0; + KernSubTableFormat1 format1; + KernSubTableFormat2 format2; + KernSubTableFormat3 format3; } u; public: DEFINE_SIZE_MIN (0); }; -template -struct KernSubTableWrapper -{ - /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - inline const T* thiz (void) const { return static_cast (this); } - - inline bool is_simple (void) const - { return !(thiz()->coverage & (T::CrossStream | T::Variation)); } - - inline bool is_horizontal (void) const - { return (thiz()->coverage & T::Direction) == T::DirectionHorizontal; } - - inline bool is_override (void) const - { return bool (thiz()->coverage & T::Override); } - - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return thiz()->subtable.get_kerning (left, right, thiz()->format); } - - inline void apply (AAT::hb_aat_apply_context_t *c) const - { thiz()->subtable.apply (c, thiz()->format); } - - inline unsigned int get_size (void) const { return thiz()->length; } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (thiz()) && - thiz()->length >= T::min_size && - c->check_range (thiz(), thiz()->length) && - thiz()->subtable.sanitize (c, thiz()->format)); - } -}; - template struct KernTable { @@ -559,8 +542,10 @@ struct KernTable inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const { + typedef KernSubTable SubTable; + int v = 0; - const typename T::SubTableWrapper *st = CastP (&thiz()->dataZ); + const SubTable *st = CastP (&thiz()->dataZ); unsigned int count = thiz()->nTables; for (unsigned int i = 0; i < count; i++) { @@ -569,15 +554,17 @@ struct KernTable if (st->is_override ()) v = 0; v += st->get_kerning (left, right); - st = &StructAfter (*st); + st = &StructAfter (*st); } return v; } inline void apply (AAT::hb_aat_apply_context_t *c) const { + typedef KernSubTable SubTable; + c->set_lookup_index (0); - const typename T::SubTableWrapper *st = CastP (&thiz()->dataZ); + const SubTable *st = CastP (&thiz()->dataZ); unsigned int count = thiz()->nTables; /* If there's an override subtable, skip subtables before that. */ unsigned int last_override = 0; @@ -585,9 +572,9 @@ struct KernTable { if (st->is_simple () && st->is_override ()) last_override = i; - st = &StructAfter (*st); + st = &StructAfter (*st); } - st = CastP (&thiz()->dataZ); + st = CastP (&thiz()->dataZ); for (unsigned int i = 0; i < count; i++) { if (!st->is_simple ()) @@ -609,7 +596,7 @@ struct KernTable (void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index); skip: - st = &StructAfter (*st); + st = &StructAfter (*st); } } @@ -620,13 +607,15 @@ struct KernTable thiz()->version != T::VERSION)) return_trace (false); - const typename T::SubTableWrapper *st = CastP (&thiz()->dataZ); + typedef KernSubTable SubTable; + + const SubTable *st = CastP (&thiz()->dataZ); unsigned int count = thiz()->nTables; for (unsigned int i = 0; i < count; i++) { if (unlikely (!st->sanitize (c))) return_trace (false); - st = &StructAfter (*st); + st = &StructAfter (*st); } return_trace (true); @@ -639,11 +628,8 @@ struct KernOT : KernTable static const uint16_t VERSION = 0x0000u; - struct SubTableWrapper : KernSubTableWrapper + struct SubTableHeader { - friend struct KernTable; - friend struct KernSubTableWrapper; - enum Coverage { Direction = 0x01u, @@ -656,14 +642,19 @@ struct KernOT : KernTable DirectionHorizontal= 0x01u }; - protected: + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + public: HBUINT16 versionZ; /* Unused. */ HBUINT16 length; /* Length of the subtable (including this header). */ HBUINT8 format; /* Subtable format. */ HBUINT8 coverage; /* Coverage bits. */ - KernSubTable subtable; /* Subtable data. */ public: - DEFINE_SIZE_MIN (6); + DEFINE_SIZE_STATIC (6); }; protected: @@ -680,11 +671,8 @@ struct KernAAT : KernTable static const uint32_t VERSION = 0x00010000u; - struct SubTableWrapper : KernSubTableWrapper + struct SubTableHeader { - friend struct KernTable; - friend struct KernSubTableWrapper; - enum Coverage { Direction = 0x80u, @@ -696,15 +684,20 @@ struct KernAAT : KernTable DirectionHorizontal= 0x00u }; - protected: + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + public: HBUINT32 length; /* Length of the subtable (including this header). */ HBUINT8 coverage; /* Coverage bits. */ HBUINT8 format; /* Subtable format. */ HBUINT16 tupleIndex; /* The tuple index (used for variations fonts). * This value specifies which tuple this subtable covers. */ - KernSubTable subtable; /* Subtable data. */ public: - DEFINE_SIZE_MIN (8); + DEFINE_SIZE_STATIC (8); }; protected: