Revert "Imported Upstream version 1.2.7"
[platform/upstream/harfbuzz.git] / src / hb-ot-layout-gsubgpos-private.hh
index 56c5015..cbc6840 100644 (file)
@@ -46,11 +46,14 @@ namespace OT {
        (&c->debug_depth, c->get_name (), this, HB_FUNC, \
         "");
 
-struct hb_closure_context_t :
-       hb_dispatch_context_t<hb_closure_context_t, hb_void_t, HB_DEBUG_CLOSURE>
+struct hb_closure_context_t
 {
   inline const char *get_name (void) { return "CLOSURE"; }
+  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; }
@@ -74,7 +77,7 @@ struct hb_closure_context_t :
 
   hb_closure_context_t (hb_face_t *face_,
                        hb_set_t *glyphs_,
-                       unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
+                       unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
                          face (face_),
                          glyphs (glyphs_),
                          recurse_func (NULL),
@@ -95,10 +98,13 @@ struct hb_closure_context_t :
        (&c->debug_depth, c->get_name (), this, HB_FUNC, \
         "%d glyphs", c->len);
 
-struct hb_would_apply_context_t :
-       hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY>
+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; }
@@ -132,11 +138,14 @@ struct hb_would_apply_context_t :
        (&c->debug_depth, c->get_name (), this, HB_FUNC, \
         "");
 
-struct hb_collect_glyphs_context_t :
-       hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, HB_DEBUG_COLLECT_GLYPHS>
+struct hb_collect_glyphs_context_t
 {
   inline const char *get_name (void) { return "COLLECT_GLYPHS"; }
+  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; }
@@ -196,7 +205,7 @@ struct hb_collect_glyphs_context_t :
                               hb_set_t  *glyphs_input,  /* OUT. May be NULL */
                               hb_set_t  *glyphs_after,  /* OUT. May be NULL */
                               hb_set_t  *glyphs_output, /* OUT. May be NULL */
-                              unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
+                              unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
                              face (face_),
                              before (glyphs_before ? glyphs_before : hb_set_get_empty ()),
                              input  (glyphs_input  ? glyphs_input  : hb_set_get_empty ()),
@@ -223,14 +232,14 @@ struct hb_collect_glyphs_context_t :
 #define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
 #endif
 
-/* XXX Can we remove this? */
-
 template <typename set_t>
-struct hb_add_coverage_context_t :
-       hb_dispatch_context_t<hb_add_coverage_context_t<set_t>, const Coverage &, HB_DEBUG_GET_COVERAGE>
+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); }
@@ -257,11 +266,9 @@ struct hb_add_coverage_context_t :
 #define TRACE_APPLY(this) \
        hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
        (&c->debug_depth, c->get_name (), this, HB_FUNC, \
-        "idx %d gid %u lookup %d", \
-        c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index);
+        "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint);
 
-struct hb_apply_context_t :
-       hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY>
+struct hb_apply_context_t
 {
   struct matcher_t
   {
@@ -319,9 +326,10 @@ struct hb_apply_context_t :
       if (!c->check_glyph_property (&info, lookup_props))
        return SKIP_YES;
 
-      if (unlikely (_hb_glyph_info_is_default_ignorable_and_not_fvs (&info) &&
+      if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
                    (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
-                   (ignore_zwj || !_hb_glyph_info_is_zwj (&info))))
+                   (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
+                   !_hb_glyph_info_ligated (&info)))
        return SKIP_MAYBE;
 
       return SKIP_NO;
@@ -355,11 +363,11 @@ struct hb_apply_context_t :
     {
       matcher.set_lookup_props (lookup_props);
     }
-    inline void set_match_func (matcher_t::match_func_t match_func_,
-                               const void *match_data_,
+    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_);
+      matcher.set_match_func (match_func, match_data);
       match_glyph_data = glyph_data;
     }
 
@@ -441,7 +449,11 @@ 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, 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; }
@@ -470,7 +482,6 @@ struct hb_apply_context_t :
   const GDEF &gdef;
   bool has_glyph_classes;
   skipping_iterator_t iter_input, iter_context;
-  unsigned int lookup_index;
   unsigned int debug_depth;
 
 
@@ -483,19 +494,18 @@ struct hb_apply_context_t :
                        lookup_mask (1),
                        auto_zwj (true),
                        recurse_func (NULL),
