Revert "Imported Upstream version 1.2.7"
[platform/upstream/harfbuzz.git] / src / hb-ot-layout-gsub-table.hh
index 7de56cf..ebe4c9e 100644 (file)
@@ -67,7 +67,7 @@ struct SingleSubstFormat1
   inline bool would_apply (hb_would_apply_context_t *c) const
   {
     TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+    return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
   }
 
   inline bool apply (hb_apply_context_t *c) const
@@ -75,14 +75,14 @@ struct SingleSubstFormat1
     TRACE_APPLY (this);
     hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
     unsigned int index = (this+coverage).get_coverage (glyph_id);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     /* According to the Adobe Annotated OpenType Suite, result is always
      * limited to 16bit. */
     glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu;
     c->replace_glyph (glyph_id);
 
-    return_trace (true);
+    return TRACE_RETURN (true);
   }
 
   inline bool serialize (hb_serialize_context_t *c,
@@ -91,16 +91,16 @@ struct SingleSubstFormat1
                         int delta)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
     deltaGlyphID.set (delta); /* TODO(serilaize) overflow? */
-    return_trace (true);
+    return TRACE_RETURN (true);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
+    return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
   }
 
   protected:
@@ -144,7 +144,7 @@ struct SingleSubstFormat2
   inline bool would_apply (hb_would_apply_context_t *c) const
   {
     TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+    return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
   }
 
   inline bool apply (hb_apply_context_t *c) const
@@ -152,14 +152,14 @@ struct SingleSubstFormat2
     TRACE_APPLY (this);
     hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
     unsigned int index = (this+coverage).get_coverage (glyph_id);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
-    if (unlikely (index >= substitute.len)) return_trace (false);
+    if (unlikely (index >= substitute.len)) return TRACE_RETURN (false);
 
     glyph_id = substitute[index];
     c->replace_glyph (glyph_id);
 
-    return_trace (true);
+    return TRACE_RETURN (true);
   }
 
   inline bool serialize (hb_serialize_context_t *c,
@@ -168,16 +168,16 @@ struct SingleSubstFormat2
                         unsigned int num_glyphs)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-    if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return_trace (false);
-    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
-    return_trace (true);
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return TRACE_RETURN (false);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
+    return TRACE_RETURN (true);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && substitute.sanitize (c));
+    return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c));
   }
 
   protected:
@@ -200,7 +200,7 @@ struct SingleSubst
                         unsigned int num_glyphs)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
     unsigned int format = 2;
     int delta = 0;
     if (num_glyphs) {
@@ -215,9 +215,9 @@ struct SingleSubst
     }
     u.format.set (format);
     switch (u.format) {
-    case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs, delta));
-    case 2: return_trace (u.format2.serialize (c, glyphs, substitutes, num_glyphs));
-    default:return_trace (false);
+    case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs, delta));
+    case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, substitutes, num_glyphs));
+    default:return TRACE_RETURN (false);
     }
   }
 
@@ -225,11 +225,11 @@ struct SingleSubst
   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));
-    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));
+    default:return TRACE_RETURN (c->default_return_value ());
     }
   }
 
@@ -273,14 +273,14 @@ struct Sequence
      * buffer->move_to() makes assumptions about this too.  Perhaps fix
      * in the future after figuring out what to do with the clusters.
      */
-    if (unlikely (!count)) return_trace (false);
+    if (unlikely (!count)) return TRACE_RETURN (false);
 
     /* Special-case to make it in-place and not consider this
      * as a "multiplied" substitution. */
     if (unlikely (count == 1))
     {
       c->replace_glyph (substitute.array[0]);
-      return_trace (true);
+      return TRACE_RETURN (true);
     }
 
     unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
@@ -292,7 +292,7 @@ struct Sequence
     }
     c->buffer->skip_glyph ();
 
-    return_trace (true);
+    return TRACE_RETURN (true);
   }
 
   inline bool serialize (hb_serialize_context_t *c,
@@ -300,15 +300,15 @@ struct Sequence
                         unsigned int num_glyphs)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-    if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return_trace (false);
-    return_trace (true);
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
+    return TRACE_RETURN (true);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (substitute.sanitize (c));
+    return TRACE_RETURN (substitute.sanitize (c));
   }
 
   protected:
