summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh380
1 files changed, 177 insertions, 203 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
index 57fc1e05f7..cbc6840bc8 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
@@ -37,12 +37,6 @@
namespace OT {
-
-#define TRACE_DISPATCH(this, format) \
- hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "format %d", (int) format);
-
#ifndef HB_DEBUG_CLOSURE
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
#endif
@@ -58,6 +52,8 @@ struct hb_closure_context_t
static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE;
typedef hb_void_t return_t;
typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
+ template <typename T, typename F>
+ inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T>
inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
static return_t default_return_value (void) { return HB_VOID; }
@@ -107,6 +103,8 @@ struct hb_would_apply_context_t
inline const char *get_name (void) { return "WOULD_APPLY"; }
static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY;
typedef bool return_t;
+ template <typename T, typename F>
+ inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T>
inline return_t dispatch (const T &obj) { return obj.would_apply (this); }
static return_t default_return_value (void) { return false; }
@@ -146,6 +144,8 @@ struct hb_collect_glyphs_context_t
static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS;
typedef hb_void_t return_t;
typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
+ template <typename T, typename F>
+ inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T>
inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
static return_t default_return_value (void) { return HB_VOID; }
@@ -232,18 +232,28 @@ struct hb_collect_glyphs_context_t
#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
#endif
-struct hb_get_coverage_context_t
+template <typename set_t>
+struct hb_add_coverage_context_t
{
inline const char *get_name (void) { return "GET_COVERAGE"; }
static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE;
typedef const Coverage &return_t;
+ template <typename T, typename F>
+ inline bool may_dispatch (const T *obj, const F *format) { return true; }
template <typename T>
inline return_t dispatch (const T &obj) { return obj.get_coverage (); }
static return_t default_return_value (void) { return Null(Coverage); }
+ bool stop_sublookup_iteration (return_t r) const
+ {
+ r.add_coverage (set);
+ return false;
+ }
- hb_get_coverage_context_t (void) :
+ hb_add_coverage_context_t (set_t *set_) :
+ set (set_),
debug_depth (0) {}
+ set_t *set;
unsigned int debug_depth;
};
@@ -260,61 +270,6 @@ struct hb_get_coverage_context_t
struct hb_apply_context_t
{
- inline const char *get_name (void) { return "APPLY"; }
- static const unsigned int max_debug_depth = HB_DEBUG_APPLY;
- typedef bool return_t;
- typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
- template <typename T>
- inline return_t dispatch (const T &obj) { return obj.apply (this); }
- static return_t default_return_value (void) { return false; }
- bool stop_sublookup_iteration (return_t r) const { return r; }
- return_t recurse (unsigned int lookup_index)
- {
- if (unlikely (nesting_level_left == 0 || !recurse_func))
- return default_return_value ();
-
- nesting_level_left--;
- bool ret = recurse_func (this, lookup_index);
- nesting_level_left++;
- return ret;
- }
-
- unsigned int table_index; /* GSUB/GPOS */
- hb_font_t *font;
- hb_face_t *face;
- hb_buffer_t *buffer;
- hb_direction_t direction;
- hb_mask_t lookup_mask;
- bool auto_zwj;
- recurse_func_t recurse_func;
- unsigned int nesting_level_left;
- unsigned int lookup_props;
- const GDEF &gdef;
- bool has_glyph_classes;
- unsigned int debug_depth;
-
-
- hb_apply_context_t (unsigned int table_index_,
- hb_font_t *font_,
- hb_buffer_t *buffer_) :
- table_index (table_index_),
- font (font_), face (font->face), buffer (buffer_),
- direction (buffer_->props.direction),
- lookup_mask (1),
- auto_zwj (true),
- recurse_func (NULL),
- nesting_level_left (MAX_NESTING_LEVEL),
- lookup_props (0),
- gdef (*hb_ot_layout_from_face (face)->gdef),
- has_glyph_classes (gdef.has_glyph_classes ()),
- debug_depth (0) {}
-
- inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
- inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; }
- inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
- inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
- inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); }
-
struct matcher_t
{
inline matcher_t (void) :
@@ -390,29 +345,24 @@ struct hb_apply_context_t
const void *match_data;
};
- struct skipping_forward_iterator_t
- {
- inline skipping_forward_iterator_t (hb_apply_context_t *c_,
- unsigned int start_index_,
- unsigned int num_items_,
- bool context_match = false) :
- idx (start_index_),
- c (c_),
- match_glyph_data (NULL),
- num_items (num_items_),
- end (c->buffer->len)
+ struct skipping_iterator_t
+ {
+ inline void init (hb_apply_context_t *c_, bool context_match = false)
{
+ c = c_;
+ match_glyph_data = NULL,
+ matcher.set_match_func (NULL, NULL);
matcher.set_lookup_props (c->lookup_props);
/* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
matcher.set_ignore_zwnj (context_match || c->table_index == 1);
/* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */
matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj);
- if (!context_match)
- matcher.set_mask (c->lookup_mask);
- matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
+ matcher.set_mask (context_match ? -1 : c->lookup_mask);
+ }
+ inline void set_lookup_props (unsigned int lookup_props)
+ {
+ matcher.set_lookup_props (lookup_props);
}
- inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
- inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); }
inline void set_match_func (matcher_t::match_func_t match_func,
const void *match_data,
const USHORT glyph_data[])
@@ -421,12 +371,21 @@ struct hb_apply_context_t
match_glyph_data = glyph_data;
}
- inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); }
+ inline void reset (unsigned int start_index_,
+ unsigned int num_items_)
+ {
+ idx = start_index_;
+ num_items = num_items_;
+ end = c->buffer->len;
+ matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
+ }
+
inline void reject (void) { num_items++; match_glyph_data--; }
+
inline bool next (void)
{
assert (num_items > 0);
- while (!has_no_chance ())
+ while (idx + num_items < end)
{
idx++;
const hb_glyph_info_t &info = c->buffer->info[idx];
@@ -450,53 +409,10 @@ struct hb_apply_context_t
}
return false;
}
-
- unsigned int idx;
- protected:
- hb_apply_context_t *c;
- matcher_t matcher;
- const USHORT *match_glyph_data;
-
- unsigned int num_items;
- unsigned int end;
- };
-
- struct skipping_backward_iterator_t
- {
- inline skipping_backward_iterator_t (hb_apply_context_t *c_,
- unsigned int start_index_,
- unsigned int num_items_,
- bool context_match = false) :
- idx (start_index_),
- c (c_),
- match_glyph_data (NULL),
- num_items (num_items_)
- {
- matcher.set_lookup_props (c->lookup_props);
- /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
- matcher.set_ignore_zwnj (context_match || c->table_index == 1);
- /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */
- matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj);
- if (!context_match)
- matcher.set_mask (c->lookup_mask);
- matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
- }
- inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
- inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); }
- inline void set_match_func (matcher_t::match_func_t match_func,
- const void *match_data,
- const USHORT glyph_data[])
- {
- matcher.set_match_func (match_func, match_data);
- match_glyph_data = glyph_data;
- }
-
- inline bool has_no_chance (void) const { return unlikely (idx < num_items); }
- inline void reject (void) { num_items++; }
inline bool prev (void)
{
assert (num_items > 0);
- while (!has_no_chance ())
+ while (idx >= num_items)
{
idx--;
const hb_glyph_info_t &info = c->buffer->out_info[idx];
@@ -528,8 +444,75 @@ struct hb_apply_context_t
const USHORT *match_glyph_data;
unsigned int num_items;
+ unsigned int end;
};
+
+ inline const char *get_name (void) { return "APPLY"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_APPLY;
+ typedef bool return_t;
+ typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
+ template <typename T, typename F>
+ inline bool may_dispatch (const T *obj, const F *format) { return true; }
+ template <typename T>
+ inline return_t dispatch (const T &obj) { return obj.apply (this); }
+ static return_t default_return_value (void) { return false; }
+ bool stop_sublookup_iteration (return_t r) const { return r; }
+ return_t recurse (unsigned int lookup_index)
+ {
+ if (unlikely (nesting_level_left == 0 || !recurse_func))
+ return default_return_value ();
+
+ nesting_level_left--;
+ bool ret = recurse_func (this, lookup_index);
+ nesting_level_left++;
+ return ret;
+ }
+
+ unsigned int table_index; /* GSUB/GPOS */
+ hb_font_t *font;
+ hb_face_t *face;
+ hb_buffer_t *buffer;
+ hb_direction_t direction;
+ hb_mask_t lookup_mask;
+ bool auto_zwj;
+ recurse_func_t recurse_func;
+ unsigned int nesting_level_left;
+ unsigned int lookup_props;
+ const GDEF &gdef;
+ bool has_glyph_classes;
+ skipping_iterator_t iter_input, iter_context;
+ unsigned int debug_depth;
+
+
+ hb_apply_context_t (unsigned int table_index_,
+ hb_font_t *font_,
+ hb_buffer_t *buffer_) :
+ table_index (table_index_),
+ font (font_), face (font->face), buffer (buffer_),
+ direction (buffer_->props.direction),
+ lookup_mask (1),
+ auto_zwj (true),
+ recurse_func (NULL),
+ nesting_level_left (MAX_NESTING_LEVEL),
+ lookup_props (0),
+ gdef (*hb_ot_layout_from_face (face)->gdef),
+ has_glyph_classes (gdef.has_glyph_classes ()),
+ iter_input (),
+ iter_context (),
+ debug_depth (0) {}
+
+ inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
+ inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; }
+ inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+ inline void set_lookup (const Lookup &l) { set_lookup_props (l.get_props ()); }
+ inline void set_lookup_props (unsigned int lookup_props_)
+ {
+ lookup_props = lookup_props_;
+ iter_input.init (this, false);
+ iter_context.init (this, true);
+ }
+
inline bool
match_properties_mark (hb_codepoint_t glyph,
unsigned int glyph_props,
@@ -741,9 +724,9 @@ static inline bool match_input (hb_apply_context_t *c,
hb_buffer_t *buffer = c->buffer;
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1);
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (buffer->idx, count - 1);
skippy_iter.set_match_func (match_func, match_data, input);
- if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
/*
* This is perhaps the trickiest part of OpenType... Remarks:
@@ -910,9 +893,9 @@ static inline bool match_backtrack (hb_apply_context_t *c,
{
TRACE_APPLY (NULL);
- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true);
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
+ skippy_iter.reset (c->buffer->backtrack_len (), count);
skippy_iter.set_match_func (match_func, match_data, backtrack);
- if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
for (unsigned int i = 0; i < count; i++)
if (!skippy_iter.prev ())
@@ -930,9 +913,9 @@ static inline bool match_lookahead (hb_apply_context_t *c,
{
TRACE_APPLY (NULL);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true);
+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
+ skippy_iter.reset (c->buffer->idx + offset - 1, count);
skippy_iter.set_match_func (match_func, match_data, lookahead);
- if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
for (unsigned int i = 0; i < count; i++)
if (!skippy_iter.next ())
@@ -945,7 +928,8 @@ static inline bool match_lookahead (hb_apply_context_t *c,
struct LookupRecord
{
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
@@ -1168,7 +1152,8 @@ struct Rule
}
public:
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
return inputCount.sanitize (c)
&& lookupCount.sanitize (c)
@@ -1232,7 +1217,8 @@ struct RuleSet
return TRACE_RETURN (false);
}
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
return TRACE_RETURN (rule.sanitize (c, this));
}
@@ -1314,7 +1300,8 @@ struct ContextFormat1
return TRACE_RETURN (rule_set.apply (c, lookup_context));
}
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
}
@@ -1406,7 +1393,8 @@ struct ContextFormat2
return TRACE_RETURN (rule_set.apply (c, lookup_context));
}
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
}
@@ -1494,7 +1482,8 @@ struct ContextFormat3
return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
}
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
if (!c->check_struct (this)) return TRACE_RETURN (false);
unsigned int count = glyphCount;
@@ -1502,7 +1491,7 @@ struct ContextFormat3
if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRACE_RETURN (false);
for (unsigned int i = 0; i < count; i++)
if (!coverageZ[i].sanitize (c, this)) return TRACE_RETURN (false);
- LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count);
return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount));
}
@@ -1526,6 +1515,7 @@ struct Context
inline typename context_t::return_t dispatch (context_t *c) const
{
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 (c->dispatch (u.format1));
case 2: return TRACE_RETURN (c->dispatch (u.format2));
@@ -1534,17 +1524,6 @@ struct Context
}
}
- inline bool sanitize (hb_sanitize_context_t *c) {
- 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 */
@@ -1726,14 +1705,15 @@ struct ChainRule
lookup.array, lookup_context));
}
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
if (!backtrack.sanitize (c)) return TRACE_RETURN (false);
- HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+ const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
if (!input.sanitize (c)) return TRACE_RETURN (false);
- ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
if (!lookahead.sanitize (c)) return TRACE_RETURN (false);
- ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
return TRACE_RETURN (lookup.sanitize (c));
}
@@ -1795,7 +1775,8 @@ struct ChainRuleSet
return TRACE_RETURN (false);
}
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
return TRACE_RETURN (rule.sanitize (c, this));
}
@@ -1874,7 +1855,8 @@ struct ChainContextFormat1
return TRACE_RETURN (rule_set.apply (c, lookup_context));
}
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
}
@@ -1984,7 +1966,8 @@ struct ChainContextFormat2
return TRACE_RETURN (rule_set.apply (c, lookup_context));
}
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) &&
inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) &&
@@ -2105,15 +2088,16 @@ struct ChainContextFormat3
lookup.len, lookup.array, lookup_context));
}
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false);
- OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
if (!input.sanitize (c, this)) return TRACE_RETURN (false);
if (!input.len) return TRACE_RETURN (false); /* To be consistent with Context. */
- OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false);
- ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
return TRACE_RETURN (lookup.sanitize (c));
}
@@ -2144,6 +2128,7 @@ struct ChainContext
inline typename context_t::return_t dispatch (context_t *c) const
{
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 (c->dispatch (u.format1));
case 2: return TRACE_RETURN (c->dispatch (u.format2));
@@ -2152,17 +2137,6 @@ struct ChainContext
}
}
- inline bool sanitize (hb_sanitize_context_t *c) {
- 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 */
@@ -2173,14 +2147,32 @@ struct ChainContext
};
+template <typename T>
struct ExtensionFormat1
{
inline unsigned int get_type (void) const { return extensionLookupType; }
- inline unsigned int get_offset (void) const { return extensionOffset; }
- inline bool sanitize (hb_sanitize_context_t *c) {
+ template <typename X>
+ inline const X& get_subtable (void) const
+ {
+ unsigned int offset = extensionOffset;
+ if (unlikely (!offset)) return Null(typename T::LookupSubTable);
+ return StructAtOffset<typename T::LookupSubTable> (this, offset);
+ }
+
+ template <typename context_t>
+ 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<typename T::LookupSubTable> ().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:
@@ -2204,49 +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 <typename X>
inline const X& get_subtable (void) const
{
- unsigned int offset = get_offset ();
- if (unlikely (!offset)) return Null(typename T::LookupSubTable);
- return StructAtOffset<typename T::LookupSubTable> (this, offset);
+ switch (u.format) {
+ case 1: return u.format1.template get_subtable<typename T::LookupSubTable> ();
+ default:return Null(typename T::LookupSubTable);
+ }
}
template <typename context_t>
inline typename context_t::return_t dispatch (context_t *c) const
{
- return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ());
- }
-
- inline bool sanitize_self (hb_sanitize_context_t *c) {
- 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) {
- 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<typename T::LookupSubTable> (this, offset).sanitize (c, get_type ()));
- }
-
protected:
union {
USHORT format; /* Format identifier */
- ExtensionFormat1 format1;
+ ExtensionFormat1<T> format1;
} u;
};
@@ -2291,7 +2264,8 @@ struct GSUBGPOS
inline const Lookup& get_lookup (unsigned int i) const
{ return (this+lookupList)[i]; }
- inline bool sanitize (hb_sanitize_context_t *c) {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
TRACE_SANITIZE (this);
return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
scriptList.sanitize (c, this) &&