-                       nesting_level_left (HB_MAX_NESTING_LEVEL),
+                       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 (),
-                       lookup_index ((unsigned int) -1),
                        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_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
+  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_;
@@ -506,39 +516,39 @@ struct hb_apply_context_t :
   inline bool
   match_properties_mark (hb_codepoint_t  glyph,
                         unsigned int    glyph_props,
-                        unsigned int    match_props) const
+                        unsigned int    lookup_props) const
   {
     /* If using mark filtering sets, the high short of
-     * match_props has the set index.
+     * lookup_props has the set index.
      */
-    if (match_props & LookupFlag::UseMarkFilteringSet)
-      return gdef.mark_set_covers (match_props >> 16, glyph);
+    if (lookup_props & LookupFlag::UseMarkFilteringSet)
+      return gdef.mark_set_covers (lookup_props >> 16, glyph);
 
-    /* The second byte of match_props has the meaning
+    /* The second byte of lookup_props has the meaning
      * "ignore marks of attachment type different than
      * the attachment type specified."
      */
-    if (match_props & LookupFlag::MarkAttachmentType)
-      return (match_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
+    if (lookup_props & LookupFlag::MarkAttachmentType)
+      return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
 
     return true;
   }
 
   inline bool
   check_glyph_property (const hb_glyph_info_t *info,
-                       unsigned int  match_props) const
+                       unsigned int  lookup_props) const
   {
     hb_codepoint_t glyph = info->codepoint;
     unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
 
     /* Not covered, if, for example, glyph class is ligature and
-     * match_props includes LookupFlags::IgnoreLigatures
+     * lookup_props includes LookupFlags::IgnoreLigatures
      */
-    if (glyph_props & match_props & LookupFlag::IgnoreFlags)
+    if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
       return false;
 
     if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
-      return match_properties_mark (glyph, glyph_props, match_props);
+      return match_properties_mark (glyph, glyph_props, lookup_props);
 
     return true;
   }
@@ -704,13 +714,13 @@ static inline bool match_input (hb_apply_context_t *c,
                                match_func_t match_func,
                                const void *match_data,
                                unsigned int *end_offset,
-                               unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
+                               unsigned int match_positions[MAX_CONTEXT_LENGTH],
                                bool *p_is_mark_ligature = NULL,
                                unsigned int *p_total_component_count = NULL)
 {
   TRACE_APPLY (NULL);
 
-  if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false);
+  if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false);
 
   hb_buffer_t *buffer = c->buffer;
 
@@ -747,7 +757,7 @@ static inline bool match_input (hb_apply_context_t *c,
   match_positions[0] = buffer->idx;
   for (unsigned int i = 1; i < count; i++)
   {
-    if (!skippy_iter.next ()) return_trace (false);
+    if (!skippy_iter.next ()) return TRACE_RETURN (false);
 
     match_positions[i] = skippy_iter.idx;
 
@@ -759,13 +769,13 @@ static inline bool match_input (hb_apply_context_t *c,
        * all subsequent components should be attached to the same ligature
        * component, otherwise we shouldn't ligate them. */
       if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
-       return_trace (false);
+       return TRACE_RETURN (false);
     } else {
       /* If first component was NOT attached to a previous ligature component,
        * all subsequent components should also NOT be attached to any ligature
        * component, unless they are attached to the first component itself! */
       if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id))
-       return_trace (false);
+       return TRACE_RETURN (false);
     }
 
     is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]);
@@ -780,11 +790,11 @@ static inline bool match_input (hb_apply_context_t *c,
   if (p_total_component_count)
     *p_total_component_count = total_component_count;
 
-  return_trace (true);
+  return TRACE_RETURN (true);
 }