@@ -347,7 +347,7 @@ struct MultipleSubstFormat1
   inline bool would_apply (hb_would_apply_context_t *c) const
   {
     TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+    return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
   }
 
   inline bool apply (hb_apply_context_t *c) const
@@ -355,9 +355,9 @@ struct MultipleSubstFormat1
     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);
 
-    return_trace ((this+sequence[index]).apply (c));
+    return TRACE_RETURN ((this+sequence[index]).apply (c));
   }
 
   inline bool serialize (hb_serialize_context_t *c,
@@ -367,21 +367,21 @@ struct MultipleSubstFormat1
                         Supplier<GlyphID> &substitute_glyphs_list)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-    if (unlikely (!sequence.serialize (c, num_glyphs))) return_trace (false);
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    if (unlikely (!sequence.serialize (c, num_glyphs))) return TRACE_RETURN (false);
     for (unsigned int i = 0; i < num_glyphs; i++)
       if (unlikely (!sequence[i].serialize (c, this).serialize (c,
                                                                substitute_glyphs_list,
-                                                               substitute_len_list[i]))) return_trace (false);
+                                                               substitute_len_list[i]))) return TRACE_RETURN (false);
     substitute_len_list.advance (num_glyphs);
-    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
-    return_trace (true);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
+    return TRACE_RETURN (true);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && sequence.sanitize (c, this));
+    return TRACE_RETURN (coverage.sanitize (c, this) && sequence.sanitize (c, this));
   }
 
   protected:
@@ -405,12 +405,12 @@ struct MultipleSubst
                         Supplier<GlyphID> &substitute_glyphs_list)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
     unsigned int format = 1;
     u.format.set (format);
     switch (u.format) {
-    case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, num_glyphs, substitute_glyphs_list));
-    default:return_trace (false);
+    case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, substitute_len_list, num_glyphs, substitute_glyphs_list));
+    default:return TRACE_RETURN (false);
     }
   }
 
@@ -418,10 +418,10 @@ struct MultipleSubst
   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));
-    default:return_trace (c->default_return_value ());
+    case 1: return TRACE_RETURN (c->dispatch (u.format1));
+    default:return TRACE_RETURN (c->default_return_value ());
     }
   }
 
@@ -473,7 +473,7 @@ struct AlternateSubstFormat1
   inline bool would_apply (hb_would_apply_context_t *c) const
   {
     TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+    return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
   }
 
   inline bool apply (hb_apply_context_t *c) const
@@ -482,11 +482,11 @@ struct AlternateSubstFormat1
     hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
 
     unsigned int index = (this+coverage).get_coverage (glyph_id);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     const AlternateSet &alt_set = this+alternateSet[index];
 
-    if (unlikely (!alt_set.len)) return_trace (false);
+    if (unlikely (!alt_set.len)) return TRACE_RETURN (false);
 
     hb_mask_t glyph_mask = c->buffer->cur().mask;
     hb_mask_t lookup_mask = c->lookup_mask;
@@ -495,13 +495,13 @@ struct AlternateSubstFormat1
     unsigned int shift = _hb_ctz (lookup_mask);
     unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
 
-    if (unlikely (alt_index > alt_set.len || alt_index == 0)) return_trace (false);
+    if (unlikely (alt_index > alt_set.len || alt_index == 0)) return TRACE_RETURN (false);
 
     glyph_id = alt_set[alt_index - 1];
 
     c->replace_glyph (glyph_id);
 
-    return_trace (true);
+    return TRACE_RETURN (true);
   }
 
   inline bool serialize (hb_serialize_context_t *c,
@@ -511,21 +511,21 @@ struct AlternateSubstFormat1
                         Supplier<GlyphID> &alternate_glyphs_list)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-    if (unlikely (!alternateSet.serialize (c, num_glyphs))) return_trace (false);
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    if (unlikely (!alternateSet.serialize (c, num_glyphs))) return TRACE_RETURN (false);
     for (unsigned int i = 0; i < num_glyphs; i++)
       if (unlikely (!alternateSet[i].serialize (c, this).serialize (c,
                                                                    alternate_glyphs_list,
-                                                                   alternate_len_list[i]))) return_trace (false);
+                                                                   alternate_len_list[i]))) return TRACE_RETURN (false);
     alternate_len_list.advance (num_glyphs);
