From 095a1257cc3cc56b044b4cd842a92f0d0f933a50 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 19 Feb 2015 10:29:41 +0300 Subject: [PATCH] [layout] Port sanitize() to use dispatch() Needed some rework of Extension table. Hopefully I got it right, and the new template usage doesn't break any compilers... --- src/hb-open-type-private.hh | 5 +- src/hb-ot-layout-gpos-table.hh | 82 +-------------------------- src/hb-ot-layout-gsub-table.hh | 72 +----------------------- src/hb-ot-layout-gsubgpos-private.hh | 84 ++++++++++------------------ 4 files changed, 37 insertions(+), 206 deletions(-) diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 4ed46c167..197495e74 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -179,10 +179,13 @@ struct hb_sanitize_context_t inline const char *get_name (void) { return "SANITIZE"; } static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; typedef bool return_t; + template + inline bool may_dispatch (const T *obj, const F *format) + { return format->sanitize (this); } template inline return_t dispatch (const T &obj) { return obj.sanitize (this); } static return_t default_return_value (void) { return true; } - bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return false; } + bool stop_sublookup_iteration (const return_t r) const { return !r; } inline void init (hb_blob_t *b) { diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index a3599a97c..9f1df4c1e 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -556,17 +556,6 @@ struct SinglePos } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -862,17 +851,6 @@ struct PairPos } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1031,16 +1009,6 @@ struct CursivePos } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1134,16 +1102,6 @@ struct MarkBasePos } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1259,16 +1217,6 @@ struct MarkLigPos } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1382,16 +1330,6 @@ struct MarkMarkPos } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1436,6 +1374,7 @@ struct PosLookupSubTable inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const { TRACE_DISPATCH (this, lookup_type); + /* The sub_format passed to may_dispatch is unnecessary but harmless. */ if (unlikely (!c->may_dispatch (this, &u.sub_format))) TRACE_RETURN (c->default_return_value ()); switch (lookup_type) { case Single: return TRACE_RETURN (u.single.dispatch (c)); @@ -1451,23 +1390,6 @@ struct PosLookupSubTable } } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) const - { - TRACE_SANITIZE (this); - switch (lookup_type) { - case Single: return TRACE_RETURN (u.single.sanitize (c)); - case Pair: return TRACE_RETURN (u.pair.sanitize (c)); - case Cursive: return TRACE_RETURN (u.cursive.sanitize (c)); - case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c)); - case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c)); - case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c)); - case Context: return TRACE_RETURN (u.context.sanitize (c)); - case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)); - case Extension: return TRACE_RETURN (u.extension.sanitize (c)); - default: return TRACE_RETURN (true); - } - } - protected: union { USHORT sub_format; @@ -1531,7 +1453,7 @@ struct PosLookup : Lookup TRACE_SANITIZE (this); if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); const OffsetArrayOf &list = get_subtables (); - return TRACE_RETURN (list.sanitize (c, this, get_type ())); + return TRACE_RETURN (dispatch (c)); } }; diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 66ee0886c..9e0c8a3dd 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -233,17 +233,6 @@ struct SingleSubst } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -436,16 +425,6 @@ struct MultipleSubst } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -590,16 +569,6 @@ struct AlternateSubst } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -911,16 +880,6 @@ struct LigatureSubst } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1078,16 +1037,6 @@ struct ReverseChainSingleSubst } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -1120,6 +1069,7 @@ struct SubstLookupSubTable inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const { TRACE_DISPATCH (this, lookup_type); + /* The sub_format passed to may_dispatch is unnecessary but harmless. */ if (unlikely (!c->may_dispatch (this, &u.sub_format))) TRACE_RETURN (c->default_return_value ()); switch (lookup_type) { case Single: return TRACE_RETURN (u.single.dispatch (c)); @@ -1134,22 +1084,6 @@ struct SubstLookupSubTable } } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) const - { - TRACE_SANITIZE (this); - switch (lookup_type) { - case Single: return TRACE_RETURN (u.single.sanitize (c)); - case Multiple: return TRACE_RETURN (u.multiple.sanitize (c)); - case Alternate: return TRACE_RETURN (u.alternate.sanitize (c)); - case Ligature: return TRACE_RETURN (u.ligature.sanitize (c)); - case Context: return TRACE_RETURN (u.context.sanitize (c)); - case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)); - case Extension: return TRACE_RETURN (u.extension.sanitize (c)); - case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.sanitize (c)); - default: return TRACE_RETURN (true); - } - } - protected: union { USHORT sub_format; @@ -1291,7 +1225,7 @@ struct SubstLookup : Lookup TRACE_SANITIZE (this); if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); const OffsetArrayOf &list = get_subtables (); - if (unlikely (!list.sanitize (c, this, get_type ()))) return TRACE_RETURN (false); + if (unlikely (!dispatch (c))) return TRACE_RETURN (false); if (unlikely (get_type () == SubstLookupSubTable::Extension)) { @@ -1363,7 +1297,7 @@ GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSE { unsigned int type = get_type (); if (unlikely (type == SubstLookupSubTable::Extension)) - return CastR (get_subtable()).is_reverse (); + return CastR (get_subtable()).is_reverse (); return SubstLookup::lookup_type_is_reverse (type); } diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index d891b6e1a..cbc6840bc 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -1524,18 +1524,6 @@ struct Context } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - case 3: return TRACE_RETURN (u.format3.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -2149,18 +2137,6 @@ struct ChainContext } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); - switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - case 3: return TRACE_RETURN (u.format3.sanitize (c)); - default:return TRACE_RETURN (true); - } - } - protected: union { USHORT format; /* Format identifier */ @@ -2171,15 +2147,32 @@ struct ChainContext }; +template struct ExtensionFormat1 { inline unsigned int get_type (void) const { return extensionLookupType; } - inline unsigned int get_offset (void) const { return extensionOffset; } + template + inline const X& get_subtable (void) const + { + unsigned int offset = extensionOffset; + if (unlikely (!offset)) return Null(typename T::LookupSubTable); + return StructAtOffset (this, offset); + } + + template + inline typename context_t::return_t dispatch (context_t *c) const + { + TRACE_DISPATCH (this, format); + if (unlikely (!c->may_dispatch (this, this))) TRACE_RETURN (c->default_return_value ()); + return get_subtable ().dispatch (c, get_type ()); + } + + /* This is called from may_dispatch() above with hb_sanitize_context_t. */ inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return TRACE_RETURN (c->check_struct (this) && extensionOffset != 0); } protected: @@ -2203,51 +2196,30 @@ struct Extension default:return 0; } } - inline unsigned int get_offset (void) const - { - switch (u.format) { - case 1: return u.format1.get_offset (); - default:return 0; - } - } - template inline const X& get_subtable (void) const { - unsigned int offset = get_offset (); - if (unlikely (!offset)) return Null(typename T::LookupSubTable); - return StructAtOffset (this, offset); + switch (u.format) { + case 1: return u.format1.template get_subtable (); + default:return Null(typename T::LookupSubTable); + } } template inline typename context_t::return_t dispatch (context_t *c) const { - return get_subtable ().dispatch (c, get_type ()); - } - - inline bool sanitize_self (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); + TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); + case 1: return TRACE_RETURN (u.format1.dispatch (c)); + default:return TRACE_RETURN (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!sanitize_self (c)) return TRACE_RETURN (false); - unsigned int offset = get_offset (); - if (unlikely (!offset)) return TRACE_RETURN (true); - return TRACE_RETURN (StructAtOffset (this, offset).sanitize (c, get_type ())); - } - protected: union { USHORT format; /* Format identifier */ - ExtensionFormat1 format1; + ExtensionFormat1 format1; } u; };