-static inline bool ligate_input (hb_apply_context_t *c,
+static inline void ligate_input (hb_apply_context_t *c,
                                 unsigned int count, /* Including the first glyph */
-                                unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
+                                unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
                                 unsigned int match_length,
                                 hb_codepoint_t lig_glyph,
                                 bool is_mark_ligature,
@@ -836,21 +846,19 @@ static inline bool ligate_input (hb_apply_context_t *c,
     if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
     {
       _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
+      _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0);
     }
   }
   c->replace_glyph_with_ligature (lig_glyph, klass);
 
   for (unsigned int i = 1; i < count; i++)
   {
-    while (buffer->idx < match_positions[i] && !buffer->in_error)
+    while (buffer->idx < match_positions[i])
     {
       if (!is_mark_ligature) {
-        unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
-       if (this_comp == 0)
-         this_comp = last_num_components;
        unsigned int new_lig_comp = components_so_far - last_num_components +
-                                   MIN (this_comp, last_num_components);
-         _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
+                                   MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components);
+       _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
       }
       buffer->next_glyph ();
     }
@@ -867,17 +875,14 @@ static inline bool ligate_input (hb_apply_context_t *c,
     /* Re-adjust components for any marks following. */
     for (unsigned int i = buffer->idx; i < buffer->len; i++) {
       if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
-        unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]);
-       if (!this_comp)
-         break;
        unsigned int new_lig_comp = components_so_far - last_num_components +
-                                   MIN (this_comp, last_num_components);
+                                   MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components);
        _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
       } else
        break;
     }
   }
-  return_trace (true);
+  TRACE_RETURN (true);
 }
 
 static inline bool match_backtrack (hb_apply_context_t *c,
@@ -894,9 +899,9 @@ static inline bool match_backtrack (hb_apply_context_t *c,
 
   for (unsigned int i = 0; i < count; i++)
     if (!skippy_iter.prev ())
-      return_trace (false);
+      return TRACE_RETURN (false);
 
-  return_trace (true);
+  return TRACE_RETURN (true);
 }
 
 static inline bool match_lookahead (hb_apply_context_t *c,
@@ -914,9 +919,9 @@ static inline bool match_lookahead (hb_apply_context_t *c,
 
   for (unsigned int i = 0; i < count; i++)
     if (!skippy_iter.next ())
-      return_trace (false);
+      return TRACE_RETURN (false);
 
-  return_trace (true);
+  return TRACE_RETURN (true);
 }
 
 
@@ -926,7 +931,7 @@ struct LookupRecord
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    return TRACE_RETURN (c->check_struct (this));
   }
 
   USHORT       sequenceIndex;          /* Index into current glyph
@@ -949,7 +954,7 @@ static inline void recurse_lookups (context_t *c,
 
 static inline bool apply_lookup (hb_apply_context_t *c,
                                 unsigned int count, /* Including the first glyph */
-                                unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
+                                unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
                                 unsigned int lookupCount,
                                 const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
                                 unsigned int match_length)
@@ -971,17 +976,12 @@ static inline bool apply_lookup (hb_apply_context_t *c,
       match_positions[j] += delta;
   }
 
-  for (unsigned int i = 0; i < lookupCount && !buffer->in_error; i++)
+  for (unsigned int i = 0; i < lookupCount; i++)
   {
     unsigned int idx = lookupRecord[i].sequenceIndex;
     if (idx >= count)
       continue;
 
-    /* Don't recurse to ourself at same position.
-     * Note that this test is too naive, it doesn't catch longer loops. */
-    if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index)
-      continue;
-
     buffer->move_to (match_positions[idx]);
 
     unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
@@ -999,13 +999,13 @@ static inline bool apply_lookup (hb_apply_context_t *c,
     /* end can't go back past the current match position.
      * Note: this is only true because we do NOT allow MultipleSubst
      * with zero sequence len. */
-    end = MAX (MIN((int) match_positions[idx] + 1, (int) new_len), int (end) + delta);
+    end = MAX ((int) match_positions[idx] + 1, int (end) + delta);
 
     unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
 
     if (delta > 0)
     {
-      if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH))
+      if (unlikely (delta + count > MAX_CONTEXT_LENGTH))
        break;
     }
     else
@@ -1032,7 +1032,7 @@ static inline bool apply_lookup (hb_apply_context_t *c,
 
   buffer->move_to (end);
 
-  return_trace (true);
+  return TRACE_RETURN (true);
 }
 
 