-    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
-    return_trace (true);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
+    return TRACE_RETURN (true);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
+    return TRACE_RETURN (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
   }
 
   protected:
@@ -549,12 +549,12 @@ struct AlternateSubst
                         Supplier<GlyphID> &alternate_glyphs_list)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
     unsigned int format = 1;
     u.format.set (format);
     switch (u.format) {
-    case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, num_glyphs, alternate_glyphs_list));
-    default:return_trace (false);
+    case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, alternate_len_list, num_glyphs, alternate_glyphs_list));
+    default:return TRACE_RETURN (false);
     }
   }
 
@@ -562,10 +562,10 @@ struct AlternateSubst
   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));
-    default:return_trace (c->default_return_value ());
+    case 1: return TRACE_RETURN (c->dispatch (u.format1));
+    default:return TRACE_RETURN (c->default_return_value ());
     }
   }
 
@@ -602,13 +602,13 @@ struct Ligature
   {
     TRACE_WOULD_APPLY (this);
     if (c->len != component.len)
-      return_trace (false);
+      return TRACE_RETURN (false);
 
     for (unsigned int i = 1; i < c->len; i++)
       if (likely (c->glyphs[i] != component[i]))
-       return_trace (false);
+       return TRACE_RETURN (false);
 
-    return_trace (true);
+    return TRACE_RETURN (true);
   }
 
   inline bool apply (hb_apply_context_t *c) const
@@ -616,21 +616,21 @@ struct Ligature
     TRACE_APPLY (this);
     unsigned int count = component.len;
 
-    if (unlikely (!count)) return_trace (false);
+    if (unlikely (!count)) return TRACE_RETURN (false);
 
     /* Special-case to make it in-place and not consider this
      * as a "ligated" substitution. */
     if (unlikely (count == 1))
     {
       c->replace_glyph (ligGlyph);
-      return_trace (true);
+      return TRACE_RETURN (true);
     }
 
     bool is_mark_ligature = false;
     unsigned int total_component_count = 0;
 
     unsigned int match_length = 0;
-    unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
+    unsigned int match_positions[MAX_CONTEXT_LENGTH];
 
     if (likely (!match_input (c, count,
                              &component[1],
@@ -640,7 +640,7 @@ struct Ligature
                              match_positions,
                              &is_mark_ligature,
                              &total_component_count)))
-      return_trace (false);
+      return TRACE_RETURN (false);
 
     ligate_input (c,
                  count,
@@ -650,7 +650,7 @@ struct Ligature
                  is_mark_ligature,
                  total_component_count);
 
-    return_trace (true);
+    return TRACE_RETURN (true);
   }
 
   inline bool serialize (hb_serialize_context_t *c,
@@ -659,17 +659,17 @@ struct Ligature
                         unsigned int num_components /* Including first component */)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
     ligGlyph = ligature;
-    if (unlikely (!component.serialize (c, components, num_components))) return_trace (false);
-    return_trace (true);
+    if (unlikely (!component.serialize (c, components, num_components))) return TRACE_RETURN (false);
+    return TRACE_RETURN (true);
   }
 
   public:
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (ligGlyph.sanitize (c) && component.sanitize (c));
+    return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c));
   }
 
   protected:
@@ -708,9 +708,9 @@ struct LigatureSet
     {
       const Ligature &lig = this+ligature[i];
       if (lig.would_apply (c))
-        return_trace (true);
+        return TRACE_RETURN (true);
     }
-    return_trace (false);
+    return TRACE_RETURN (false);
   }
 
   inline bool apply (hb_apply_context_t *c) const
@@ -720,10 +720,10 @@ struct LigatureSet
     for (unsigned int i = 0; i < num_ligs; i++)
     {
       const Ligature &lig = this+ligature[i];
-      if (lig.apply (c)) return_trace (true);
+      if (lig.apply (c)) return TRACE_RETURN (true);
     }
 
