diff options
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh')
-rw-r--r-- | Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh | 733 |
1 files changed, 146 insertions, 587 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh index 5bc9e436c74..14e0656842b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh @@ -27,89 +27,7 @@ #ifndef HB_OT_KERN_TABLE_HH #define HB_OT_KERN_TABLE_HH -#include "hb-open-type.hh" -#include "hb-ot-shape.hh" -#include "hb-ot-layout-gsubgpos.hh" -#include "hb-aat-layout-common.hh" - - -template <typename Driver> -struct hb_kern_machine_t -{ - hb_kern_machine_t (const Driver &driver_) : driver (driver_) {} - - HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW - inline void kern (hb_font_t *font, - hb_buffer_t *buffer, - hb_mask_t kern_mask, - bool scale = true) const - { - OT::hb_ot_apply_context_t c (1, font, buffer); - c.set_lookup_mask (kern_mask); - c.set_lookup_props (OT::LookupFlag::IgnoreMarks); - OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input; - skippy_iter.init (&c); - - bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction); - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - for (unsigned int idx = 0; idx < count;) - { - if (!(info[idx].mask & kern_mask)) - { - idx++; - continue; - } - - skippy_iter.reset (idx, 1); - if (!skippy_iter.next ()) - { - idx++; - continue; - } - - unsigned int i = idx; - unsigned int j = skippy_iter.idx; - - hb_position_t kern = driver.get_kerning (info[i].codepoint, - info[j].codepoint); - - - if (likely (!kern)) - goto skip; - - - if (horizontal) - { - if (scale) - kern = font->em_scale_x (kern); - hb_position_t kern1 = kern >> 1; - hb_position_t kern2 = kern - kern1; - pos[i].x_advance += kern1; - pos[j].x_advance += kern2; - pos[j].x_offset += kern2; - } - else - { - if (scale) - kern = font->em_scale_y (kern); - hb_position_t kern1 = kern >> 1; - hb_position_t kern2 = kern - kern1; - pos[i].y_advance += kern1; - pos[j].y_advance += kern2; - pos[j].y_offset += kern2; - } - - buffer->unsafe_to_break (i, j + 1); - - skip: - idx = skippy_iter.idx; - } - } - - const Driver &driver; -}; +#include "hb-aat-layout-kerx-table.hh" /* @@ -123,290 +41,7 @@ struct hb_kern_machine_t namespace OT { -struct hb_glyph_pair_t -{ - hb_codepoint_t left; - hb_codepoint_t right; -}; - -struct KernPair -{ - inline int get_kerning (void) const - { return value; } - - inline int cmp (const hb_glyph_pair_t &o) const - { - int ret = left.cmp (o.left); - if (ret) return ret; - return right.cmp (o.right); - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - protected: - GlyphID left; - GlyphID right; - FWORD value; - public: - DEFINE_SIZE_STATIC (6); -}; - -struct KernSubTableFormat0 -{ - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { - hb_glyph_pair_t pair = {left, right}; - int i = pairs.bsearch (pair); - if (i == -1) - return 0; - return pairs[i].get_kerning (); - } - - inline bool apply (AAT::hb_aat_apply_context_t *c) const - { - TRACE_APPLY (this); - - if (!c->plan->requested_kerning) - return false; - - hb_kern_machine_t<KernSubTableFormat0> machine (*this); - machine.kern (c->font, c->buffer, c->plan->kern_mask); - - return_trace (true); - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (pairs.sanitize (c)); - } - - protected: - BinSearchArrayOf<KernPair> pairs; /* Array of kerning pairs. */ - public: - DEFINE_SIZE_ARRAY (8, pairs); -}; - -struct KernSubTableFormat1 -{ - typedef void EntryData; - - struct driver_context_t - { - static const bool in_place = true; - enum Flags - { - Push = 0x8000, /* If set, push this glyph on the kerning stack. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph - * before going to the new state. */ - Offset = 0x3FFF, /* Byte offset from beginning of subtable to the - * value table for the glyphs on the kerning stack. */ - }; - - inline driver_context_t (const KernSubTableFormat1 *table_, - AAT::hb_aat_apply_context_t *c_) : - c (c_), - table (table_), - /* Apparently the offset kernAction is from the beginning of the state-machine, - * similar to offsets in morx table, NOT from beginning of this table, like - * other subtables in kerx. Discovered via testing. */ - kernAction (&table->machine + table->kernAction), - depth (0) {} - - inline bool is_actionable (AAT::StateTableDriver<AAT::MortTypes, EntryData> *driver HB_UNUSED, - const AAT::Entry<EntryData> *entry) - { - return entry->flags & Offset; - } - inline bool transition (AAT::StateTableDriver<AAT::MortTypes, EntryData> *driver, - const AAT::Entry<EntryData> *entry) - { - hb_buffer_t *buffer = driver->buffer; - unsigned int flags = entry->flags; - - if (flags & Push) - { - if (likely (depth < ARRAY_LENGTH (stack))) - stack[depth++] = buffer->idx; - else - depth = 0; /* Probably not what CoreText does, but better? */ - } - - if (entry->flags & Offset) - { - unsigned int kernIndex = AAT::MortTypes::offsetToIndex (entry->flags & Offset, &table->machine, kernAction.arrayZ); - const FWORD *actions = &kernAction[kernIndex]; - if (!c->sanitizer.check_array (actions, depth)) - { - depth = 0; - return false; - } - - hb_mask_t kern_mask = c->plan->kern_mask; - for (unsigned int i = 0; i < depth; i++) - { - /* Apparently, when spec says "Each pops one glyph from the kerning stack - * and applies the kerning value to it.", it doesn't mean it in that order. - * The deepest item in the stack corresponds to the first item in the action - * list. Discovered by testing. */ - unsigned int idx = stack[i]; - int v = *actions++; - if (idx < buffer->len && buffer->info[idx].mask & kern_mask) - { - if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - { - buffer->pos[idx].x_advance += c->font->em_scale_x (v); - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) - buffer->pos[idx].x_offset += c->font->em_scale_x (v); - } - else - { - buffer->pos[idx].y_advance += c->font->em_scale_y (v); - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) - buffer->pos[idx].y_offset += c->font->em_scale_y (v); - } - } - } - depth = 0; - } - - return true; - } - - private: - AAT::hb_aat_apply_context_t *c; - const KernSubTableFormat1 *table; - const UnsizedArrayOf<FWORD> &kernAction; - unsigned int stack[8]; - unsigned int depth; - }; - - inline bool apply (AAT::hb_aat_apply_context_t *c) const - { - TRACE_APPLY (this); - - if (!c->plan->requested_kerning) - return false; - - driver_context_t dc (this, c); - - AAT::StateTableDriver<AAT::MortTypes, EntryData> driver (machine, c->buffer, c->font->face); - driver.drive (&dc); - - return_trace (true); - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - /* The rest of array sanitizations are done at run-time. */ - return_trace (likely (c->check_struct (this) && - machine.sanitize (c))); - } - - protected: - AAT::StateTable<AAT::MortTypes, EntryData> machine; - OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false> kernAction; - public: - DEFINE_SIZE_STATIC (10); -}; - -struct KernClassTable -{ - inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - classes.sanitize (c)); - } - - protected: - HBUINT16 firstGlyph; /* First glyph in class range. */ - ArrayOf<HBUINT16> classes; /* Glyph classes. */ - public: - DEFINE_SIZE_ARRAY (4, classes); -}; - -struct KernSubTableFormat2 -{ - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, - AAT::hb_aat_apply_context_t *c) const - { - /* This subtable is disabled. It's not cleaer to me *exactly* where the offests are - * based from. I *think* they should be based from beginning of kern subtable wrapper, - * *NOT* "this". Since we know of no fonts that use this subtable, we are disabling - * it. Someday fix it and re-enable. */ - return 0; - unsigned int l = (this+leftClassTable).get_class (left); - unsigned int r = (this+rightClassTable).get_class (right); - unsigned int offset = l + r; - const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset); -#if 0 - if (unlikely ((const char *) v < (const char *) &array || - (const char *) v > (const char *) end - 2)) -#endif - return 0; - return *v; - } - - inline bool apply (AAT::hb_aat_apply_context_t *c) const - { - TRACE_APPLY (this); - - if (!c->plan->requested_kerning) - return false; - - accelerator_t accel (*this, c); - hb_kern_machine_t<accelerator_t> machine (accel); - machine.kern (c->font, c->buffer, c->plan->kern_mask); - - return_trace (true); - } - - struct accelerator_t - { - const KernSubTableFormat2 &table; - AAT::hb_aat_apply_context_t *c; - - inline accelerator_t (const KernSubTableFormat2 &table_, - AAT::hb_aat_apply_context_t *c_) : - table (table_), c (c_) {} - - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table.get_kerning (left, right, c); } - }; - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (true); /* Disabled. See above. */ - return_trace (c->check_struct (this) && - leftClassTable.sanitize (c, this) && - rightClassTable.sanitize (c, this) && - array.sanitize (c, this)); - } - - protected: - HBUINT16 rowWidth; /* The width, in bytes, of a row in the table. */ - OffsetTo<KernClassTable> - leftClassTable; /* Offset from beginning of this subtable to - * left-hand class table. */ - OffsetTo<KernClassTable> - rightClassTable;/* Offset from beginning of this subtable to - * right-hand class table. */ - OffsetTo<FWORD> - array; /* Offset from beginning of this subtable to - * the start of the kerning array. */ - public: - DEFINE_SIZE_MIN (8); -}; - +template <typename KernSubTableHeader> struct KernSubTableFormat3 { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const @@ -431,7 +66,10 @@ struct KernSubTableFormat3 if (!c->plan->requested_kerning) return false; - hb_kern_machine_t<KernSubTableFormat3> machine (*this); + if (header.coverage & header.Backwards) + return false; + + hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); return_trace (true); @@ -448,299 +86,224 @@ 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<FWORD> - 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<FWORD> kernValueZ; /* The kerning values. + * Length kernValueCount. */ #if 0 - UnsizedArrayOf<HBUINT8> - leftClass; /* The left-hand classes. - * Length glyphCount. */ - UnsizedArrayOf<HBUINT8> - RightClass; /* The right-hand classes. - * Length glyphCount. */ - UnsizedArrayOf<HBUINT8> - kernIndex; /* The indices into the kernValue array. - * Length leftClassCount * rightClassCount */ + UnsizedArrayOf<HBUINT8>leftClass; /* The left-hand classes. + * Length glyphCount. */ + UnsizedArrayOf<HBUINT8>rightClass; /* The right-hand classes. + * Length glyphCount. */ + UnsizedArrayOf<HBUINT8>kernIndex; /* 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 <typename KernSubTableHeader> 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 unsigned int get_type (void) const { return u.header.format; } + + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - switch (format) { + switch (get_type ()) { /* 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 + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const { - /* TODO Switch to dispatch(). */ - switch (format) { - case 0: u.format0.apply (c); return; - case 1: u.format1.apply (c); return; - case 2: u.format2.apply (c); return; - case 3: u.format3.apply (c); return; - default: return; + unsigned int subtable_type = get_type (); + TRACE_DISPATCH (this, subtable_type); + switch (subtable_type) { + case 0: return_trace (c->dispatch (u.format0)); + case 1: return_trace (u.header.apple ? c->dispatch (u.format1) : c->default_return_value ()); + case 2: return_trace (c->dispatch (u.format2)); + case 3: return_trace (u.header.apple ? c->dispatch (u.format3) : c->default_return_value ()); + default: return_trace (c->default_return_value ()); } } - 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) { - case 0: return_trace (u.format0.sanitize (c)); - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - case 3: return_trace (u.format3.sanitize (c)); - default:return_trace (true); - } + if (unlikely (!u.header.sanitize (c) || + u.header.length < u.header.min_size || + !c->check_range (this, u.header.length))) return_trace (false); + + return_trace (dispatch (c)); } - protected: + public: union { - KernSubTableFormat0 format0; - KernSubTableFormat1 format1; - KernSubTableFormat2 format2; - KernSubTableFormat3 format3; + KernSubTableHeader header; + AAT::KerxSubTableFormat0<KernSubTableHeader> format0; + AAT::KerxSubTableFormat1<KernSubTableHeader> format1; + AAT::KerxSubTableFormat2<KernSubTableHeader> format2; + KernSubTableFormat3<KernSubTableHeader> format3; } u; public: DEFINE_SIZE_MIN (0); }; -template <typename T> -struct KernSubTableWrapper +struct KernOTSubTableHeader { - /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - inline const T* thiz (void) const { return static_cast<const T *> (this); } + static const bool apple = false; + typedef AAT::ObsoleteTypes Types; - inline bool is_supported (void) const - { return !(thiz()->coverage & T::CheckFlags); } - - inline bool is_horizontal (void) const - { return (thiz()->coverage & T::Direction) == T::CheckHorizontal; } - - 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 int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return is_supported () && is_horizontal () ? get_kerning (left, right) : 0; } + inline unsigned int tuple_count (void) const { return 0; } + inline bool is_horizontal (void) const { return (coverage & Horizontal); } - 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; } + enum Coverage + { + Horizontal = 0x01u, + Minimum = 0x02u, + CrossStream = 0x04u, + Override = 0x08u, + + /* Not supported: */ + Backwards = 0x00u, + Variation = 0x00u, + }; 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)); + 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. */ + public: + DEFINE_SIZE_STATIC (6); }; -template <typename T> -struct KernTable +struct KernOT : AAT::KerxTable<KernOT> { - /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - inline const T* thiz (void) const { return static_cast<const T *> (this); } - - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { - int v = 0; - const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ); - unsigned int count = thiz()->nTables; - for (unsigned int i = 0; i < count; i++) - { - if (st->is_supported () && st->is_override ()) - v = 0; - v += st->get_h_kerning (left, right); - st = &StructAfter<typename T::SubTableWrapper> (*st); - } - return v; - } + friend struct AAT::KerxTable<KernOT>; - inline void apply (AAT::hb_aat_apply_context_t *c) const - { - c->set_lookup_index (0); - const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ); - unsigned int count = thiz()->nTables; - /* If there's an override subtable, skip subtables before that. */ - unsigned int last_override = 0; - for (unsigned int i = 0; i < count; i++) - { - if (st->is_supported () && st->is_override ()) - last_override = i; - st = &StructAfter<typename T::SubTableWrapper> (*st); - } - st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ); - for (unsigned int i = 0; i < count; i++) - { - if (!st->is_supported ()) - goto skip; + static const hb_tag_t tableTag = HB_OT_TAG_kern; + static const uint16_t minVersion = 0; - if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->is_horizontal ()) - goto skip; + typedef KernOTSubTableHeader SubTableHeader; + typedef SubTableHeader::Types Types; + typedef KernSubTable<SubTableHeader> SubTable; - if (i < last_override) - goto skip; + protected: + HBUINT16 version; /* Version--0x0000u */ + HBUINT16 tableCount; /* Number of subtables in the kerning table. */ + SubTable firstSubTable; /* Subtables. */ + public: + DEFINE_SIZE_MIN (4); +}; - if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index)) - goto skip; - c->sanitizer.set_object (*st); +struct KernAATSubTableHeader +{ + static const bool apple = true; + typedef AAT::ObsoleteTypes Types; - st->apply (c); + inline unsigned int tuple_count (void) const { return 0; } + inline bool is_horizontal (void) const { return !(coverage & Vertical); } - (void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index); + enum Coverage + { + Vertical = 0x80u, + CrossStream = 0x40u, + Variation = 0x20u, - skip: - st = &StructAfter<typename T::SubTableWrapper> (*st); - } - } + /* Not supported: */ + Backwards = 0x00u, + }; inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (thiz()) || - thiz()->version != T::VERSION)) - return_trace (false); - - const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&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<typename T::SubTableWrapper> (*st); - } - - return_trace (true); + return_trace (c->check_struct (this)); } -}; - -struct KernOT : KernTable<KernOT> -{ - friend struct KernTable<KernOT>; - - static const uint16_t VERSION = 0x0000u; - - struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper> - { - friend struct KernTable<KernOT>; - friend struct KernSubTableWrapper<SubTableWrapper>; - - enum Coverage - { - Direction = 0x01u, - Minimum = 0x02u, - CrossStream = 0x04u, - Override = 0x08u, - - Variation = 0x00u, /* Not supported. */ - - CheckFlags = 0x06u, - CheckHorizontal = 0x01u - }; - - protected: - 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); - }; - protected: - HBUINT16 version; /* Version--0x0000u */ - HBUINT16 nTables; /* Number of subtables in the kerning table. */ - UnsizedArrayOf<HBUINT8> dataZ; public: - DEFINE_SIZE_ARRAY (4, dataZ); + 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. + * Note: We don't implement. */ + public: + DEFINE_SIZE_STATIC (8); }; -struct KernAAT : KernTable<KernAAT> +struct KernAAT : AAT::KerxTable<KernAAT> { - friend struct KernTable<KernAAT>; + friend struct AAT::KerxTable<KernAAT>; - static const uint32_t VERSION = 0x00010000u; + static const hb_tag_t tableTag = HB_OT_TAG_kern; + static const uint32_t minVersion = 0x00010000u; - struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper> - { - friend struct KernTable<KernAAT>; - friend struct KernSubTableWrapper<SubTableWrapper>; - - enum Coverage - { - Direction = 0x80u, - CrossStream = 0x40u, - Variation = 0x20u, - - Override = 0x00u, /* Not supported. */ - - CheckFlags = 0x60u, - CheckHorizontal = 0x00u - }; - - protected: - 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); - }; + typedef KernAATSubTableHeader SubTableHeader; + typedef SubTableHeader::Types Types; + typedef KernSubTable<SubTableHeader> SubTable; protected: - HBUINT32 version; /* Version--0x00010000u */ - HBUINT32 nTables; /* Number of subtables in the kerning table. */ - UnsizedArrayOf<HBUINT8> dataZ; + HBUINT32 version; /* Version--0x00010000u */ + HBUINT32 tableCount; /* Number of subtables in the kerning table. */ + SubTable firstSubTable; /* Subtables. */ public: - DEFINE_SIZE_ARRAY (8, dataZ); + DEFINE_SIZE_MIN (8); }; struct kern { static const hb_tag_t tableTag = HB_OT_TAG_kern; - inline bool has_data (void) const - { return u.version32 != 0; } + inline bool has_data (void) const { return u.version32; } + inline unsigned int get_type (void) const { return u.major; } + + inline bool has_cross_stream (void) const + { + switch (get_type ()) { + case 0: return u.ot.has_cross_stream (); + case 1: return u.aat.has_cross_stream (); + default:return false; + } + } inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - switch (u.major) { + switch (get_type ()) { case 0: return u.ot.get_h_kerning (left, right); case 1: return u.aat.get_h_kerning (left, right); default:return 0; } } - inline void apply (AAT::hb_aat_apply_context_t *c) const + inline bool apply (AAT::hb_aat_apply_context_t *c) const + { return dispatch (c); } + + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const { - /* TODO Switch to dispatch(). */ - switch (u.major) { - case 0: u.ot.apply (c); return; - case 1: u.aat.apply (c); return; - default: return; + unsigned int subtable_type = get_type (); + TRACE_DISPATCH (this, subtable_type); + switch (subtable_type) { + case 0: return_trace (c->dispatch (u.ot)); + case 1: return_trace (c->dispatch (u.aat)); + default: return_trace (c->default_return_value ()); } } @@ -748,11 +311,7 @@ struct kern { TRACE_SANITIZE (this); if (!u.version32.sanitize (c)) return_trace (false); - switch (u.major) { - case 0: return_trace (u.ot.sanitize (c)); - case 1: return_trace (u.aat.sanitize (c)); - default:return_trace (true); - } + return_trace (dispatch (c)); } protected: |