@@ -1104,7 +1104,7 @@ static inline bool context_apply_lookup (hb_apply_context_t *c,
                                         ContextApplyLookupContext &lookup_context)
 {
   unsigned int match_length = 0;
-  unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
+  unsigned int match_positions[MAX_CONTEXT_LENGTH];
   return match_input (c,
                      inputCount, input,
                      lookup_context.funcs.match, lookup_context.match_data,
@@ -1141,14 +1141,14 @@ struct Rule
   {
     TRACE_WOULD_APPLY (this);
     const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
-    return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
+    return TRACE_RETURN (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
   }
 
   inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
     const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
-    return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
+    return TRACE_RETURN (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
   }
 
   public:
@@ -1200,9 +1200,9 @@ struct RuleSet
     for (unsigned int i = 0; i < num_rules; i++)
     {
       if ((this+rule[i]).would_apply (c, lookup_context))
-        return_trace (true);
+        return TRACE_RETURN (true);
     }
-    return_trace (false);
+    return TRACE_RETURN (false);
   }
 
   inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
@@ -1212,15 +1212,15 @@ struct RuleSet
     for (unsigned int i = 0; i < num_rules; i++)
     {
       if ((this+rule[i]).apply (c, lookup_context))
-        return_trace (true);
+        return TRACE_RETURN (true);
     }
-    return_trace (false);
+    return TRACE_RETURN (false);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (rule.sanitize (c, this));
+    return TRACE_RETURN (rule.sanitize (c, this));
   }
 
   protected:
@@ -1277,7 +1277,7 @@ struct ContextFormat1
       {match_glyph},
       NULL
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1290,20 +1290,20 @@ struct ContextFormat1
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
     if (likely (index == NOT_COVERED))
-      return_trace (false);
+      return TRACE_RETURN (false);
 
     const RuleSet &rule_set = this+ruleSet[index];
     struct ContextApplyLookupContext lookup_context = {
       {match_glyph},
       NULL
     };
-    return_trace (rule_set.apply (c, lookup_context));
+    return TRACE_RETURN (rule_set.apply (c, lookup_context));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
+    return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
   }
 
   protected:
@@ -1369,7 +1369,7 @@ struct ContextFormat2
       {match_class},
       &class_def
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1381,7 +1381,7 @@ struct ContextFormat2
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     const ClassDef &class_def = this+classDef;
     index = class_def.get_class (c->buffer->cur().codepoint);
@@ -1390,13 +1390,13 @@ struct ContextFormat2
       {match_class},
       &class_def
     };
-    return_trace (rule_set.apply (c, lookup_context));
+    return TRACE_RETURN (rule_set.apply (c, lookup_context));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
+    return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
   }
 
   protected:
@@ -1460,7 +1460,7 @@ struct ContextFormat3
       {match_coverage},
       this
     };
-    return_trace (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+    return TRACE_RETURN (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1472,27 +1472,27 @@ struct ContextFormat3
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
     struct ContextApplyLookupContext lookup_context = {
       {match_coverage},
       this
     };
-    return_trace (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+    return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!c->check_struct (this)) return_trace (false);
+    if (!c->check_struct (this)) return TRACE_RETURN (false);
     unsigned int count = glyphCount;
-    if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */
-    if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return_trace (false);
+    if (!count) return TRACE_RETURN (false); /* We want to access coverageZ[0] freely. */
+    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 (false);
+      if (!coverageZ[i].sanitize (c, this)) return TRACE_RETURN (false);
     const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count);
-    return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount));
+    return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount));
   }
 
   protected:
@@ -1515,12 +1515,12 @@ 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))) return_trace (c->no_dispatch_return_value ());
+    if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
-    case 2: return_trace (c->dispatch (u.format2));
-    case 3: return_trace (c->dispatch (u.format3));
-    default:return_trace (c->default_return_value ());
+    case 1: return TRACE_RETURN (c->dispatch (u.format1));
+    case 2: return TRACE_RETURN (c->dispatch (u.format2));
+    case 3: return TRACE_RETURN (c->dispatch (u.format3));
+    default:return TRACE_RETURN (c->default_return_value ());
     }
   }
 