-    return_trace (false);
+    return TRACE_RETURN (false);
   }
 
   inline bool serialize (hb_serialize_context_t *c,
@@ -733,22 +733,22 @@ struct LigatureSet
                         Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-    if (unlikely (!ligature.serialize (c, num_ligatures))) return_trace (false);
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    if (unlikely (!ligature.serialize (c, num_ligatures))) return TRACE_RETURN (false);
     for (unsigned int i = 0; i < num_ligatures; i++)
       if (unlikely (!ligature[i].serialize (c, this).serialize (c,
                                                                ligatures[i],
                                                                component_list,
-                                                               component_count_list[i]))) return_trace (false);
+                                                               component_count_list[i]))) return TRACE_RETURN (false);
     ligatures.advance (num_ligatures);
     component_count_list.advance (num_ligatures);
-    return_trace (true);
+    return TRACE_RETURN (true);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (ligature.sanitize (c, this));
+    return TRACE_RETURN (ligature.sanitize (c, this));
   }
 
   protected:
@@ -790,10 +790,10 @@ struct LigatureSubstFormat1
   {
     TRACE_WOULD_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     const LigatureSet &lig_set = this+ligatureSet[index];
-    return_trace (lig_set.would_apply (c));
+    return TRACE_RETURN (lig_set.would_apply (c));
   }
 
   inline bool apply (hb_apply_context_t *c) const
@@ -802,10 +802,10 @@ struct LigatureSubstFormat1
     hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
 
     unsigned int index = (this+coverage).get_coverage (glyph_id);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
 
     const LigatureSet &lig_set = this+ligatureSet[index];
-    return_trace (lig_set.apply (c));
+    return TRACE_RETURN (lig_set.apply (c));
   }
 
   inline bool serialize (hb_serialize_context_t *c,
@@ -817,23 +817,23 @@ struct LigatureSubstFormat1
                         Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-    if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return_trace (false);
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return TRACE_RETURN (false);
     for (unsigned int i = 0; i < num_first_glyphs; i++)
       if (unlikely (!ligatureSet[i].serialize (c, this).serialize (c,
                                                                   ligatures_list,
                                                                   component_count_list,
                                                                   ligature_per_first_glyph_count_list[i],
-                                                                  component_list))) return_trace (false);
+                                                                  component_list))) return TRACE_RETURN (false);
     ligature_per_first_glyph_count_list.advance (num_first_glyphs);
-    if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return_trace (false);
-    return_trace (true);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return TRACE_RETURN (false);
+    return TRACE_RETURN (true);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
+    return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
   }
 
   protected:
@@ -859,18 +859,13 @@ struct LigatureSubst
                         Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
     unsigned int format = 1;
     u.format.set (format);
     switch (u.format) {
-    case 1: return_trace (u.format1.serialize (c,
-                                              first_glyphs,
-                                              ligature_per_first_glyph_count_list,
-                                              num_first_glyphs,
-                                              ligatures_list,
-                                              component_count_list,
-                                              component_list));
-    default:return_trace (false);
+    case 1: return TRACE_RETURN (u.format1.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs,
+                                                     ligatures_list, component_count_list, component_list));
+    default:return TRACE_RETURN (false);
     }
   }
 
@@ -878,10 +873,10 @@ struct LigatureSubst
   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));
-    default:return_trace (c->default_return_value ());
+    case 1: return TRACE_RETURN (c->dispatch (u.format1));
+    default:return TRACE_RETURN (c->default_return_value ());
     }
   }
 
@@ -964,17 +959,17 @@ struct ReverseChainSingleSubstFormat1
   inline bool would_apply (hb_would_apply_context_t *c) const
   {
     TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+    return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
   }
 
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL))
-      return_trace (false); /* No chaining to this type */
+    if (unlikely (c->nesting_level_left != MAX_NESTING_LEVEL))
+      return TRACE_RETURN (false); /* No chaining to this type */
 
     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 OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
     const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
@@ -991,22 +986,22 @@ struct ReverseChainSingleSubstFormat1
       /* Note: We DON'T decrease buffer->idx.  The main loop does it
        * for us.  This is useful for preventing surprises if someone
        * calls us through a Context lookup. */
-      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);
     if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
-      return_trace (false);
+      return TRACE_RETURN (false);
     const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
     if (!lookahead.sanitize (c, this))
-      return_trace (false);
+      return TRACE_RETURN (false);
     const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
-    return_trace (substitute.sanitize (c));
+    return TRACE_RETURN (substitute.sanitize (c));
   }
 
   protected:
@@ -1035,10 +1030,10 @@ struct ReverseChainSingleSubst
   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));