@@ -1631,7 +1631,7 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
                                               ChainContextApplyLookupContext &lookup_context)
 {
   unsigned int match_length = 0;
-  unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
+  unsigned int match_positions[MAX_CONTEXT_LENGTH];
   return match_input (c,
                      inputCount, input,
                      lookup_context.funcs.match, lookup_context.match_data[1],
@@ -1685,11 +1685,11 @@ struct ChainRule
     const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
     const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
-    return_trace (chain_context_would_apply_lookup (c,
-                                                   backtrack.len, backtrack.array,
-                                                   input.len, input.array,
-                                                   lookahead.len, lookahead.array, lookup.len,
-                                                   lookup.array, lookup_context));
+    return TRACE_RETURN (chain_context_would_apply_lookup (c,
+                                                          backtrack.len, backtrack.array,
+                                                          input.len, input.array,
+                                                          lookahead.len, lookahead.array, lookup.len,
+                                                          lookup.array, lookup_context));
   }
 
   inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
@@ -1698,23 +1698,23 @@ struct ChainRule
     const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
     const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
-    return_trace (chain_context_apply_lookup (c,
-                                             backtrack.len, backtrack.array,
-                                             input.len, input.array,
-                                             lookahead.len, lookahead.array, lookup.len,
-                                             lookup.array, lookup_context));
+    return TRACE_RETURN (chain_context_apply_lookup (c,
+                                                    backtrack.len, backtrack.array,
+                                                    input.len, input.array,
+                                                    lookahead.len, lookahead.array, lookup.len,
+                                                    lookup.array, lookup_context));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!backtrack.sanitize (c)) return_trace (false);
+    if (!backtrack.sanitize (c)) return TRACE_RETURN (false);
     const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
-    if (!input.sanitize (c)) return_trace (false);
+    if (!input.sanitize (c)) return TRACE_RETURN (false);
     const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
-    if (!lookahead.sanitize (c)) return_trace (false);
+    if (!lookahead.sanitize (c)) return TRACE_RETURN (false);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
-    return_trace (lookup.sanitize (c));
+    return TRACE_RETURN (lookup.sanitize (c));
   }
 
   protected:
@@ -1759,9 +1759,9 @@ struct ChainRuleSet
     unsigned int num_rules = rule.len;
     for (unsigned int i = 0; i < num_rules; i++)
       if ((this+rule[i]).would_apply (c, lookup_context))
-        return_trace (true);
+        return TRACE_RETURN (true);
 
-    return_trace (false);
+    return TRACE_RETURN (false);
   }
 
   inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
@@ -1770,15 +1770,15 @@ struct ChainRuleSet
     unsigned int num_rules = rule.len;
     for (unsigned int i = 0; i < num_rules; i++)
       if ((this+rule[i]).apply (c, lookup_context))
-        return_trace (true);
+        return TRACE_RETURN (true);
 
-    return_trace (false);
+    return TRACE_RETURN (false);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (rule.sanitize (c, this));
+    return TRACE_RETURN (rule.sanitize (c, this));
   }
 
   protected:
@@ -1833,7 +1833,7 @@ struct ChainContextFormat1
       {match_glyph},
       {NULL, NULL, NULL}
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1845,20 +1845,20 @@ struct ChainContextFormat1
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     const ChainRuleSet &rule_set = this+ruleSet[index];
     struct ChainContextApplyLookupContext lookup_context = {
       {match_glyph},
       {NULL, NULL, NULL}
     };
-    return_trace (rule_set.apply (c, lookup_context));
+    return TRACE_RETURN (rule_set.apply (c, lookup_context));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
+    return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
   }
 
   protected:
@@ -1937,7 +1937,7 @@ struct ChainContextFormat2
        &input_class_def,
        &lookahead_class_def}
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1949,7 +1949,7 @@ struct ChainContextFormat2
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     const ClassDef &backtrack_class_def = this+backtrackClassDef;
     const ClassDef &input_class_def = this+inputClassDef;
@@ -1963,17 +1963,15 @@ struct ChainContextFormat2
        &input_class_def,
        &lookahead_class_def}
     };
-    return_trace (rule_set.apply (c, lookup_context));
+    return TRACE_RETURN (rule_set.apply (c, lookup_context));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) &&
-                 backtrackClassDef.sanitize (c, this) &&
-                 inputClassDef.sanitize (c, this) &&
-                 lookaheadClassDef.sanitize (c, this) &&
-                 ruleSet.sanitize (c, this));
+    return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) &&
+                        inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) &&
+                        ruleSet.sanitize (c, this));
   }
 
   protected:
@@ -2056,11 +2054,11 @@ struct ChainContextFormat3
       {match_coverage},
       {this, this, this}
     };