-    default:return_trace (c->default_return_value ());
+    case 1: return TRACE_RETURN (c->dispatch (u.format1));
+    default:return TRACE_RETURN (c->default_return_value ());
     }
   }
 
@@ -1074,17 +1069,18 @@ struct SubstLookupSubTable
   inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
   {
     TRACE_DISPATCH (this, lookup_type);
-    if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ());
+    /* 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 (u.single.dispatch (c));
-    case Multiple:             return_trace (u.multiple.dispatch (c));
-    case Alternate:            return_trace (u.alternate.dispatch (c));
-    case Ligature:             return_trace (u.ligature.dispatch (c));
-    case Context:              return_trace (u.context.dispatch (c));
-    case ChainContext:         return_trace (u.chainContext.dispatch (c));
-    case Extension:            return_trace (u.extension.dispatch (c));
-    case ReverseChainSingle:   return_trace (u.reverseChainContextSingle.dispatch (c));
-    default:                   return_trace (c->default_return_value ());
+    case Single:               return TRACE_RETURN (u.single.dispatch (c));
+    case Multiple:             return TRACE_RETURN (u.multiple.dispatch (c));
+    case Alternate:            return TRACE_RETURN (u.alternate.dispatch (c));
+    case Ligature:             return TRACE_RETURN (u.ligature.dispatch (c));
+    case Context:              return TRACE_RETURN (u.context.dispatch (c));
+    case ChainContext:         return TRACE_RETURN (u.chainContext.dispatch (c));
+    case Extension:            return TRACE_RETURN (u.extension.dispatch (c));
+    case ReverseChainSingle:   return TRACE_RETURN (u.reverseChainContextSingle.dispatch (c));
+    default:                   return TRACE_RETURN (c->default_return_value ());
     }
   }
 
@@ -1124,21 +1120,21 @@ struct SubstLookup : Lookup
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    return_trace (dispatch (c));
+    return TRACE_RETURN (dispatch (c));
   }
 
   inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
   {
     TRACE_CLOSURE (this);
     c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>);
-    return_trace (dispatch (c));
+    return TRACE_RETURN (dispatch (c));
   }
 
   inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
     c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>);
-    return_trace (dispatch (c));
+    return TRACE_RETURN (dispatch (c));
   }
 
   template <typename set_t>
@@ -1152,9 +1148,9 @@ struct SubstLookup : Lookup
                           const hb_ot_layout_lookup_accelerator_t *accel) const
   {
     TRACE_WOULD_APPLY (this);
-    if (unlikely (!c->len))  return_trace (false);
-    if (!accel->may_have (c->glyphs[0]))  return_trace (false);
-      return_trace (dispatch (c));
+    if (unlikely (!c->len))  return TRACE_RETURN (false);
+    if (!accel->may_have (c->glyphs[0]))  return TRACE_RETURN (false);
+      return TRACE_RETURN (dispatch (c));
   }
 
   static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
@@ -1170,8 +1166,8 @@ struct SubstLookup : Lookup
                                unsigned int num_glyphs)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return_trace (false);
-    return_trace (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs));
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return TRACE_RETURN (false);
+    return TRACE_RETURN (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs));
   }
 
   inline bool serialize_multiple (hb_serialize_context_t *c,
@@ -1182,12 +1178,9 @@ struct SubstLookup : Lookup
                                  Supplier<GlyphID> &substitute_glyphs_list)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return_trace (false);
-    return_trace (serialize_subtable (c, 0).u.multiple.serialize (c,
-                                                                 glyphs,
-                                                                 substitute_len_list,
-                                                                 num_glyphs,
-                                                                 substitute_glyphs_list));
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return TRACE_RETURN (false);
+    return TRACE_RETURN (serialize_subtable (c, 0).u.multiple.serialize (c, glyphs, substitute_len_list, num_glyphs,
+                                                                        substitute_glyphs_list));
   }
 
   inline bool serialize_alternate (hb_serialize_context_t *c,
@@ -1198,12 +1191,9 @@ struct SubstLookup : Lookup
                                   Supplier<GlyphID> &alternate_glyphs_list)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return_trace (false);
-    return_trace (serialize_subtable (c, 0).u.alternate.serialize (c,
-                                                                  glyphs,
-                                                                  alternate_len_list,
-                                                                  num_glyphs,
-                                                                  alternate_glyphs_list));
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return TRACE_RETURN (false);
+    return TRACE_RETURN (serialize_subtable (c, 0).u.alternate.serialize (c, glyphs, alternate_len_list, num_glyphs,
+                                                                         alternate_glyphs_list));
   }
 
   inline bool serialize_ligature (hb_serialize_context_t *c,
@@ -1216,14 +1206,9 @@ struct SubstLookup : Lookup
                                  Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return_trace (false);
-    return_trace (serialize_subtable (c, 0).u.ligature.serialize (c,
-                                                                 first_glyphs,
-                                                                 ligature_per_first_glyph_count_list,
-                                                                 num_first_glyphs,
-                                                                 ligatures_list,
-                                                                 component_count_list,
-                                                                 component_list));
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return TRACE_RETURN (false);
+    return TRACE_RETURN (serialize_subtable (c, 0).u.ligature.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs,
+                                                                        ligatures_list, component_count_list, component_list));
   }
 
   template <typename context_t>
@@ -1236,8 +1221,9 @@ struct SubstLookup : Lookup
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (!Lookup::sanitize (c))) return_trace (false);
-    if (unlikely (!dispatch (c))) return_trace (false);
+    if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
+    const OffsetArrayOf<SubstLookupSubTable> &list = get_subtables<SubstLookupSubTable> ();
+    if (unlikely (!dispatch (c))) return TRACE_RETURN (false);
 
     if (unlikely (get_type () == SubstLookupSubTable::Extension))
     {
@@ -1248,9 +1234,9 @@ struct SubstLookup : Lookup
       unsigned int count = get_subtable_count ();
       for (unsigned int i = 1; i < count; i++)
         if (get_subtable (i).u.extension.get_type () != type)
-         return_trace (false);
+         return TRACE_RETURN (false);
     }
-    return_trace (true);
+    return TRACE_RETURN (true);
   }
 };
 
@@ -1268,13 +1254,14 @@ struct GSUB : GSUBGPOS
   { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
 
   static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer);
+  static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer);
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false);
+    if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
     const OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList);
-    return_trace (list.sanitize (c, this));
+    return TRACE_RETURN (list.sanitize (c, this));
   }
   public:
   DEFINE_SIZE_STATIC (10);
@@ -1288,32 +1275,19 @@ GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
 
   const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef;
   unsigned int count = buffer->len;
-  hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
   {
-    unsigned int props = gdef.get_glyph_props (info[i].codepoint);
-    if (!props)
-    {
-      /* Never mark default-ignorables as marks.
-       * They won't get in the way of lookups anyway,
-       * but having them as mark will cause them to be skipped
-       * over if the lookup-flag says so, but at least for the
-       * Mongolian variation selectors, looks like Uniscribe
-       * marks them as non-mark.  Some Mongolian fonts without
-       * GDEF rely on this.  Another notable character that
-       * this applies to is COMBINING GRAPHEME JOINER. */
-      props = (_hb_glyph_info_get_general_category (&info[i]) !=
-              HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ||
-              _hb_glyph_info_is_default_ignorable (&info[i])) ?
-             HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH :
-             HB_OT_LAYOUT_GLYPH_PROPS_MARK;
-    }
-    _hb_glyph_info_set_glyph_props (&info[i], props);
-    _hb_glyph_info_clear_lig_props (&info[i]);
+    _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
+    _hb_glyph_info_clear_lig_props (&buffer->info[i]);
     buffer->info[i].syllable() = 0;
   }
 }
 
+void
+GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
+{
+}
+
 
 /* Out-of-class implementation for methods recursing */
 
@@ -1338,11 +1312,8 @@ template <typename context_t>
   const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
   const SubstLookup &l = gsub.get_lookup (lookup_index);
   unsigned int saved_lookup_props = c->lookup_props;
-  unsigned int saved_lookup_index = c->lookup_index;
-  c->set_lookup_index (lookup_index);
-  c->set_lookup_props (l.get_props ());
+  c->set_lookup (l);
   bool ret = l.dispatch (c);
-  c->set_lookup_index (saved_lookup_index);
   c->set_lookup_props (saved_lookup_props);
   return ret;
 }