-    return_trace (chain_context_would_apply_lookup (c,
-                                                   backtrack.len, (const USHORT *) backtrack.array,
-                                                   input.len, (const USHORT *) input.array + 1,
-                                                   lookahead.len, (const USHORT *) lookahead.array,
-                                                   lookup.len, lookup.array, lookup_context));
+    return TRACE_RETURN (chain_context_would_apply_lookup (c,
+                                                          backtrack.len, (const USHORT *) backtrack.array,
+                                                          input.len, (const USHORT *) input.array + 1,
+                                                          lookahead.len, (const USHORT *) lookahead.array,
+                                                          lookup.len, lookup.array, lookup_context));
   }
 
   inline const Coverage &get_coverage (void) const
@@ -2075,7 +2073,7 @@ struct ChainContextFormat3
     const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
 
     unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
@@ -2083,24 +2081,24 @@ struct ChainContextFormat3
       {match_coverage},
       {this, this, this}
     };
-    return_trace (chain_context_apply_lookup (c,
-                                             backtrack.len, (const USHORT *) backtrack.array,
-                                             input.len, (const USHORT *) input.array + 1,
-                                             lookahead.len, (const USHORT *) lookahead.array,
-                                             lookup.len, lookup.array, lookup_context));
+    return TRACE_RETURN (chain_context_apply_lookup (c,
+                                                    backtrack.len, (const USHORT *) backtrack.array,
+                                                    input.len, (const USHORT *) input.array + 1,
+                                                    lookahead.len, (const USHORT *) lookahead.array,
+                                                    lookup.len, lookup.array, lookup_context));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!backtrack.sanitize (c, this)) return_trace (false);
+    if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false);
     const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
-    if (!input.sanitize (c, this)) return_trace (false);
-    if (!input.len) return_trace (false); /* To be consistent with Context. */
+    if (!input.sanitize (c, this)) return TRACE_RETURN (false);
+    if (!input.len) return TRACE_RETURN (false); /* To be consistent with Context. */
     const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
-    if (!lookahead.sanitize (c, this)) return_trace (false);
+    if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
-    return_trace (lookup.sanitize (c));
+    return TRACE_RETURN (lookup.sanitize (c));
   }
 
   protected:
@@ -2130,12 +2128,12 @@ 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))) return_trace (c->no_dispatch_return_value ());
+    if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
     switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1));
-    case 2: return_trace (c->dispatch (u.format2));
-    case 3: return_trace (c->dispatch (u.format3));
-    default:return_trace (c->default_return_value ());
+    case 1: return TRACE_RETURN (c->dispatch (u.format1));
+    case 2: return TRACE_RETURN (c->dispatch (u.format2));
+    case 3: return TRACE_RETURN (c->dispatch (u.format3));
+    default:return TRACE_RETURN (c->default_return_value ());
     }
   }
 
@@ -2166,15 +2164,15 @@ struct ExtensionFormat1
   inline typename context_t::return_t dispatch (context_t *c) const
   {
     TRACE_DISPATCH (this, format);
-    if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ());
-    return_trace (get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()));
+    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 (c->check_struct (this) && extensionOffset != 0);
+    return TRACE_RETURN (c->check_struct (this) && extensionOffset != 0);
   }
 
   protected:
@@ -2211,10 +2209,10 @@ struct Extension
   inline typename context_t::return_t dispatch (context_t *c) const
   {
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
     switch (u.format) {
-    case 1: return_trace (u.format1.dispatch (c));
-    default:return_trace (c->default_return_value ());
+    case 1: return TRACE_RETURN (u.format1.dispatch (c));
+    default:return TRACE_RETURN (c->default_return_value ());
     }
   }
 
@@ -2269,15 +2267,14 @@ struct GSUBGPOS
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (version.sanitize (c) &&
-                 likely (version.major == 1) &&
-                 scriptList.sanitize (c, this) &&
-                 featureList.sanitize (c, this) &&
-                 lookupList.sanitize (c, this));
+    return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
+                        scriptList.sanitize (c, this) &&
+                        featureList.sanitize (c, this) &&
+                        lookupList.sanitize (c, this));
   }
 
   protected:
-  FixedVersion<>version;       /* Version of the GSUB/GPOS table--initially set
+  FixedVersion version;        /* Version of the GSUB/GPOS table--initially set
                                 * to 0x00010000u */
   OffsetTo<ScriptList>
                scriptList;     /* ScriptList table */