[HarfBuzz] harfbuzz-ng: Branch 'master' - 17 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Tue May 4 22:49:48 PDT 2010


 src/hb-buffer-private.h              |   30 +-
 src/hb-open-file-private.hh          |   19 -
 src/hb-open-type-private.hh          |  287 ++++++++++++------------
 src/hb-ot-layout-common-private.hh   |   55 ++--
 src/hb-ot-layout-gdef-private.hh     |   28 +-
 src/hb-ot-layout-gpos-private.hh     |  406 +++++++++++++++++------------------
 src/hb-ot-layout-gsub-private.hh     |  261 +++++++++++-----------
 src/hb-ot-layout-gsubgpos-private.hh |  240 ++++++++++----------
 8 files changed, 673 insertions(+), 653 deletions(-)

New commits:
commit 583d7f9586ce69754f1354aa3895e6d732a0c2ce
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 01:49:22 2010 -0400

    Cosmetic

diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index ed9369b..5684383 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -100,7 +100,8 @@ typedef struct OffsetTable
   public:
   inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    return SANITIZE_SELF () && SANITIZE_ARRAY (tableDir, TableDirectory::get_size (), numTables);
+    return SANITIZE_SELF ()
+	&& SANITIZE_ARRAY (tableDir, TableDirectory::get_size (), numTables);
   }
 
   private:
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 78a1c3b..8e90133 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -555,7 +555,8 @@ struct GenericArrayOf
   private:
   inline bool sanitize_shallow (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    return SANITIZE_SELF() && SANITIZE_ARRAY (this, Type::get_size (), len);
+    return SANITIZE_SELF()
+	&& SANITIZE_ARRAY (this, Type::get_size (), len);
   }
 
   public:
@@ -622,7 +623,8 @@ struct HeadlessArrayOf
   { return len.get_size () + (len ? len - 1 : 0) * Type::get_size (); }
 
   inline bool sanitize_shallow (hb_sanitize_context_t *context) {
-    return SANITIZE_SELF() && SANITIZE_ARRAY (this, Type::get_size (), len);
+    return SANITIZE_SELF()
+	&& SANITIZE_ARRAY (this, Type::get_size (), len);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index d9b2da3..22a5432 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -166,7 +166,8 @@ struct LangSys
 
   inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    return SANITIZE_SELF () && SANITIZE (featureIndex);
+    return SANITIZE_SELF ()
+	&& SANITIZE (featureIndex);
   }
 
   Offset	lookupOrder;	/* = Null (reserved for an offset to a
@@ -234,7 +235,8 @@ struct Feature
 
   inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    return SANITIZE_SELF () && SANITIZE (lookupIndex);
+    return SANITIZE_SELF ()
+	&& SANITIZE (lookupIndex);
   }
 
   /* LONGTERMTODO: implement get_feature_parameters() */
@@ -285,7 +287,8 @@ struct Lookup
   inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     /* Real sanitize of the subtables is done by GSUB/GPOS/... */
-    if (!(SANITIZE_SELF () && likely (subTable.sanitize (context)))) return false;
+    if (!(SANITIZE_SELF ()
+       && likely (subTable.sanitize (context)))) return false;
     if (unlikely (lookupFlag & LookupFlag::UseMarkFilteringSet))
     {
       USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
@@ -454,7 +457,8 @@ struct ClassDefFormat1
 
   inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    return SANITIZE_SELF () && SANITIZE (classValue);
+    return SANITIZE_SELF ()
+	&& SANITIZE (classValue);
   }
 
   USHORT	classFormat;		/* Format identifier--format = 1 */
@@ -594,7 +598,8 @@ struct Device
 
   inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    return SANITIZE_SELF() && SANITIZE_MEM (this, this->get_size ());
+    return SANITIZE_SELF()
+	&& SANITIZE_MEM (this, this->get_size ());
   }
 
   private:
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 613fd0b..145fc04 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -159,9 +159,8 @@ struct ValueFormat : USHORT
 
   inline bool sanitize_value (hb_sanitize_context_t *context, void *base, const Value *values) {
     TRACE_SANITIZE ();
-
-    return SANITIZE_MEM (values, get_size ()) &&
-	   (!has_device () || sanitize_value_devices (context, base, values));
+    return SANITIZE_MEM (values, get_size ())
+	&& (!has_device () || sanitize_value_devices (context, base, values));
   }
 
   inline bool sanitize_values (hb_sanitize_context_t *context, void *base, const Value *values, unsigned int count) {
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 7290e98..9083db5 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -428,7 +428,8 @@ struct Ligature
   public:
   inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    return SANITIZE (ligGlyph) && SANITIZE (component);
+    return SANITIZE (ligGlyph)
+        && SANITIZE (component);
   }
 
   private:
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 24889b9..6ed1bf7 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -287,8 +287,9 @@ struct Rule
   public:
   inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    if (!(SANITIZE (inputCount) && SANITIZE (lookupCount))) return false;
-    return SANITIZE_MEM (input,
+    return SANITIZE (inputCount)
+	&& SANITIZE (lookupCount)
+	&& SANITIZE_MEM (input,
 			 input[0].get_size () * inputCount +
 			 lookupRecordX[0].get_size () * lookupCount);
   }
@@ -444,10 +445,10 @@ struct ContextFormat3
     TRACE_SANITIZE ();
     if (!SANITIZE_SELF ()) return false;
     unsigned int count = glyphCount;
-    if (!SANITIZE_ARRAY (coverage, OffsetTo<Coverage>::get_size (), glyphCount)) return false;
+    if (!SANITIZE_ARRAY (coverage, OffsetTo<Coverage>::get_size (), count)) return false;
     for (unsigned int i = 0; i < count; i++)
       if (!SANITIZE_WITH_BASE (this, coverage[i])) return false;
-    LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, OffsetTo<Coverage>::get_size () * glyphCount);
+    LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, OffsetTo<Coverage>::get_size () * count);
     return SANITIZE_ARRAY (lookupRecord, LookupRecord::get_size (), lookupCount);
   }
 
commit 705e215268aa95c2bc6af8af9b48b72b690ec1f7
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 01:40:25 2010 -0400

    Minor

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index c66d707..78a1c3b 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -230,11 +230,11 @@ struct hb_sanitize_context_t
     return this->writable;
   }
 
+  unsigned int debug_depth;
   const char *start, *end;
   bool writable;
   unsigned int edit_count;
   hb_blob_t *blob;
-  unsigned int debug_depth;
 };
 
 
@@ -254,7 +254,7 @@ template <typename Type>
 struct Sanitizer
 {
   static hb_blob_t *sanitize (hb_blob_t *blob) {
-    hb_sanitize_context_t context[1] = {{}};
+    hb_sanitize_context_t context[1] = {{0}};
     bool sane;
 
     /* TODO is_sane() stuff */
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index b1fb3cb..613fd0b 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -1490,7 +1490,7 @@ struct PosLookup : Lookup
 			  unsigned int    nesting_level_left) const
   {
     unsigned int lookup_type = get_type ();
-    hb_apply_context_t context[1] = {{}};
+    hb_apply_context_t context[1] = {{0}};
 
     context->layout = layout;
     context->buffer = buffer;
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 5cea951..7290e98 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -775,7 +775,7 @@ struct SubstLookup : Lookup
 			  unsigned int nesting_level_left) const
   {
     unsigned int lookup_type = get_type ();
-    hb_apply_context_t context[1] = {{}};
+    hb_apply_context_t context[1] = {{0}};
 
     context->layout = layout;
     context->buffer = buffer;
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index b4c9e05..24889b9 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -42,13 +42,13 @@
 
 struct hb_apply_context_t
 {
+  unsigned int debug_depth;
   hb_ot_layout_context_t *layout;
   hb_buffer_t *buffer;
   unsigned int context_length;
   unsigned int nesting_level_left;
   unsigned int lookup_flag;
   unsigned int property; /* propety of first glyph (TODO remove) */
-  unsigned int debug_depth;
 };
 
 
commit b18eafd0f62f854d15276c78f99843aecd47acad
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 01:39:26 2010 -0400

    Minor

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index bdffa95..c66d707 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -254,7 +254,7 @@ template <typename Type>
 struct Sanitizer
 {
   static hb_blob_t *sanitize (hb_blob_t *blob) {
-    hb_sanitize_context_t context[1];
+    hb_sanitize_context_t context[1] = {{}};
     bool sane;
 
     /* TODO is_sane() stuff */
commit 4169710911450e0f9bc045fe279bfc8ba9e8457c
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 01:37:58 2010 -0400

    Simplify chaining

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 6e3b6e5..b4c9e05 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -258,20 +258,15 @@ static inline bool context_lookup (hb_apply_context_t *context,
 				   const LookupRecord lookupRecord[],
 				   ContextLookupContext &lookup_context)
 {
-  unsigned int new_context_length;
-  if (!match_input (context,
-		    inputCount, input,
-		    lookup_context.funcs.match, lookup_context.match_data,
-		    &new_context_length)) return false;
-  unsigned int old_context_length;
-  old_context_length = context->context_length;
-  context->context_length = new_context_length;
-  bool ret = apply_lookup (context,
-			   inputCount,
-			   lookupCount, lookupRecord,
-			   lookup_context.funcs.apply);
-  context->context_length = old_context_length;
-  return ret;
+  hb_apply_context_t new_context = *context;
+  return match_input (context,
+		      inputCount, input,
+		      lookup_context.funcs.match, lookup_context.match_data,
+		      &new_context.context_length)
+      && apply_lookup (&new_context,
+		       inputCount,
+		       lookupCount, lookupRecord,
+		       lookup_context.funcs.apply);
 }
 
 struct Rule
@@ -529,28 +524,22 @@ static inline bool chain_context_lookup (hb_apply_context_t *context,
 		inputCount + lookaheadCount > context->context_length))
     return false;
 
-  unsigned int offset;
-  if (!(match_backtrack (context,
-			 backtrackCount, backtrack,
-			 lookup_context.funcs.match, lookup_context.match_data[0]) &&
-	match_input (context,
-		     inputCount, input,
-		     lookup_context.funcs.match, lookup_context.match_data[1],
-		     &offset) &&
-	match_lookahead (context,
-			 lookaheadCount, lookahead,
-			 lookup_context.funcs.match, lookup_context.match_data[2],
-			 offset))) return false;
-
-  unsigned int old_context_length;
-  old_context_length = context->context_length;
-  context->context_length = offset;
-  bool ret = apply_lookup (context,
-			   inputCount,
-			   lookupCount, lookupRecord,
-			   lookup_context.funcs.apply);
-  context->context_length = old_context_length;
-  return ret;
+  hb_apply_context_t new_context = *context;
+  return match_backtrack (context,
+			  backtrackCount, backtrack,
+			  lookup_context.funcs.match, lookup_context.match_data[0])
+      && match_input (context,
+		      inputCount, input,
+		      lookup_context.funcs.match, lookup_context.match_data[1],
+		      &new_context.context_length)
+      && match_lookahead (context,
+			  lookaheadCount, lookahead,
+			  lookup_context.funcs.match, lookup_context.match_data[2],
+			  new_context.context_length)
+      && apply_lookup (&new_context,
+		       inputCount,
+		       lookupCount, lookupRecord,
+		       lookup_context.funcs.apply);
 }
 
 struct ChainRule
commit 1911b9d21b2b7b6b8219ce6c888540e3a60aa9c3
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 01:32:04 2010 -0400

    Remove APPLY_ARG_DEF and APPLY_ARG

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 200f353..b1fb3cb 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -379,7 +379,7 @@ ASSERT_SIZE (MarkRecord, 4);
 
 struct MarkArray
 {
-  inline bool apply (APPLY_ARG_DEF,
+  inline bool apply (hb_apply_context_t *context,
 		     unsigned int mark_index, unsigned int glyph_index,
 		     const AnchorMatrix &anchors, unsigned int class_count,
 		     unsigned int glyph_pos) const
@@ -426,7 +426,7 @@ struct SinglePosFormat1
   friend struct SinglePos;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
@@ -464,7 +464,7 @@ struct SinglePosFormat2
   friend struct SinglePos;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
@@ -507,12 +507,12 @@ struct SinglePos
   friend struct PosLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
-    case 2: return u.format2->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
+    case 2: return u.format2->apply (context);
     default:return false;
     }
   }
@@ -574,7 +574,7 @@ struct PairPosFormat1
   friend struct PairPos;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context->context_length);
@@ -667,7 +667,7 @@ struct PairPosFormat2
   friend struct PairPos;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context->context_length);
@@ -757,12 +757,12 @@ struct PairPos
   friend struct PosLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
-    case 2: return u.format2->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
+    case 2: return u.format2->apply (context);
     default:return false;
     }
   }
@@ -812,7 +812,7 @@ struct CursivePosFormat1
   friend struct CursivePos;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     /* Now comes the messiest part of the whole OpenType
@@ -1009,11 +1009,11 @@ struct CursivePos
   friend struct PosLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
     default:return false;
     }
   }
@@ -1045,7 +1045,7 @@ struct MarkBasePosFormat1
   friend struct MarkBasePos;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     unsigned int mark_index = (this+markCoverage) (IN_CURGLYPH ());
@@ -1072,7 +1072,7 @@ struct MarkBasePosFormat1
     if (base_index == NOT_COVERED)
       return false;
 
-    return (this+markArray).apply (APPLY_ARG, mark_index, base_index, this+baseArray, classCount, j);
+    return (this+markArray).apply (context, mark_index, base_index, this+baseArray, classCount, j);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -1107,11 +1107,11 @@ struct MarkBasePos
   friend struct PosLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
     default:return false;
     }
   }
@@ -1148,7 +1148,7 @@ struct MarkLigPosFormat1
   friend struct MarkLigPos;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     unsigned int mark_index = (this+markCoverage) (IN_CURGLYPH ());
@@ -1196,7 +1196,7 @@ struct MarkLigPosFormat1
     else
       comp_index = comp_count - 1;
 
-    return (this+markArray).apply (APPLY_ARG, mark_index, comp_index, lig_attach, classCount, j);
+    return (this+markArray).apply (context, mark_index, comp_index, lig_attach, classCount, j);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -1232,11 +1232,11 @@ struct MarkLigPos
   friend struct PosLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
     default:return false;
     }
   }
@@ -1268,7 +1268,7 @@ struct MarkMarkPosFormat1
   friend struct MarkMarkPos;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     unsigned int mark1_index = (this+mark1Coverage) (IN_CURGLYPH ());
@@ -1299,7 +1299,7 @@ struct MarkMarkPosFormat1
     if (mark2_index == NOT_COVERED)
       return false;
 
-    return (this+mark1Array).apply (APPLY_ARG, mark1_index, mark2_index, this+mark2Array, classCount, j);
+    return (this+mark1Array).apply (context, mark1_index, mark2_index, this+mark2Array, classCount, j);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -1336,11 +1336,11 @@ struct MarkMarkPos
   friend struct PosLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
     default:return false;
     }
   }
@@ -1362,17 +1362,17 @@ struct MarkMarkPos
 };
 
 
-static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index);
+static inline bool position_lookup (hb_apply_context_t *context, unsigned int lookup_index);
 
 struct ContextPos : Context
 {
   friend struct PosLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
-    return Context::apply (APPLY_ARG, position_lookup);
+    return Context::apply (context, position_lookup);
   }
 };
 
@@ -1381,10 +1381,10 @@ struct ChainContextPos : ChainContext
   friend struct PosLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
-    return ChainContext::apply (APPLY_ARG, position_lookup);
+    return ChainContext::apply (context, position_lookup);
   }
 };
 
@@ -1401,7 +1401,7 @@ struct ExtensionPos : Extension
     return StructAtOffset<PosLookupSubTable> (*this, offset);
   }
 
-  inline bool apply (APPLY_ARG_DEF) const;
+  inline bool apply (hb_apply_context_t *context) const;
 
   inline bool sanitize (hb_sanitize_context_t *context);
 };
@@ -1429,19 +1429,19 @@ struct PosLookupSubTable
     Extension		= 9
   };
 
-  inline bool apply (APPLY_ARG_DEF, unsigned int lookup_type) const
+  inline bool apply (hb_apply_context_t *context, unsigned int lookup_type) const
   {
     TRACE_APPLY ();
     switch (lookup_type) {
-    case Single:		return u.single->apply (APPLY_ARG);
-    case Pair:			return u.pair->apply (APPLY_ARG);
-    case Cursive:		return u.cursive->apply (APPLY_ARG);
-    case MarkBase:		return u.markBase->apply (APPLY_ARG);
-    case MarkLig:		return u.markLig->apply (APPLY_ARG);
-    case MarkMark:		return u.markMark->apply (APPLY_ARG);
-    case Context:		return u.context->apply (APPLY_ARG);
-    case ChainContext:		return u.chainContext->apply (APPLY_ARG);
-    case Extension:		return u.extension->apply (APPLY_ARG);
+    case Single:		return u.single->apply (context);
+    case Pair:			return u.pair->apply (context);
+    case Cursive:		return u.cursive->apply (context);
+    case MarkBase:		return u.markBase->apply (context);
+    case MarkLig:		return u.markLig->apply (context);
+    case MarkMark:		return u.markMark->apply (context);
+    case Context:		return u.context->apply (context);
+    case ChainContext:		return u.chainContext->apply (context);
+    case Extension:		return u.extension->apply (context);
     default:return false;
     }
   }
@@ -1502,7 +1502,7 @@ struct PosLookup : Lookup
       return false;
 
     for (unsigned int i = 0; i < get_subtable_count (); i++)
-      if (get_subtable (i).apply (APPLY_ARG, lookup_type))
+      if (get_subtable (i).apply (context, lookup_type))
 	return true;
 
     return false;
@@ -1585,10 +1585,10 @@ ASSERT_SIZE (GPOS, 10);
 
 /* Out-of-class implementation for methods recursing */
 
-inline bool ExtensionPos::apply (APPLY_ARG_DEF) const
+inline bool ExtensionPos::apply (hb_apply_context_t *context) const
 {
   TRACE_APPLY ();
-  return get_subtable ().apply (APPLY_ARG, get_type ());
+  return get_subtable ().apply (context, get_type ());
 }
 
 inline bool ExtensionPos::sanitize (hb_sanitize_context_t *context)
@@ -1600,7 +1600,7 @@ inline bool ExtensionPos::sanitize (hb_sanitize_context_t *context)
   return SANITIZE (StructAtOffset<PosLookupSubTable> (*this, offset));
 }
 
-static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
+static inline bool position_lookup (hb_apply_context_t *context, unsigned int lookup_index)
 {
   const GPOS &gpos = *(context->layout->face->ot_layout.gpos);
   const PosLookup &l = gpos.get_lookup (lookup_index);
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 19297c4..5cea951 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -40,7 +40,7 @@ struct SingleSubstFormat1
 
   private:
 
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     hb_codepoint_t glyph_id = IN_CURGLYPH ();
@@ -80,7 +80,7 @@ struct SingleSubstFormat2
 
   private:
 
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     hb_codepoint_t glyph_id = IN_CURGLYPH ();
@@ -124,12 +124,12 @@ struct SingleSubst
 
   private:
 
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
-    case 2: return u.format2->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
+    case 2: return u.format2->apply (context);
     default:return false;
     }
   }
@@ -158,7 +158,7 @@ struct Sequence
   friend struct MultipleSubstFormat1;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     if (unlikely (!substitute.len))
@@ -201,7 +201,7 @@ struct MultipleSubstFormat1
 
   private:
 
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
 
@@ -209,7 +209,7 @@ struct MultipleSubstFormat1
     if (likely (index == NOT_COVERED))
       return false;
 
-    return (this+sequence[index]).apply (APPLY_ARG);
+    return (this+sequence[index]).apply (context);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -235,11 +235,11 @@ struct MultipleSubst
 
   private:
 
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
     default:return false;
     }
   }
@@ -271,7 +271,7 @@ struct AlternateSubstFormat1
 
   private:
 
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     hb_codepoint_t glyph_id = IN_CURGLYPH ();
@@ -331,11 +331,11 @@ struct AlternateSubst
 
   private:
 
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
     default:return false;
     }
   }
@@ -362,7 +362,7 @@ struct Ligature
   friend struct LigatureSet;
 
   private:
-  inline bool apply (APPLY_ARG_DEF, bool is_mark) const
+  inline bool apply (hb_apply_context_t *context, bool is_mark) const
   {
     TRACE_APPLY ();
     unsigned int i, j;
@@ -445,14 +445,14 @@ struct LigatureSet
   friend struct LigatureSubstFormat1;
 
   private:
-  inline bool apply (APPLY_ARG_DEF, bool is_mark) const
+  inline bool apply (hb_apply_context_t *context, bool is_mark) const
   {
     TRACE_APPLY ();
     unsigned int num_ligs = ligature.len;
     for (unsigned int i = 0; i < num_ligs; i++)
     {
       const Ligature &lig = this+ligature[i];
-      if (lig.apply (APPLY_ARG, is_mark))
+      if (lig.apply (context, is_mark))
         return true;
     }
 
@@ -477,7 +477,7 @@ struct LigatureSubstFormat1
   friend struct LigatureSubst;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     hb_codepoint_t glyph_id = IN_CURGLYPH ();
@@ -489,7 +489,7 @@ struct LigatureSubstFormat1
       return false;
 
     const LigatureSet &lig_set = this+ligatureSet[index];
-    return lig_set.apply (APPLY_ARG, first_is_mark);
+    return lig_set.apply (context, first_is_mark);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -514,11 +514,11 @@ struct LigatureSubst
   friend struct SubstLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
     default:return false;
     }
   }
@@ -541,17 +541,17 @@ struct LigatureSubst
 
 
 
-static inline bool substitute_lookup (APPLY_ARG_DEF, unsigned int lookup_index);
+static inline bool substitute_lookup (hb_apply_context_t *context, unsigned int lookup_index);
 
 struct ContextSubst : Context
 {
   friend struct SubstLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
-    return Context::apply (APPLY_ARG, substitute_lookup);
+    return Context::apply (context, substitute_lookup);
   }
 };
 
@@ -560,10 +560,10 @@ struct ChainContextSubst : ChainContext
   friend struct SubstLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
-    return ChainContext::apply (APPLY_ARG, substitute_lookup);
+    return ChainContext::apply (context, substitute_lookup);
   }
 };
 
@@ -581,7 +581,7 @@ struct ExtensionSubst : Extension
     return StructAtOffset<SubstLookupSubTable> (*this, offset);
   }
 
-  inline bool apply (APPLY_ARG_DEF) const;
+  inline bool apply (hb_apply_context_t *context) const;
 
   inline bool sanitize (hb_sanitize_context_t *context);
 
@@ -594,7 +594,7 @@ struct ReverseChainSingleSubstFormat1
   friend struct ReverseChainSingleSubst;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     if (unlikely (context->context_length != NO_CONTEXT))
@@ -607,10 +607,10 @@ struct ReverseChainSingleSubstFormat1
     const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
     const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
 
-    if (match_backtrack (APPLY_ARG,
+    if (match_backtrack (context,
 			 backtrack.len, (USHORT *) backtrack.array(),
 			 match_coverage, CharP(this)) &&
-        match_lookahead (APPLY_ARG,
+        match_lookahead (context,
 			 lookahead.len, (USHORT *) lookahead.array(),
 			 match_coverage, CharP(this),
 			 1))
@@ -659,11 +659,11 @@ struct ReverseChainSingleSubst
   friend struct SubstLookupSubTable;
 
   private:
-  inline bool apply (APPLY_ARG_DEF) const
+  inline bool apply (hb_apply_context_t *context) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG);
+    case 1: return u.format1->apply (context);
     default:return false;
     }
   }
@@ -705,18 +705,18 @@ struct SubstLookupSubTable
     ReverseChainSingle	= 8
   };
 
-  inline bool apply (APPLY_ARG_DEF, unsigned int lookup_type) const
+  inline bool apply (hb_apply_context_t *context, unsigned int lookup_type) const
   {
     TRACE_APPLY ();
     switch (lookup_type) {
-    case Single:		return u.single->apply (APPLY_ARG);
-    case Multiple:		return u.multiple->apply (APPLY_ARG);
-    case Alternate:		return u.alternate->apply (APPLY_ARG);
-    case Ligature:		return u.ligature->apply (APPLY_ARG);
-    case Context:		return u.context->apply (APPLY_ARG);
-    case ChainContext:		return u.chainContext->apply (APPLY_ARG);
-    case Extension:		return u.extension->apply (APPLY_ARG);
-    case ReverseChainSingle:	return u.reverseChainContextSingle->apply (APPLY_ARG);
+    case Single:		return u.single->apply (context);
+    case Multiple:		return u.multiple->apply (context);
+    case Alternate:		return u.alternate->apply (context);
+    case Ligature:		return u.ligature->apply (context);
+    case Context:		return u.context->apply (context);
+    case ChainContext:		return u.chainContext->apply (context);
+    case Extension:		return u.extension->apply (context);
+    case ReverseChainSingle:	return u.reverseChainContextSingle->apply (context);
     default:return false;
     }
   }
@@ -802,7 +802,7 @@ struct SubstLookup : Lookup
 
     unsigned int count = get_subtable_count ();
     for (unsigned int i = 0; i < count; i++)
-      if (get_subtable (i).apply (APPLY_ARG, lookup_type))
+      if (get_subtable (i).apply (context, lookup_type))
 	return true;
 
     return false;
@@ -896,10 +896,10 @@ ASSERT_SIZE (GSUB, 10);
 
 /* Out-of-class implementation for methods recursing */
 
-inline bool ExtensionSubst::apply (APPLY_ARG_DEF) const
+inline bool ExtensionSubst::apply (hb_apply_context_t *context) const
 {
   TRACE_APPLY ();
-  return get_subtable ().apply (APPLY_ARG, get_type ());
+  return get_subtable ().apply (context, get_type ());
 }
 
 inline bool ExtensionSubst::sanitize (hb_sanitize_context_t *context)
@@ -919,7 +919,7 @@ inline bool ExtensionSubst::is_reverse (void) const
   return SubstLookup::lookup_type_is_reverse (type);
 }
 
-static inline bool substitute_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
+static inline bool substitute_lookup (hb_apply_context_t *context, unsigned int lookup_index)
 {
   const GSUB &gsub = *(context->layout->face->ot_layout.gsub);
   const SubstLookup &l = gsub.get_lookup (lookup_index);
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index ad4e404..6e3b6e5 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -40,11 +40,6 @@
 	trace.log ("APPLY", HB_FUNC, this);
 
 
-#define APPLY_ARG_DEF \
-	hb_apply_context_t *context
-#define APPLY_ARG \
-	context
-
 struct hb_apply_context_t
 {
   hb_ot_layout_context_t *layout;
@@ -64,7 +59,7 @@ struct hb_apply_context_t
 
 
 typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const char *data);
-typedef bool (*apply_lookup_func_t) (APPLY_ARG_DEF, unsigned int lookup_index);
+typedef bool (*apply_lookup_func_t) (hb_apply_context_t *context, unsigned int lookup_index);
 
 struct ContextFuncs
 {
@@ -91,7 +86,7 @@ static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value,
 }
 
 
-static inline bool match_input (APPLY_ARG_DEF,
+static inline bool match_input (hb_apply_context_t *context,
 				unsigned int count, /* Including the first glyph (not matched) */
 				const USHORT input[], /* Array of input values--start with second glyph */
 				match_func_t match_func,
@@ -121,7 +116,7 @@ static inline bool match_input (APPLY_ARG_DEF,
   return true;
 }
 
-static inline bool match_backtrack (APPLY_ARG_DEF,
+static inline bool match_backtrack (hb_apply_context_t *context,
 				    unsigned int count,
 				    const USHORT backtrack[],
 				    match_func_t match_func,
@@ -146,7 +141,7 @@ static inline bool match_backtrack (APPLY_ARG_DEF,
   return true;
 }
 
-static inline bool match_lookahead (APPLY_ARG_DEF,
+static inline bool match_lookahead (hb_apply_context_t *context,
 				    unsigned int count,
 				    const USHORT lookahead[],
 				    match_func_t match_func,
@@ -191,7 +186,7 @@ struct LookupRecord
 };
 ASSERT_SIZE (LookupRecord, 4);
 
-static inline bool apply_lookup (APPLY_ARG_DEF,
+static inline bool apply_lookup (hb_apply_context_t *context,
 				 unsigned int count, /* Including the first glyph */
 				 unsigned int lookupCount,
 				 const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
@@ -223,7 +218,7 @@ static inline bool apply_lookup (APPLY_ARG_DEF,
       unsigned int old_pos = context->buffer->in_pos;
 
       /* Apply a lookup */
-      bool done = apply_func (APPLY_ARG, lookupRecord->lookupListIndex);
+      bool done = apply_func (context, lookupRecord->lookupListIndex);
 
       lookupRecord++;
       lookupCount--;
@@ -256,7 +251,7 @@ struct ContextLookupContext
   const char *match_data;
 };
 
-static inline bool context_lookup (APPLY_ARG_DEF,
+static inline bool context_lookup (hb_apply_context_t *context,
 				   unsigned int inputCount, /* Including the first glyph (not matched) */
 				   const USHORT input[], /* Array of input values--start with second glyph */
 				   unsigned int lookupCount,
@@ -264,14 +259,14 @@ static inline bool context_lookup (APPLY_ARG_DEF,
 				   ContextLookupContext &lookup_context)
 {
   unsigned int new_context_length;
-  if (!match_input (APPLY_ARG,
+  if (!match_input (context,
 		    inputCount, input,
 		    lookup_context.funcs.match, lookup_context.match_data,
 		    &new_context_length)) return false;
   unsigned int old_context_length;
   old_context_length = context->context_length;
   context->context_length = new_context_length;
-  bool ret = apply_lookup (APPLY_ARG,
+  bool ret = apply_lookup (context,
 			   inputCount,
 			   lookupCount, lookupRecord,
 			   lookup_context.funcs.apply);
@@ -284,11 +279,11 @@ struct Rule
   friend struct RuleSet;
 
   private:
-  inline bool apply (APPLY_ARG_DEF, ContextLookupContext &lookup_context) const
+  inline bool apply (hb_apply_context_t *context, ContextLookupContext &lookup_context) const
   {
     TRACE_APPLY ();
     const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].get_size () * (inputCount ? inputCount - 1 : 0));
-    return context_lookup (APPLY_ARG,
+    return context_lookup (context,
 			   inputCount, input,
 			   lookupCount, lookupRecord,
 			   lookup_context);
@@ -317,13 +312,13 @@ ASSERT_SIZE_VAR2 (Rule, 4, USHORT, LookupRecord);
 
 struct RuleSet
 {
-  inline bool apply (APPLY_ARG_DEF, ContextLookupContext &lookup_context) const
+  inline bool apply (hb_apply_context_t *context, ContextLookupContext &lookup_context) const
   {
     TRACE_APPLY ();
     unsigned int num_rules = rule.len;
     for (unsigned int i = 0; i < num_rules; i++)
     {
-      if ((this+rule[i]).apply (APPLY_ARG, lookup_context))
+      if ((this+rule[i]).apply (context, lookup_context))
         return true;
     }
 
@@ -347,7 +342,7 @@ struct ContextFormat1
   friend struct Context;
 
   private:
-  inline bool apply (APPLY_ARG_DEF, apply_lookup_func_t apply_func) const
+  inline bool apply (hb_apply_context_t *context, apply_lookup_func_t apply_func) const
   {
     TRACE_APPLY ();
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
@@ -359,7 +354,7 @@ struct ContextFormat1
       {match_glyph, apply_func},
       NULL
     };
-    return rule_set.apply (APPLY_ARG, lookup_context);
+    return rule_set.apply (context, lookup_context);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -385,7 +380,7 @@ struct ContextFormat2
   friend struct Context;
 
   private:
-  inline bool apply (APPLY_ARG_DEF, apply_lookup_func_t apply_func) const
+  inline bool apply (hb_apply_context_t *context, apply_lookup_func_t apply_func) const
   {
     TRACE_APPLY ();
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
@@ -402,7 +397,7 @@ struct ContextFormat2
      {match_class, apply_func},
       CharP(&class_def)
     };
-    return rule_set.apply (APPLY_ARG, lookup_context);
+    return rule_set.apply (context, lookup_context);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -432,7 +427,7 @@ struct ContextFormat3
   friend struct Context;
 
   private:
-  inline bool apply (APPLY_ARG_DEF, apply_lookup_func_t apply_func) const
+  inline bool apply (hb_apply_context_t *context, apply_lookup_func_t apply_func) const
   {
     TRACE_APPLY ();
     unsigned int index = (this+coverage[0]) (IN_CURGLYPH ());
@@ -444,7 +439,7 @@ struct ContextFormat3
       {match_coverage, apply_func},
        CharP(this)
     };
-    return context_lookup (APPLY_ARG,
+    return context_lookup (context,
 			   glyphCount, (const USHORT *) (coverage + 1),
 			   lookupCount, lookupRecord,
 			   lookup_context);
@@ -477,13 +472,13 @@ ASSERT_SIZE_VAR2 (ContextFormat3, 6, OffsetTo<Coverage>, LookupRecord);
 struct Context
 {
   protected:
-  inline bool apply (APPLY_ARG_DEF, apply_lookup_func_t apply_func) const
+  inline bool apply (hb_apply_context_t *context, apply_lookup_func_t apply_func) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG, apply_func);
-    case 2: return u.format2->apply (APPLY_ARG, apply_func);
-    case 3: return u.format3->apply (APPLY_ARG, apply_func);
+    case 1: return u.format1->apply (context, apply_func);
+    case 2: return u.format2->apply (context, apply_func);
+    case 3: return u.format3->apply (context, apply_func);
     default:return false;
     }
   }
@@ -517,7 +512,7 @@ struct ChainContextLookupContext
   const char *match_data[3];
 };
 
-static inline bool chain_context_lookup (APPLY_ARG_DEF,
+static inline bool chain_context_lookup (hb_apply_context_t *context,
 					 unsigned int backtrackCount,
 					 const USHORT backtrack[],
 					 unsigned int inputCount, /* Including the first glyph (not matched) */
@@ -535,14 +530,14 @@ static inline bool chain_context_lookup (APPLY_ARG_DEF,
     return false;
 
   unsigned int offset;
-  if (!(match_backtrack (APPLY_ARG,
+  if (!(match_backtrack (context,
 			 backtrackCount, backtrack,
 			 lookup_context.funcs.match, lookup_context.match_data[0]) &&
-	match_input (APPLY_ARG,
+	match_input (context,
 		     inputCount, input,
 		     lookup_context.funcs.match, lookup_context.match_data[1],
 		     &offset) &&
-	match_lookahead (APPLY_ARG,
+	match_lookahead (context,
 			 lookaheadCount, lookahead,
 			 lookup_context.funcs.match, lookup_context.match_data[2],
 			 offset))) return false;
@@ -550,7 +545,7 @@ static inline bool chain_context_lookup (APPLY_ARG_DEF,
   unsigned int old_context_length;
   old_context_length = context->context_length;
   context->context_length = offset;
-  bool ret = apply_lookup (APPLY_ARG,
+  bool ret = apply_lookup (context,
 			   inputCount,
 			   lookupCount, lookupRecord,
 			   lookup_context.funcs.apply);
@@ -563,13 +558,13 @@ struct ChainRule
   friend struct ChainRuleSet;
 
   private:
-  inline bool apply (APPLY_ARG_DEF, ChainContextLookupContext &lookup_context) const
+  inline bool apply (hb_apply_context_t *context, ChainContextLookupContext &lookup_context) const
   {
     TRACE_APPLY ();
     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 chain_context_lookup (APPLY_ARG,
+    return chain_context_lookup (context,
 				 backtrack.len, backtrack.array(),
 				 input.len, input.array(),
 				 lookahead.len, lookahead.array(),
@@ -609,13 +604,13 @@ ASSERT_SIZE (ChainRule, 8);
 
 struct ChainRuleSet
 {
-  inline bool apply (APPLY_ARG_DEF, ChainContextLookupContext &lookup_context) const
+  inline bool apply (hb_apply_context_t *context, ChainContextLookupContext &lookup_context) const
   {
     TRACE_APPLY ();
     unsigned int num_rules = rule.len;
     for (unsigned int i = 0; i < num_rules; i++)
     {
-      if ((this+rule[i]).apply (APPLY_ARG, lookup_context))
+      if ((this+rule[i]).apply (context, lookup_context))
         return true;
     }
 
@@ -639,7 +634,7 @@ struct ChainContextFormat1
   friend struct ChainContext;
 
   private:
-  inline bool apply (APPLY_ARG_DEF, apply_lookup_func_t apply_func) const
+  inline bool apply (hb_apply_context_t *context, apply_lookup_func_t apply_func) const
   {
     TRACE_APPLY ();
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
@@ -651,7 +646,7 @@ struct ChainContextFormat1
       {match_glyph, apply_func},
       {NULL, NULL, NULL}
     };
-    return rule_set.apply (APPLY_ARG, lookup_context);
+    return rule_set.apply (context, lookup_context);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -676,7 +671,7 @@ struct ChainContextFormat2
   friend struct ChainContext;
 
   private:
-  inline bool apply (APPLY_ARG_DEF, apply_lookup_func_t apply_func) const
+  inline bool apply (hb_apply_context_t *context, apply_lookup_func_t apply_func) const
   {
     TRACE_APPLY ();
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
@@ -698,7 +693,7 @@ struct ChainContextFormat2
       CharP(&input_class_def),
       CharP(&lookahead_class_def)}
     };
-    return rule_set.apply (APPLY_ARG, lookup_context);
+    return rule_set.apply (context, lookup_context);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -739,7 +734,7 @@ struct ChainContextFormat3
 
   private:
 
-  inline bool apply (APPLY_ARG_DEF, apply_lookup_func_t apply_func) const
+  inline bool apply (hb_apply_context_t *context, apply_lookup_func_t apply_func) const
   {
     TRACE_APPLY ();
     const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
@@ -754,7 +749,7 @@ struct ChainContextFormat3
       {match_coverage, apply_func},
       {CharP(this), CharP(this), CharP(this)}
     };
-    return chain_context_lookup (APPLY_ARG,
+    return chain_context_lookup (context,
 				 backtrack.len, (const USHORT *) backtrack.array(),
 				 input.len, (const USHORT *) input.array() + 1,
 				 lookahead.len, (const USHORT *) lookahead.array(),
@@ -797,13 +792,13 @@ ASSERT_SIZE (ChainContextFormat3, 10);
 struct ChainContext
 {
   protected:
-  inline bool apply (APPLY_ARG_DEF, apply_lookup_func_t apply_func) const
+  inline bool apply (hb_apply_context_t *context, apply_lookup_func_t apply_func) const
   {
     TRACE_APPLY ();
     switch (u.format) {
-    case 1: return u.format1->apply (APPLY_ARG, apply_func);
-    case 2: return u.format2->apply (APPLY_ARG, apply_func);
-    case 3: return u.format3->apply (APPLY_ARG, apply_func);
+    case 1: return u.format1->apply (context, apply_func);
+    case 2: return u.format2->apply (context, apply_func);
+    case 3: return u.format3->apply (context, apply_func);
     default:return false;
     }
   }
commit 6c42cddfe53a1c664081862bb9a3e1c38d05a823
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 01:30:48 2010 -0400

    Port apply to use hb_trace_t

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index cfd2411..200f353 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -1487,11 +1487,10 @@ struct PosLookup : Lookup
   inline bool apply_once (hb_ot_layout_context_t *layout,
 			  hb_buffer_t    *buffer,
 			  unsigned int    context_length,
-			  unsigned int    nesting_level_left,
-			  unsigned int    apply_depth) const
+			  unsigned int    nesting_level_left) const
   {
     unsigned int lookup_type = get_type ();
-    hb_apply_context_t context[1];
+    hb_apply_context_t context[1] = {{}};
 
     context->layout = layout;
     context->buffer = buffer;
@@ -1528,7 +1527,7 @@ struct PosLookup : Lookup
       bool done;
       if (~IN_MASK (buffer->in_pos) & mask)
       {
-	  done = apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL, 0);
+	  done = apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL);
 	  ret |= done;
       }
       else
@@ -1612,7 +1611,7 @@ static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
   if (unlikely (context->context_length < 1))
     return false;
 
-  return l.apply_once (context->layout, context->buffer, context->context_length, context->nesting_level_left - 1, apply_depth + 1);
+  return l.apply_once (context->layout, context->buffer, context->context_length, context->nesting_level_left - 1);
 }
 
 
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 87dfcd2..19297c4 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -772,11 +772,10 @@ struct SubstLookup : Lookup
   inline bool apply_once (hb_ot_layout_context_t *layout,
 			  hb_buffer_t *buffer,
 			  unsigned int context_length,
-			  unsigned int nesting_level_left,
-			  unsigned int apply_depth) const
+			  unsigned int nesting_level_left) const
   {
     unsigned int lookup_type = get_type ();
-    hb_apply_context_t context[1];
+    hb_apply_context_t context[1] = {{}};
 
     context->layout = layout;
     context->buffer = buffer;
@@ -828,7 +827,7 @@ struct SubstLookup : Lookup
 	while (buffer->in_pos < buffer->in_length)
 	{
 	  if ((~IN_MASK (buffer->in_pos) & mask) &&
-	      apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL, 0))
+	      apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL))
 	    ret = true;
 	  else
 	    _hb_buffer_next_glyph (buffer);
@@ -844,7 +843,7 @@ struct SubstLookup : Lookup
 	do
 	{
 	  if ((~IN_MASK (buffer->in_pos) & mask) &&
-	      apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL, 0))
+	      apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL))
 	    ret = true;
 	  else
 	    buffer->in_pos--;
@@ -931,7 +930,7 @@ static inline bool substitute_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
   if (unlikely (context->context_length < 1))
     return false;
 
-  return l.apply_once (context->layout, context->buffer, context->context_length, context->nesting_level_left - 1, apply_depth + 1);
+  return l.apply_once (context->layout, context->buffer, context->context_length, context->nesting_level_left - 1);
 }
 
 
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 80968dc..ad4e404 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -36,18 +36,14 @@
 #endif
 
 #define TRACE_APPLY() \
-	HB_STMT_START { \
-	  if (HB_DEBUG_APPLY) \
-		  _hb_trace ("APPLY", HB_FUNC, this, apply_depth, HB_DEBUG_APPLY); \
-	} HB_STMT_END
+	hb_trace_t<HB_DEBUG_APPLY> trace (&context->debug_depth); \
+	trace.log ("APPLY", HB_FUNC, this);
 
 
 #define APPLY_ARG_DEF \
-	hb_apply_context_t *context, \
-	unsigned int apply_depth HB_UNUSED
+	hb_apply_context_t *context
 #define APPLY_ARG \
-	context, \
-	(HB_DEBUG_APPLY ? apply_depth + 1 : 0)
+	context
 
 struct hb_apply_context_t
 {
@@ -57,6 +53,7 @@ struct hb_apply_context_t
   unsigned int nesting_level_left;
   unsigned int lookup_flag;
   unsigned int property; /* propety of first glyph (TODO remove) */
+  unsigned int debug_depth;
 };
 
 
commit 969c9705ae0c64577c3f69f5300fec975f952e1f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 01:23:44 2010 -0400

    Move context_length into apply_context

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 605102d..cfd2411 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -577,7 +577,7 @@ struct PairPosFormat1
   inline bool apply (APPLY_ARG_DEF) const
   {
     TRACE_APPLY ();
-    unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+    unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context->context_length);
     if (unlikely (context->buffer->in_pos + 2 > end))
       return false;
 
@@ -670,7 +670,7 @@ struct PairPosFormat2
   inline bool apply (APPLY_ARG_DEF) const
   {
     TRACE_APPLY ();
-    unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+    unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context->context_length);
     if (unlikely (context->buffer->in_pos + 2 > end))
       return false;
 
@@ -1495,6 +1495,7 @@ struct PosLookup : Lookup
 
     context->layout = layout;
     context->buffer = buffer;
+    context->context_length = context_length;
     context->nesting_level_left = nesting_level_left;
     context->lookup_flag = get_flag ();
 
@@ -1608,10 +1609,10 @@ static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
   if (unlikely (context->nesting_level_left == 0))
     return false;
 
-  if (unlikely (context_length < 1))
+  if (unlikely (context->context_length < 1))
     return false;
 
-  return l.apply_once (context->layout, context->buffer, context_length, context->nesting_level_left - 1, apply_depth + 1);
+  return l.apply_once (context->layout, context->buffer, context->context_length, context->nesting_level_left - 1, apply_depth + 1);
 }
 
 
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index f0306a3..87dfcd2 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -367,7 +367,7 @@ struct Ligature
     TRACE_APPLY ();
     unsigned int i, j;
     unsigned int count = component.len;
-    unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+    unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context->context_length);
     if (unlikely (context->buffer->in_pos + count > end))
       return false;
 
@@ -597,7 +597,7 @@ struct ReverseChainSingleSubstFormat1
   inline bool apply (APPLY_ARG_DEF) const
   {
     TRACE_APPLY ();
-    if (unlikely (context_length != NO_CONTEXT))
+    if (unlikely (context->context_length != NO_CONTEXT))
       return false; /* No chaining to this type */
 
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
@@ -780,6 +780,7 @@ struct SubstLookup : Lookup
 
     context->layout = layout;
     context->buffer = buffer;
+    context->context_length = context_length;
     context->nesting_level_left = nesting_level_left;
     context->lookup_flag = get_flag ();
 
@@ -927,10 +928,10 @@ static inline bool substitute_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
   if (unlikely (context->nesting_level_left == 0))
     return false;
 
-  if (unlikely (context_length < 1))
+  if (unlikely (context->context_length < 1))
     return false;
 
-  return l.apply_once (context->layout, context->buffer, context_length, context->nesting_level_left - 1, apply_depth + 1);
+  return l.apply_once (context->layout, context->buffer, context->context_length, context->nesting_level_left - 1, apply_depth + 1);
 }
 
 
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 5398b8a..80968dc 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -44,17 +44,16 @@
 
 #define APPLY_ARG_DEF \
 	hb_apply_context_t *context, \
-	unsigned int context_length HB_UNUSED, \
 	unsigned int apply_depth HB_UNUSED
 #define APPLY_ARG \
 	context, \
-	context_length, \
 	(HB_DEBUG_APPLY ? apply_depth + 1 : 0)
 
 struct hb_apply_context_t
 {
   hb_ot_layout_context_t *layout;
   hb_buffer_t *buffer;
+  unsigned int context_length;
   unsigned int nesting_level_left;
   unsigned int lookup_flag;
   unsigned int property; /* propety of first glyph (TODO remove) */
@@ -103,7 +102,7 @@ static inline bool match_input (APPLY_ARG_DEF,
 				unsigned int *context_length_out)
 {
   unsigned int i, j;
-  unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+  unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context->context_length);
   if (unlikely (context->buffer->in_pos + count > end))
     return false;
 
@@ -158,7 +157,7 @@ static inline bool match_lookahead (APPLY_ARG_DEF,
 				    unsigned int offset)
 {
   unsigned int i, j;
-  unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+  unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context->context_length);
   if (unlikely (context->buffer->in_pos + offset + count > end))
     return false;
 
@@ -201,7 +200,7 @@ static inline bool apply_lookup (APPLY_ARG_DEF,
 				 const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
 				 apply_lookup_func_t apply_func)
 {
-  unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+  unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context->context_length);
   if (unlikely (context->buffer->in_pos + count > end))
     return false;
 
@@ -267,14 +266,20 @@ static inline bool context_lookup (APPLY_ARG_DEF,
 				   const LookupRecord lookupRecord[],
 				   ContextLookupContext &lookup_context)
 {
-  return match_input (APPLY_ARG,
-		      inputCount, input,
-		      lookup_context.funcs.match, lookup_context.match_data,
-		      &context_length) &&
-	 apply_lookup (APPLY_ARG,
-		       inputCount,
-		       lookupCount, lookupRecord,
-		       lookup_context.funcs.apply);
+  unsigned int new_context_length;
+  if (!match_input (APPLY_ARG,
+		    inputCount, input,
+		    lookup_context.funcs.match, lookup_context.match_data,
+		    &new_context_length)) return false;
+  unsigned int old_context_length;
+  old_context_length = context->context_length;
+  context->context_length = new_context_length;
+  bool ret = apply_lookup (APPLY_ARG,
+			   inputCount,
+			   lookupCount, lookupRecord,
+			   lookup_context.funcs.apply);
+  context->context_length = old_context_length;
+  return ret;
 }
 
 struct Rule
@@ -529,26 +534,31 @@ static inline bool chain_context_lookup (APPLY_ARG_DEF,
   /* First guess */
   if (unlikely (context->buffer->out_pos < backtrackCount ||
 		context->buffer->in_pos + inputCount + lookaheadCount > context->buffer->in_length ||
-		inputCount + lookaheadCount > context_length))
+		inputCount + lookaheadCount > context->context_length))
     return false;
 
   unsigned int offset;
-  return match_backtrack (APPLY_ARG,
-			  backtrackCount, backtrack,
-			  lookup_context.funcs.match, lookup_context.match_data[0]) &&
-	 match_input (APPLY_ARG,
-		      inputCount, input,
-		      lookup_context.funcs.match, lookup_context.match_data[1],
-		      &offset) &&
-	 match_lookahead (APPLY_ARG,
-			  lookaheadCount, lookahead,
-			  lookup_context.funcs.match, lookup_context.match_data[2],
-			  offset) &&
-	 (context_length = offset, true) &&
-	 apply_lookup (APPLY_ARG,
-		       inputCount,
-		       lookupCount, lookupRecord,
-		       lookup_context.funcs.apply);
+  if (!(match_backtrack (APPLY_ARG,
+			 backtrackCount, backtrack,
+			 lookup_context.funcs.match, lookup_context.match_data[0]) &&
+	match_input (APPLY_ARG,
+		     inputCount, input,
+		     lookup_context.funcs.match, lookup_context.match_data[1],
+		     &offset) &&
+	match_lookahead (APPLY_ARG,
+			 lookaheadCount, lookahead,
+			 lookup_context.funcs.match, lookup_context.match_data[2],
+			 offset))) return false;
+
+  unsigned int old_context_length;
+  old_context_length = context->context_length;
+  context->context_length = offset;
+  bool ret = apply_lookup (APPLY_ARG,
+			   inputCount,
+			   lookupCount, lookupRecord,
+			   lookup_context.funcs.apply);
+  context->context_length = old_context_length;
+  return ret;
 }
 
 struct ChainRule
commit 94a23aaeca39c662614037ef887412249bdc8d49
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 01:13:09 2010 -0400

    Move buffer into apply_context

diff --git a/src/hb-buffer-private.h b/src/hb-buffer-private.h
index c2bd885..d4a1641 100644
--- a/src/hb-buffer-private.h
+++ b/src/hb-buffer-private.h
@@ -132,20 +132,24 @@ HB_INTERNAL unsigned short
 _hb_buffer_allocate_lig_id (hb_buffer_t *buffer);
 
 
+#ifndef BUFFER
+#define BUFFER buffer
+#endif
+
 /* convenience macros */
-#define IN_GLYPH(pos)		(buffer->in_string[(pos)].codepoint)
-#define IN_INFO(pos)		(&buffer->in_string[(pos)])
-#define IN_CURGLYPH()		(buffer->in_string[buffer->in_pos].codepoint)
-#define IN_NEXTGLYPH()		(buffer->in_string[buffer->in_pos + 1].codepoint)
-#define IN_CURINFO()		(&buffer->in_string[buffer->in_pos])
-#define IN_MASK(pos)		(buffer->in_string[(pos)].mask)
-#define IN_CLUSTER(pos)		(buffer->in_string[(pos)].cluster)
-#define IN_LIGID(pos)		(buffer->in_string[(pos)].lig_id)
-#define IN_COMPONENT(pos)	(buffer->in_string[(pos)].component)
-#define POSITION(pos)		(&buffer->positions[(pos)])
-#define CURPOSITION()		(&buffer->positions[buffer->in_pos])
-#define OUT_GLYPH(pos)		(buffer->out_string[(pos)].codepoint)
-#define OUT_INFO(pos)		(&buffer->out_string[(pos)])
+#define IN_GLYPH(pos)		(BUFFER->in_string[(pos)].codepoint)
+#define IN_INFO(pos)		(&BUFFER->in_string[(pos)])
+#define IN_CURGLYPH()		(BUFFER->in_string[BUFFER->in_pos].codepoint)
+#define IN_NEXTGLYPH()		(BUFFER->in_string[BUFFER->in_pos + 1].codepoint)
+#define IN_CURINFO()		(&BUFFER->in_string[BUFFER->in_pos])
+#define IN_MASK(pos)		(BUFFER->in_string[(pos)].mask)
+#define IN_CLUSTER(pos)		(BUFFER->in_string[(pos)].cluster)
+#define IN_LIGID(pos)		(BUFFER->in_string[(pos)].lig_id)
+#define IN_COMPONENT(pos)	(BUFFER->in_string[(pos)].component)
+#define POSITION(pos)		(&BUFFER->positions[(pos)])
+#define CURPOSITION()		(&BUFFER->positions[BUFFER->in_pos])
+#define OUT_GLYPH(pos)		(BUFFER->out_string[(pos)].codepoint)
+#define OUT_INFO(pos)		(&BUFFER->out_string[(pos)])
 
 HB_END_DECLS
 
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 8fe93eb..605102d 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -29,6 +29,11 @@
 
 #include "hb-ot-layout-gsubgpos-private.hh"
 
+
+#undef BUFFER
+#define BUFFER context->buffer
+
+
 #define HB_OT_LAYOUT_GPOS_NO_LAST ((unsigned int) -1)
 
 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
@@ -391,14 +396,14 @@ struct MarkArray
     mark_anchor.get_anchor (context->layout, IN_CURGLYPH (), &mark_x, &mark_y);
     glyph_anchor.get_anchor (context->layout, IN_GLYPH (glyph_pos), &base_x, &base_y);
 
-    hb_internal_glyph_position_t *o = POSITION (buffer->in_pos);
+    hb_internal_glyph_position_t *o = POSITION (context->buffer->in_pos);
     o->x_advance = 0;
     o->y_advance = 0;
     o->x_offset  = base_x - mark_x;
     o->y_offset  = base_y - mark_y;
-    o->back      = buffer->in_pos - glyph_pos;
+    o->back      = context->buffer->in_pos - glyph_pos;
 
-    buffer->in_pos++;
+    context->buffer->in_pos++;
     return true;
   }
 
@@ -430,7 +435,7 @@ struct SinglePosFormat1
 
     valueFormat.apply_value (context->layout, CharP(this), values, CURPOSITION ());
 
-    buffer->in_pos++;
+    context->buffer->in_pos++;
     return true;
   }
 
@@ -473,7 +478,7 @@ struct SinglePosFormat2
 			     &values[index * valueFormat.get_len ()],
 			     CURPOSITION ());
 
-    buffer->in_pos++;
+    context->buffer->in_pos++;
     return true;
   }
 
@@ -572,15 +577,15 @@ struct PairPosFormat1
   inline bool apply (APPLY_ARG_DEF) const
   {
     TRACE_APPLY ();
-    unsigned int end = MIN (buffer->in_length, buffer->in_pos + context_length);
-    if (unlikely (buffer->in_pos + 2 > end))
+    unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+    if (unlikely (context->buffer->in_pos + 2 > end))
       return false;
 
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
     if (likely (index == NOT_COVERED))
       return false;
 
-    unsigned int j = buffer->in_pos + 1;
+    unsigned int j = context->buffer->in_pos + 1;
     while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), context->lookup_flag, NULL))
     {
       if (unlikely (j == end))
@@ -603,7 +608,7 @@ struct PairPosFormat1
 	valueFormat2.apply_value (context->layout, CharP(this), &record->values[len1], POSITION (j));
 	if (len2)
 	  j++;
-	buffer->in_pos = j;
+	context->buffer->in_pos = j;
 	return true;
       }
       record = &StructAtOffset<PairValueRecord> (*record, record_size);
@@ -665,15 +670,15 @@ struct PairPosFormat2
   inline bool apply (APPLY_ARG_DEF) const
   {
     TRACE_APPLY ();
-    unsigned int end = MIN (buffer->in_length, buffer->in_pos + context_length);
-    if (unlikely (buffer->in_pos + 2 > end))
+    unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+    if (unlikely (context->buffer->in_pos + 2 > end))
       return false;
 
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
     if (likely (index == NOT_COVERED))
       return false;
 
-    unsigned int j = buffer->in_pos + 1;
+    unsigned int j = context->buffer->in_pos + 1;
     while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), context->lookup_flag, NULL))
     {
       if (unlikely (j == end))
@@ -696,7 +701,7 @@ struct PairPosFormat2
 
     if (len2)
       j++;
-    buffer->in_pos = j;
+    context->buffer->in_pos = j;
 
     return true;
   }
@@ -949,10 +954,10 @@ struct CursivePosFormat1
 
     /* TODO vertical */
 
-    if (buffer->direction == HB_DIRECTION_RTL)
+    if (context->buffer->direction == HB_DIRECTION_RTL)
     {
       /* advance is absolute, not relative */
-      POSITION (buffer->in_pos)->x_advance = entry_x - gpi->anchor_x;
+      POSITION (context->buffer->in_pos)->x_advance = entry_x - gpi->anchor_x;
     }
     else
     {
@@ -962,23 +967,23 @@ struct CursivePosFormat1
 
     if  (context->lookup_flag & LookupFlag::RightToLeft)
     {
-      POSITION (last_pos)->cursive_chain = last_pos - buffer->in_pos;
+      POSITION (last_pos)->cursive_chain = last_pos - context->buffer->in_pos;
       POSITION (last_pos)->y_offset = entry_y - gpi->anchor_y;
     }
     else
     {
-      POSITION (buffer->in_pos)->cursive_chain = buffer->in_pos - last_pos;
-      POSITION (buffer->in_pos)->y_offset = gpi->anchor_y - entry_y;
+      POSITION (context->buffer->in_pos)->cursive_chain = context->buffer->in_pos - last_pos;
+      POSITION (context->buffer->in_pos)->y_offset = gpi->anchor_y - entry_y;
     }
 
   end:
     if (record.exitAnchor)
     {
-      gpi->last = buffer->in_pos;
+      gpi->last = context->buffer->in_pos;
       (this+record.exitAnchor).get_anchor (context->layout, IN_CURGLYPH (), &gpi->anchor_x, &gpi->anchor_y);
     }
 
-    buffer->in_pos++;
+    context->buffer->in_pos++;
     return true;
   }
 
@@ -1049,7 +1054,7 @@ struct MarkBasePosFormat1
 
     /* now we search backwards for a non-mark glyph */
     unsigned int property;
-    unsigned int j = buffer->in_pos;
+    unsigned int j = context->buffer->in_pos;
     do
     {
       if (unlikely (!j))
@@ -1152,7 +1157,7 @@ struct MarkLigPosFormat1
 
     /* now we search backwards for a non-mark glyph */
     unsigned int property;
-    unsigned int j = buffer->in_pos;
+    unsigned int j = context->buffer->in_pos;
     do
     {
       if (unlikely (!j))
@@ -1182,9 +1187,9 @@ struct MarkLigPosFormat1
      * is identical to the ligature ID of the found ligature.  If yes, we
      * can directly use the component index.  If not, we attach the mark
      * glyph to the last component of the ligature. */
-    if (IN_LIGID (j) && IN_LIGID (j) == IN_LIGID (buffer->in_pos) && IN_COMPONENT (buffer->in_pos))
+    if (IN_LIGID (j) && IN_LIGID (j) == IN_LIGID (context->buffer->in_pos) && IN_COMPONENT (context->buffer->in_pos))
     {
-      comp_index = IN_COMPONENT (buffer->in_pos) - 1;
+      comp_index = IN_COMPONENT (context->buffer->in_pos) - 1;
       if (comp_index >= comp_count)
 	comp_index = comp_count - 1;
     }
@@ -1272,7 +1277,7 @@ struct MarkMarkPosFormat1
 
     /* now we search backwards for a suitable mark glyph until a non-mark glyph */
     unsigned int property;
-    unsigned int j = buffer->in_pos;
+    unsigned int j = context->buffer->in_pos;
     do
     {
       if (unlikely (!j))
@@ -1286,8 +1291,8 @@ struct MarkMarkPosFormat1
     /* Two marks match only if they belong to the same base, or same component
      * of the same ligature.  That is, the component numbers must match, and
      * if those are non-zero, the ligid number should also match. */
-    if ((IN_COMPONENT (j) != IN_COMPONENT (buffer->in_pos)) ||
-	(IN_COMPONENT (j) && IN_LIGID (j) != IN_LIGID (buffer->in_pos)))
+    if ((IN_COMPONENT (j) != IN_COMPONENT (context->buffer->in_pos)) ||
+	(IN_COMPONENT (j) && IN_LIGID (j) != IN_LIGID (context->buffer->in_pos)))
       return false;
 
     unsigned int mark2_index = (this+mark2Coverage) (IN_GLYPH (j));
@@ -1489,6 +1494,7 @@ struct PosLookup : Lookup
     hb_apply_context_t context[1];
 
     context->layout = layout;
+    context->buffer = buffer;
     context->nesting_level_left = nesting_level_left;
     context->lookup_flag = get_flag ();
 
@@ -1506,6 +1512,8 @@ struct PosLookup : Lookup
 			     hb_buffer_t *buffer,
 			     hb_mask_t    mask) const
   {
+#undef BUFFER
+#define BUFFER buffer
     bool ret = false;
 
     if (unlikely (!buffer->in_length))
@@ -1603,7 +1611,7 @@ static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
   if (unlikely (context_length < 1))
     return false;
 
-  return l.apply_once (context->layout, buffer, context_length, context->nesting_level_left - 1, apply_depth + 1);
+  return l.apply_once (context->layout, context->buffer, context_length, context->nesting_level_left - 1, apply_depth + 1);
 }
 
 
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index f2f8954..f0306a3 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -30,6 +30,10 @@
 #include "hb-ot-layout-gsubgpos-private.hh"
 
 
+#undef BUFFER
+#define BUFFER context->buffer
+
+
 struct SingleSubstFormat1
 {
   friend struct SingleSubst;
@@ -45,7 +49,7 @@ struct SingleSubstFormat1
       return false;
 
     glyph_id += deltaGlyphID;
-    _hb_buffer_replace_glyph (buffer, glyph_id);
+    _hb_buffer_replace_glyph (context->buffer, glyph_id);
 
     /* We inherit the old glyph class to the substituted glyph */
     if (_hb_ot_layout_has_new_glyph_classes (context->layout->face))
@@ -88,7 +92,7 @@ struct SingleSubstFormat2
       return false;
 
     glyph_id = substitute[index];
-    _hb_buffer_replace_glyph (buffer, glyph_id);
+    _hb_buffer_replace_glyph (context->buffer, glyph_id);
 
     /* We inherit the old glyph class to the substituted glyph */
     if (_hb_ot_layout_has_new_glyph_classes (context->layout->face))
@@ -160,7 +164,7 @@ struct Sequence
     if (unlikely (!substitute.len))
       return false;
 
-    _hb_buffer_add_output_glyphs_be16 (buffer, 1,
+    _hb_buffer_add_output_glyphs_be16 (context->buffer, 1,
 				       substitute.len, (const uint16_t *) substitute.array(),
 				       0xFFFF, 0xFFFF);
 
@@ -285,8 +289,8 @@ struct AlternateSubstFormat1
 
     /* XXX callback to user to choose alternate
     if (context->layout->face->altfunc)
-      alt_index = (context->layout->face->altfunc)(context->layout->layout, buffer,
-				    buffer->out_pos, glyph_id,
+      alt_index = (context->layout->face->altfunc)(context->layout->layout, context->buffer,
+				    context->buffer->out_pos, glyph_id,
 				    alt_set.len, alt_set.array);
 				   */
 
@@ -295,7 +299,7 @@ struct AlternateSubstFormat1
 
     glyph_id = alt_set[alt_index];
 
-    _hb_buffer_replace_glyph (buffer, glyph_id);
+    _hb_buffer_replace_glyph (context->buffer, glyph_id);
 
     /* We inherit the old glyph class to the substituted glyph */
     if (_hb_ot_layout_has_new_glyph_classes (context->layout->face))
@@ -363,11 +367,11 @@ struct Ligature
     TRACE_APPLY ();
     unsigned int i, j;
     unsigned int count = component.len;
-    unsigned int end = MIN (buffer->in_length, buffer->in_pos + context_length);
-    if (unlikely (buffer->in_pos + count > end))
+    unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+    if (unlikely (context->buffer->in_pos + count > end))
       return false;
 
-    for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++)
+    for (i = 1, j = context->buffer->in_pos + 1; i < count; i++, j++)
     {
       unsigned int property;
       while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), context->lookup_flag, &property))
@@ -389,18 +393,18 @@ struct Ligature
 				     is_mark ? HB_OT_LAYOUT_GLYPH_CLASS_MARK
 					     : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE);
 
-    if (j == buffer->in_pos + i) /* No input glyphs skipped */
+    if (j == context->buffer->in_pos + i) /* No input glyphs skipped */
       /* We don't use a new ligature ID if there are no skipped
 	 glyphs and the ligature already has an ID. */
-      _hb_buffer_add_output_glyphs_be16 (buffer, i,
+      _hb_buffer_add_output_glyphs_be16 (context->buffer, i,
 					 1, (const uint16_t *) &ligGlyph,
 					 0,
-					 IN_LIGID (buffer->in_pos) && !IN_COMPONENT (buffer->in_pos) ?
-					 0xFFFF : _hb_buffer_allocate_lig_id (buffer));
+					 IN_LIGID (context->buffer->in_pos) && !IN_COMPONENT (context->buffer->in_pos) ?
+					 0xFFFF : _hb_buffer_allocate_lig_id (context->buffer));
     else
     {
-      unsigned int lig_id = _hb_buffer_allocate_lig_id (buffer);
-      _hb_buffer_add_output_glyph (buffer, ligGlyph, 0xFFFF, lig_id);
+      unsigned int lig_id = _hb_buffer_allocate_lig_id (context->buffer);
+      _hb_buffer_add_output_glyph (context->buffer, ligGlyph, 0xFFFF, lig_id);
 
       /* Now we must do a second loop to copy the skipped glyphs to
 	 `out' and assign component values to it.  We start with the
@@ -412,9 +416,9 @@ struct Ligature
       for ( i = 1; i < count; i++ )
       {
 	while (_hb_ot_layout_skip_mark (context->layout->face, IN_CURINFO (), context->lookup_flag, NULL))
-	  _hb_buffer_add_output_glyph (buffer, IN_CURGLYPH (), i, lig_id);
+	  _hb_buffer_add_output_glyph (context->buffer, IN_CURGLYPH (), i, lig_id);
 
-	(buffer->in_pos)++;
+	(context->buffer->in_pos)++;
       }
     }
 
@@ -612,7 +616,7 @@ struct ReverseChainSingleSubstFormat1
 			 1))
     {
       IN_CURGLYPH () = substitute[index];
-      buffer->in_pos--; /* Reverse! */
+      context->buffer->in_pos--; /* Reverse! */
       return true;
     }
 
@@ -775,6 +779,7 @@ struct SubstLookup : Lookup
     hb_apply_context_t context[1];
 
     context->layout = layout;
+    context->buffer = buffer;
     context->nesting_level_left = nesting_level_left;
     context->lookup_flag = get_flag ();
 
@@ -807,6 +812,8 @@ struct SubstLookup : Lookup
 			    hb_buffer_t *buffer,
 			    hb_mask_t    mask) const
   {
+#undef BUFFER
+#define BUFFER buffer
     bool ret = false;
 
     if (unlikely (!buffer->in_length))
@@ -923,7 +930,7 @@ static inline bool substitute_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
   if (unlikely (context_length < 1))
     return false;
 
-  return l.apply_once (context->layout, buffer, context_length, context->nesting_level_left - 1, apply_depth + 1);
+  return l.apply_once (context->layout, context->buffer, context_length, context->nesting_level_left - 1, apply_depth + 1);
 }
 
 
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index e91bae5..5398b8a 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -44,24 +44,29 @@
 
 #define APPLY_ARG_DEF \
 	hb_apply_context_t *context, \
-	hb_buffer_t *buffer, \
 	unsigned int context_length HB_UNUSED, \
 	unsigned int apply_depth HB_UNUSED
 #define APPLY_ARG \
 	context, \
-	buffer, \
 	context_length, \
 	(HB_DEBUG_APPLY ? apply_depth + 1 : 0)
 
 struct hb_apply_context_t
 {
   hb_ot_layout_context_t *layout;
+  hb_buffer_t *buffer;
   unsigned int nesting_level_left;
   unsigned int lookup_flag;
   unsigned int property; /* propety of first glyph (TODO remove) */
 };
 
 
+
+
+#undef BUFFER
+#define BUFFER context->buffer
+
+
 typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const char *data);
 typedef bool (*apply_lookup_func_t) (APPLY_ARG_DEF, unsigned int lookup_index);
 
@@ -98,11 +103,11 @@ static inline bool match_input (APPLY_ARG_DEF,
 				unsigned int *context_length_out)
 {
   unsigned int i, j;
-  unsigned int end = MIN (buffer->in_length, buffer->in_pos + context_length);
-  if (unlikely (buffer->in_pos + count > end))
+  unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+  if (unlikely (context->buffer->in_pos + count > end))
     return false;
 
-  for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++)
+  for (i = 1, j = context->buffer->in_pos + 1; i < count; i++, j++)
   {
     while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), context->lookup_flag, NULL))
     {
@@ -115,7 +120,7 @@ static inline bool match_input (APPLY_ARG_DEF,
       return false;
   }
 
-  *context_length_out = j - buffer->in_pos;
+  *context_length_out = j - context->buffer->in_pos;
 
   return true;
 }
@@ -126,10 +131,10 @@ static inline bool match_backtrack (APPLY_ARG_DEF,
 				    match_func_t match_func,
 				    const char *match_data)
 {
-  if (unlikely (buffer->out_pos < count))
+  if (unlikely (context->buffer->out_pos < count))
     return false;
 
-  for (unsigned int i = 0, j = buffer->out_pos - 1; i < count; i++, j--)
+  for (unsigned int i = 0, j = context->buffer->out_pos - 1; i < count; i++, j--)
   {
     while (_hb_ot_layout_skip_mark (context->layout->face, OUT_INFO (j), context->lookup_flag, NULL))
     {
@@ -153,11 +158,11 @@ static inline bool match_lookahead (APPLY_ARG_DEF,
 				    unsigned int offset)
 {
   unsigned int i, j;
-  unsigned int end = MIN (buffer->in_length, buffer->in_pos + context_length);
-  if (unlikely (buffer->in_pos + offset + count > end))
+  unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+  if (unlikely (context->buffer->in_pos + offset + count > end))
     return false;
 
-  for (i = 0, j = buffer->in_pos + offset; i < count; i++, j++)
+  for (i = 0, j = context->buffer->in_pos + offset; i < count; i++, j++)
   {
     while (_hb_ot_layout_skip_mark (context->layout->face, OUT_INFO (j), context->lookup_flag, NULL))
     {
@@ -196,8 +201,8 @@ static inline bool apply_lookup (APPLY_ARG_DEF,
 				 const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
 				 apply_lookup_func_t apply_func)
 {
-  unsigned int end = MIN (buffer->in_length, buffer->in_pos + context_length);
-  if (unlikely (buffer->in_pos + count > end))
+  unsigned int end = MIN (context->buffer->in_length, context->buffer->in_pos + context_length);
+  if (unlikely (context->buffer->in_pos + count > end))
     return false;
 
   /* TODO We don't support lookupRecord arrays that are not increasing:
@@ -211,15 +216,15 @@ static inline bool apply_lookup (APPLY_ARG_DEF,
   {
     while (_hb_ot_layout_skip_mark (context->layout->face, IN_CURINFO (), context->lookup_flag, NULL))
     {
-      if (unlikely (buffer->in_pos == end))
+      if (unlikely (context->buffer->in_pos == end))
 	return true;
       /* No lookup applied for this index */
-      _hb_buffer_next_glyph (buffer);
+      _hb_buffer_next_glyph (context->buffer);
     }
 
     if (lookupCount && i == lookupRecord->sequenceIndex)
     {
-      unsigned int old_pos = buffer->in_pos;
+      unsigned int old_pos = context->buffer->in_pos;
 
       /* Apply a lookup */
       bool done = apply_func (APPLY_ARG, lookupRecord->lookupListIndex);
@@ -227,8 +232,8 @@ static inline bool apply_lookup (APPLY_ARG_DEF,
       lookupRecord++;
       lookupCount--;
       /* Err, this is wrong if the lookup jumped over some glyphs */
-      i += buffer->in_pos - old_pos;
-      if (unlikely (buffer->in_pos == end))
+      i += context->buffer->in_pos - old_pos;
+      if (unlikely (context->buffer->in_pos == end))
 	return true;
 
       if (!done)
@@ -238,7 +243,7 @@ static inline bool apply_lookup (APPLY_ARG_DEF,
     {
     not_applied:
       /* No lookup applied for this index */
-      _hb_buffer_next_glyph (buffer);
+      _hb_buffer_next_glyph (context->buffer);
       i++;
     }
   }
@@ -522,9 +527,9 @@ static inline bool chain_context_lookup (APPLY_ARG_DEF,
 					 ChainContextLookupContext &lookup_context)
 {
   /* First guess */
-  if (unlikely (buffer->out_pos < backtrackCount ||
-		   buffer->in_pos + inputCount + lookaheadCount > buffer->in_length ||
-		   inputCount + lookaheadCount > context_length))
+  if (unlikely (context->buffer->out_pos < backtrackCount ||
+		context->buffer->in_pos + inputCount + lookaheadCount > context->buffer->in_length ||
+		inputCount + lookaheadCount > context_length))
     return false;
 
   unsigned int offset;
commit 63493f956dca519df49da0a6badc3cb0a1b92779
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 01:01:05 2010 -0400

    Move layout_context into apply_context

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 8c75c9f..8fe93eb 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -87,7 +87,7 @@ struct ValueFormat : USHORT
   inline unsigned int get_size () const
   { return get_len () * Value::get_size (); }
 
-  void apply_value (hb_ot_layout_context_t       *layout_context,
+  void apply_value (hb_ot_layout_context_t       *layout,
 		    const char                   *base,
 		    const Value                  *values,
 		    hb_internal_glyph_position_t *glyph_pos) const
@@ -98,8 +98,8 @@ struct ValueFormat : USHORT
 
     if (!format) return;
 
-    x_scale = layout_context->font->x_scale;
-    y_scale = layout_context->font->y_scale;
+    x_scale = layout->font->x_scale;
+    y_scale = layout->font->y_scale;
     /* design units -> fractional pixel */
     if (format & xPlacement) glyph_pos->x_offset  += _hb_16dot16_mul_round (x_scale, *(SHORT*)values++);
     if (format & yPlacement) glyph_pos->y_offset  += _hb_16dot16_mul_round (y_scale, *(SHORT*)values++);
@@ -108,8 +108,8 @@ struct ValueFormat : USHORT
 
     if (!has_device ()) return;
 
-    x_ppem = layout_context->font->x_ppem;
-    y_ppem = layout_context->font->y_ppem;
+    x_ppem = layout->font->x_ppem;
+    y_ppem = layout->font->y_ppem;
 
     if (!x_ppem && !y_ppem) return;
 
@@ -199,11 +199,11 @@ struct AnchorFormat1
   friend struct Anchor;
 
   private:
-  inline void get_anchor (hb_ot_layout_context_t *layout_context, hb_codepoint_t glyph_id HB_UNUSED,
+  inline void get_anchor (hb_ot_layout_context_t *layout, hb_codepoint_t glyph_id HB_UNUSED,
 			  hb_position_t *x, hb_position_t *y) const
   {
-      *x = _hb_16dot16_mul_round (layout_context->font->x_scale, xCoordinate);
-      *y = _hb_16dot16_mul_round (layout_context->font->y_scale, yCoordinate);
+      *x = _hb_16dot16_mul_round (layout->font->x_scale, xCoordinate);
+      *y = _hb_16dot16_mul_round (layout->font->y_scale, yCoordinate);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -223,18 +223,18 @@ struct AnchorFormat2
   friend struct Anchor;
 
   private:
-  inline void get_anchor (hb_ot_layout_context_t *layout_context, hb_codepoint_t glyph_id,
+  inline void get_anchor (hb_ot_layout_context_t *layout, hb_codepoint_t glyph_id,
 			  hb_position_t *x, hb_position_t *y) const
   {
-      unsigned int x_ppem = layout_context->font->x_ppem;
-      unsigned int y_ppem = layout_context->font->y_ppem;
+      unsigned int x_ppem = layout->font->x_ppem;
+      unsigned int y_ppem = layout->font->y_ppem;
       hb_position_t cx, cy;
       hb_bool_t ret;
 
       if (x_ppem || y_ppem)
-	ret = hb_font_get_contour_point (layout_context->font, layout_context->face, anchorPoint, glyph_id, &cx, &cy);
-      *x = x_ppem && ret ? cx : _hb_16dot16_mul_round (layout_context->font->x_scale, xCoordinate);
-      *y = y_ppem && ret ? cy : _hb_16dot16_mul_round (layout_context->font->y_scale, yCoordinate);
+	ret = hb_font_get_contour_point (layout->font, layout->face, anchorPoint, glyph_id, &cx, &cy);
+      *x = x_ppem && ret ? cx : _hb_16dot16_mul_round (layout->font->x_scale, xCoordinate);
+      *y = y_ppem && ret ? cy : _hb_16dot16_mul_round (layout->font->y_scale, yCoordinate);
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -255,17 +255,17 @@ struct AnchorFormat3
   friend struct Anchor;
 
   private:
-  inline void get_anchor (hb_ot_layout_context_t *layout_context, hb_codepoint_t glyph_id HB_UNUSED,
+  inline void get_anchor (hb_ot_layout_context_t *layout, hb_codepoint_t glyph_id HB_UNUSED,
 			  hb_position_t *x, hb_position_t *y) const
   {
-      *x = _hb_16dot16_mul_round (layout_context->font->x_scale, xCoordinate);
-      *y = _hb_16dot16_mul_round (layout_context->font->y_scale, yCoordinate);
+      *x = _hb_16dot16_mul_round (layout->font->x_scale, xCoordinate);
+      *y = _hb_16dot16_mul_round (layout->font->y_scale, yCoordinate);
 
       /* pixel -> fractional pixel */
-      if (layout_context->font->x_ppem)
-	*x += (this+xDeviceTable).get_delta (layout_context->font->x_ppem) << 16;
-      if (layout_context->font->y_ppem)
-	*y += (this+yDeviceTable).get_delta (layout_context->font->y_ppem) << 16;
+      if (layout->font->x_ppem)
+	*x += (this+xDeviceTable).get_delta (layout->font->x_ppem) << 16;
+      if (layout->font->y_ppem)
+	*y += (this+yDeviceTable).get_delta (layout->font->y_ppem) << 16;
   }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -292,15 +292,15 @@ ASSERT_SIZE (AnchorFormat3, 10);
 
 struct Anchor
 {
-  inline void get_anchor (hb_ot_layout_context_t *layout_context, hb_codepoint_t glyph_id,
+  inline void get_anchor (hb_ot_layout_context_t *layout, hb_codepoint_t glyph_id,
 			  hb_position_t *x, hb_position_t *y) const
   {
     *x = *y = 0;
     switch (u.format) {
-    case 1: u.format1->get_anchor (layout_context, glyph_id, x, y); return;
-    case 2: u.format2->get_anchor (layout_context, glyph_id, x, y); return;
-    case 3: u.format3->get_anchor (layout_context, glyph_id, x, y); return;
-    default:							    return;
+    case 1: u.format1->get_anchor (layout, glyph_id, x, y); return;
+    case 2: u.format2->get_anchor (layout, glyph_id, x, y); return;
+    case 3: u.format3->get_anchor (layout, glyph_id, x, y); return;
+    default:						    return;
     }
   }
 
@@ -388,8 +388,8 @@ struct MarkArray
 
     hb_position_t mark_x, mark_y, base_x, base_y;
 
-    mark_anchor.get_anchor (layout_context, IN_CURGLYPH (), &mark_x, &mark_y);
-    glyph_anchor.get_anchor (layout_context, IN_GLYPH (glyph_pos), &base_x, &base_y);
+    mark_anchor.get_anchor (context->layout, IN_CURGLYPH (), &mark_x, &mark_y);
+    glyph_anchor.get_anchor (context->layout, IN_GLYPH (glyph_pos), &base_x, &base_y);
 
     hb_internal_glyph_position_t *o = POSITION (buffer->in_pos);
     o->x_advance = 0;
@@ -428,7 +428,7 @@ struct SinglePosFormat1
     if (likely (index == NOT_COVERED))
       return false;
 
-    valueFormat.apply_value (layout_context, CharP(this), values, CURPOSITION ());
+    valueFormat.apply_value (context->layout, CharP(this), values, CURPOSITION ());
 
     buffer->in_pos++;
     return true;
@@ -469,7 +469,7 @@ struct SinglePosFormat2
     if (likely (index >= valueCount))
       return false;
 
-    valueFormat.apply_value (layout_context, CharP(this),
+    valueFormat.apply_value (context->layout, CharP(this),
 			     &values[index * valueFormat.get_len ()],
 			     CURPOSITION ());
 
@@ -581,7 +581,7 @@ struct PairPosFormat1
       return false;
 
     unsigned int j = buffer->in_pos + 1;
-    while (_hb_ot_layout_skip_mark (layout_context->face, IN_INFO (j), context->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), context->lookup_flag, NULL))
     {
       if (unlikely (j == end))
 	return false;
@@ -599,8 +599,8 @@ struct PairPosFormat1
     {
       if (IN_GLYPH (j) == record->secondGlyph)
       {
-	valueFormat1.apply_value (layout_context, CharP(this), &record->values[0], CURPOSITION ());
-	valueFormat2.apply_value (layout_context, CharP(this), &record->values[len1], POSITION (j));
+	valueFormat1.apply_value (context->layout, CharP(this), &record->values[0], CURPOSITION ());
+	valueFormat2.apply_value (context->layout, CharP(this), &record->values[len1], POSITION (j));
 	if (len2)
 	  j++;
 	buffer->in_pos = j;
@@ -674,7 +674,7 @@ struct PairPosFormat2
       return false;
 
     unsigned int j = buffer->in_pos + 1;
-    while (_hb_ot_layout_skip_mark (layout_context->face, IN_INFO (j), context->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), context->lookup_flag, NULL))
     {
       if (unlikely (j == end))
 	return false;
@@ -691,8 +691,8 @@ struct PairPosFormat2
       return false;
 
     const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
-    valueFormat1.apply_value (layout_context, CharP(this), v, CURPOSITION ());
-    valueFormat2.apply_value (layout_context, CharP(this), v + len1, POSITION (j));
+    valueFormat1.apply_value (context->layout, CharP(this), v, CURPOSITION ());
+    valueFormat2.apply_value (context->layout, CharP(this), v + len1, POSITION (j));
 
     if (len2)
       j++;
@@ -927,7 +927,7 @@ struct CursivePosFormat1
        Since horizontal advance widths or vertical advance heights
        can be used alone but not together, no ambiguity occurs.        */
 
-    struct hb_ot_layout_context_t::info_t::gpos_t *gpi = &layout_context->info.gpos;
+    struct hb_ot_layout_context_t::info_t::gpos_t *gpi = &context->layout->info.gpos;
     hb_codepoint_t last_pos = gpi->last;
     gpi->last = HB_OT_LAYOUT_GPOS_NO_LAST;
 
@@ -945,7 +945,7 @@ struct CursivePosFormat1
       goto end;
 
     hb_position_t entry_x, entry_y;
-    (this+record.entryAnchor).get_anchor (layout_context, IN_CURGLYPH (), &entry_x, &entry_y);
+    (this+record.entryAnchor).get_anchor (context->layout, IN_CURGLYPH (), &entry_x, &entry_y);
 
     /* TODO vertical */
 
@@ -975,7 +975,7 @@ struct CursivePosFormat1
     if (record.exitAnchor)
     {
       gpi->last = buffer->in_pos;
-      (this+record.exitAnchor).get_anchor (layout_context, IN_CURGLYPH (), &gpi->anchor_x, &gpi->anchor_y);
+      (this+record.exitAnchor).get_anchor (context->layout, IN_CURGLYPH (), &gpi->anchor_x, &gpi->anchor_y);
     }
 
     buffer->in_pos++;
@@ -1055,7 +1055,7 @@ struct MarkBasePosFormat1
       if (unlikely (!j))
 	return false;
       j--;
-    } while (_hb_ot_layout_skip_mark (layout_context->face, IN_INFO (j), LookupFlag::IgnoreMarks, &property));
+    } while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), LookupFlag::IgnoreMarks, &property));
 
 #if 0
     /* The following assertion is too strong. */
@@ -1158,7 +1158,7 @@ struct MarkLigPosFormat1
       if (unlikely (!j))
 	return false;
       j--;
-    } while (_hb_ot_layout_skip_mark (layout_context->face, IN_INFO (j), LookupFlag::IgnoreMarks, &property));
+    } while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), LookupFlag::IgnoreMarks, &property));
 
 #if 0
     /* The following assertion is too strong. */
@@ -1278,7 +1278,7 @@ struct MarkMarkPosFormat1
       if (unlikely (!j))
 	return false;
       j--;
-    } while (_hb_ot_layout_skip_mark (layout_context->face, IN_INFO (j), context->lookup_flag, &property));
+    } while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), context->lookup_flag, &property));
 
     if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
       return false;
@@ -1479,7 +1479,7 @@ struct PosLookup : Lookup
   inline const PosLookupSubTable& get_subtable (unsigned int i) const
   { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
 
-  inline bool apply_once (hb_ot_layout_context_t *layout_context,
+  inline bool apply_once (hb_ot_layout_context_t *layout,
 			  hb_buffer_t    *buffer,
 			  unsigned int    context_length,
 			  unsigned int    nesting_level_left,
@@ -1488,10 +1488,11 @@ struct PosLookup : Lookup
     unsigned int lookup_type = get_type ();
     hb_apply_context_t context[1];
 
+    context->layout = layout;
     context->nesting_level_left = nesting_level_left;
     context->lookup_flag = get_flag ();
 
-    if (!_hb_ot_layout_check_glyph_property (layout_context->face, IN_CURINFO (), context->lookup_flag, &context->property))
+    if (!_hb_ot_layout_check_glyph_property (context->layout->face, IN_CURINFO (), context->lookup_flag, &context->property))
       return false;
 
     for (unsigned int i = 0; i < get_subtable_count (); i++)
@@ -1501,7 +1502,7 @@ struct PosLookup : Lookup
     return false;
   }
 
-   inline bool apply_string (hb_ot_layout_context_t *layout_context,
+   inline bool apply_string (hb_ot_layout_context_t *layout,
 			     hb_buffer_t *buffer,
 			     hb_mask_t    mask) const
   {
@@ -1510,7 +1511,7 @@ struct PosLookup : Lookup
     if (unlikely (!buffer->in_length))
       return false;
 
-    layout_context->info.gpos.last = HB_OT_LAYOUT_GPOS_NO_LAST; /* no last valid glyph for cursive pos. */
+    layout->info.gpos.last = HB_OT_LAYOUT_GPOS_NO_LAST; /* no last valid glyph for cursive pos. */
 
     buffer->in_pos = 0;
     while (buffer->in_pos < buffer->in_length)
@@ -1518,7 +1519,7 @@ struct PosLookup : Lookup
       bool done;
       if (~IN_MASK (buffer->in_pos) & mask)
       {
-	  done = apply_once (layout_context, buffer, NO_CONTEXT, MAX_NESTING_LEVEL, 0);
+	  done = apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL, 0);
 	  ret |= done;
       }
       else
@@ -1526,7 +1527,7 @@ struct PosLookup : Lookup
           done = false;
 	  /* Contrary to properties defined in GDEF, user-defined properties
 	     will always stop a possible cursive positioning.                */
-	  layout_context->info.gpos.last = HB_OT_LAYOUT_GPOS_NO_LAST;
+	  layout->info.gpos.last = HB_OT_LAYOUT_GPOS_NO_LAST;
       }
 
       if (!done)
@@ -1558,11 +1559,11 @@ struct GPOS : GSUBGPOS
   inline const PosLookup& get_lookup (unsigned int i) const
   { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
 
-  inline bool position_lookup (hb_ot_layout_context_t *layout_context,
+  inline bool position_lookup (hb_ot_layout_context_t *layout,
 			       hb_buffer_t  *buffer,
 			       unsigned int  lookup_index,
 			       hb_mask_t     mask) const
-  { return get_lookup (lookup_index).apply_string (layout_context, buffer, mask); }
+  { return get_lookup (lookup_index).apply_string (layout, buffer, mask); }
 
   inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
@@ -1593,7 +1594,7 @@ inline bool ExtensionPos::sanitize (hb_sanitize_context_t *context)
 
 static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
 {
-  const GPOS &gpos = *(layout_context->face->ot_layout.gpos);
+  const GPOS &gpos = *(context->layout->face->ot_layout.gpos);
   const PosLookup &l = gpos.get_lookup (lookup_index);
 
   if (unlikely (context->nesting_level_left == 0))
@@ -1602,7 +1603,7 @@ static inline bool position_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
   if (unlikely (context_length < 1))
     return false;
 
-  return l.apply_once (layout_context, buffer, context_length, context->nesting_level_left - 1, apply_depth + 1);
+  return l.apply_once (context->layout, buffer, context_length, context->nesting_level_left - 1, apply_depth + 1);
 }
 
 
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 2dfe7c2..f2f8954 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -48,8 +48,8 @@ struct SingleSubstFormat1
     _hb_buffer_replace_glyph (buffer, glyph_id);
 
     /* We inherit the old glyph class to the substituted glyph */
-    if (_hb_ot_layout_has_new_glyph_classes (layout_context->face))
-      _hb_ot_layout_set_glyph_property (layout_context->face, glyph_id, context->property);
+    if (_hb_ot_layout_has_new_glyph_classes (context->layout->face))
+      _hb_ot_layout_set_glyph_property (context->layout->face, glyph_id, context->property);
 
     return true;
   }
@@ -91,8 +91,8 @@ struct SingleSubstFormat2
     _hb_buffer_replace_glyph (buffer, glyph_id);
 
     /* We inherit the old glyph class to the substituted glyph */
-    if (_hb_ot_layout_has_new_glyph_classes (layout_context->face))
-      _hb_ot_layout_set_glyph_property (layout_context->face, glyph_id, context->property);
+    if (_hb_ot_layout_has_new_glyph_classes (context->layout->face))
+      _hb_ot_layout_set_glyph_property (context->layout->face, glyph_id, context->property);
 
     return true;
   }
@@ -165,7 +165,7 @@ struct Sequence
 				       0xFFFF, 0xFFFF);
 
     /* This is a guess only ... */
-    if (_hb_ot_layout_has_new_glyph_classes (layout_context->face))
+    if (_hb_ot_layout_has_new_glyph_classes (context->layout->face))
     {
       unsigned int property = context->property;
       if (property == HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)
@@ -173,7 +173,7 @@ struct Sequence
 
       unsigned int count = substitute.len;
       for (unsigned int n = 0; n < count; n++)
-	_hb_ot_layout_set_glyph_property (layout_context->face, substitute[n], property);
+	_hb_ot_layout_set_glyph_property (context->layout->face, substitute[n], property);
     }
 
     return true;
@@ -284,8 +284,8 @@ struct AlternateSubstFormat1
     unsigned int alt_index = 0;
 
     /* XXX callback to user to choose alternate
-    if (layout_context->face->altfunc)
-      alt_index = (layout_context->face->altfunc)(layout_context->layout, buffer,
+    if (context->layout->face->altfunc)
+      alt_index = (context->layout->face->altfunc)(context->layout->layout, buffer,
 				    buffer->out_pos, glyph_id,
 				    alt_set.len, alt_set.array);
 				   */
@@ -298,8 +298,8 @@ struct AlternateSubstFormat1
     _hb_buffer_replace_glyph (buffer, glyph_id);
 
     /* We inherit the old glyph class to the substituted glyph */
-    if (_hb_ot_layout_has_new_glyph_classes (layout_context->face))
-      _hb_ot_layout_set_glyph_property (layout_context->face, glyph_id, context->property);
+    if (_hb_ot_layout_has_new_glyph_classes (context->layout->face))
+      _hb_ot_layout_set_glyph_property (context->layout->face, glyph_id, context->property);
 
     return true;
   }
@@ -370,7 +370,7 @@ struct Ligature
     for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++)
     {
       unsigned int property;
-      while (_hb_ot_layout_skip_mark (layout_context->face, IN_INFO (j), context->lookup_flag, &property))
+      while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), context->lookup_flag, &property))
       {
 	if (unlikely (j + count - i == end))
 	  return false;
@@ -384,8 +384,8 @@ struct Ligature
         return false;
     }
     /* This is just a guess ... */
-    if (_hb_ot_layout_has_new_glyph_classes (layout_context->face))
-      _hb_ot_layout_set_glyph_class (layout_context->face, ligGlyph,
+    if (_hb_ot_layout_has_new_glyph_classes (context->layout->face))
+      _hb_ot_layout_set_glyph_class (context->layout->face, ligGlyph,
 				     is_mark ? HB_OT_LAYOUT_GLYPH_CLASS_MARK
 					     : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE);
 
@@ -411,7 +411,7 @@ struct Ligature
 
       for ( i = 1; i < count; i++ )
       {
-	while (_hb_ot_layout_skip_mark (layout_context->face, IN_CURINFO (), context->lookup_flag, NULL))
+	while (_hb_ot_layout_skip_mark (context->layout->face, IN_CURINFO (), context->lookup_flag, NULL))
 	  _hb_buffer_add_output_glyph (buffer, IN_CURGLYPH (), i, lig_id);
 
 	(buffer->in_pos)++;
@@ -765,7 +765,7 @@ struct SubstLookup : Lookup
   }
 
 
-  inline bool apply_once ( hb_ot_layout_context_t *layout_context,
+  inline bool apply_once (hb_ot_layout_context_t *layout,
 			  hb_buffer_t *buffer,
 			  unsigned int context_length,
 			  unsigned int nesting_level_left,
@@ -774,10 +774,11 @@ struct SubstLookup : Lookup
     unsigned int lookup_type = get_type ();
     hb_apply_context_t context[1];
 
+    context->layout = layout;
     context->nesting_level_left = nesting_level_left;
     context->lookup_flag = get_flag ();
 
-    if (!_hb_ot_layout_check_glyph_property (layout_context->face, IN_CURINFO (), context->lookup_flag, &context->property))
+    if (!_hb_ot_layout_check_glyph_property (context->layout->face, IN_CURINFO (), context->lookup_flag, &context->property))
       return false;
 
     if (unlikely (lookup_type == SubstLookupSubTable::Extension))
@@ -802,7 +803,7 @@ struct SubstLookup : Lookup
     return false;
   }
 
-  inline bool apply_string (hb_ot_layout_context_t *layout_context,
+  inline bool apply_string (hb_ot_layout_context_t *layout,
 			    hb_buffer_t *buffer,
 			    hb_mask_t    mask) const
   {
@@ -819,7 +820,7 @@ struct SubstLookup : Lookup
 	while (buffer->in_pos < buffer->in_length)
 	{
 	  if ((~IN_MASK (buffer->in_pos) & mask) &&
-	      apply_once (layout_context, buffer, NO_CONTEXT, MAX_NESTING_LEVEL, 0))
+	      apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL, 0))
 	    ret = true;
 	  else
 	    _hb_buffer_next_glyph (buffer);
@@ -835,7 +836,7 @@ struct SubstLookup : Lookup
 	do
 	{
 	  if ((~IN_MASK (buffer->in_pos) & mask) &&
-	      apply_once (layout_context, buffer, NO_CONTEXT, MAX_NESTING_LEVEL, 0))
+	      apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL, 0))
 	    ret = true;
 	  else
 	    buffer->in_pos--;
@@ -869,11 +870,11 @@ struct GSUB : GSUBGPOS
   inline const SubstLookup& get_lookup (unsigned int i) const
   { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
 
-  inline bool substitute_lookup (hb_ot_layout_context_t *layout_context,
+  inline bool substitute_lookup (hb_ot_layout_context_t *layout,
 				 hb_buffer_t  *buffer,
 			         unsigned int  lookup_index,
 				 hb_mask_t     mask) const
-  { return get_lookup (lookup_index).apply_string (layout_context, buffer, mask); }
+  { return get_lookup (lookup_index).apply_string (layout, buffer, mask); }
 
 
   inline bool sanitize (hb_sanitize_context_t *context) {
@@ -913,7 +914,7 @@ inline bool ExtensionSubst::is_reverse (void) const
 
 static inline bool substitute_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
 {
-  const GSUB &gsub = *(layout_context->face->ot_layout.gsub);
+  const GSUB &gsub = *(context->layout->face->ot_layout.gsub);
   const SubstLookup &l = gsub.get_lookup (lookup_index);
 
   if (unlikely (context->nesting_level_left == 0))
@@ -922,7 +923,7 @@ static inline bool substitute_lookup (APPLY_ARG_DEF, unsigned int lookup_index)
   if (unlikely (context_length < 1))
     return false;
 
-  return l.apply_once (layout_context, buffer, context_length, context->nesting_level_left - 1, apply_depth + 1);
+  return l.apply_once (context->layout, buffer, context_length, context->nesting_level_left - 1, apply_depth + 1);
 }
 
 
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index e542481..e91bae5 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -44,19 +44,18 @@
 
 #define APPLY_ARG_DEF \
 	hb_apply_context_t *context, \
-	hb_ot_layout_context_t *layout_context, \
 	hb_buffer_t *buffer, \
 	unsigned int context_length HB_UNUSED, \
 	unsigned int apply_depth HB_UNUSED
 #define APPLY_ARG \
 	context, \
-	layout_context, \
 	buffer, \
 	context_length, \
 	(HB_DEBUG_APPLY ? apply_depth + 1 : 0)
 
 struct hb_apply_context_t
 {
+  hb_ot_layout_context_t *layout;
   unsigned int nesting_level_left;
   unsigned int lookup_flag;
   unsigned int property; /* propety of first glyph (TODO remove) */
@@ -105,7 +104,7 @@ static inline bool match_input (APPLY_ARG_DEF,
 
   for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++)
   {
-    while (_hb_ot_layout_skip_mark (layout_context->face, IN_INFO (j), context->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->layout->face, IN_INFO (j), context->lookup_flag, NULL))
     {
       if (unlikely (j + count - i == end))
 	return false;
@@ -132,7 +131,7 @@ static inline bool match_backtrack (APPLY_ARG_DEF,
 
   for (unsigned int i = 0, j = buffer->out_pos - 1; i < count; i++, j--)
   {
-    while (_hb_ot_layout_skip_mark (layout_context->face, OUT_INFO (j), context->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->layout->face, OUT_INFO (j), context->lookup_flag, NULL))
     {
       if (unlikely (j + 1 == count - i))
 	return false;
@@ -160,7 +159,7 @@ static inline bool match_lookahead (APPLY_ARG_DEF,
 
   for (i = 0, j = buffer->in_pos + offset; i < count; i++, j++)
   {
-    while (_hb_ot_layout_skip_mark (layout_context->face, OUT_INFO (j), context->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->layout->face, OUT_INFO (j), context->lookup_flag, NULL))
     {
       if (unlikely (j + count - i == end))
 	return false;
@@ -210,7 +209,7 @@ static inline bool apply_lookup (APPLY_ARG_DEF,
    */
   for (unsigned int i = 0; i < count; /* NOP */)
   {
-    while (_hb_ot_layout_skip_mark (layout_context->face, IN_CURINFO (), context->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (context->layout->face, IN_CURINFO (), context->lookup_flag, NULL))
     {
       if (unlikely (buffer->in_pos == end))
 	return true;
commit fff9aa263d1daf7c5117cf383fafa5043d5eb5af
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 00:32:21 2010 -0400

    Minor

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 71fe8a6..e542481 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -281,10 +281,10 @@ struct Rule
   inline bool apply (APPLY_ARG_DEF, ContextLookupContext &lookup_context) const
   {
     TRACE_APPLY ();
-    const LookupRecord &lookupRecord = StructAtOffset<LookupRecord> (input, input[0].get_size () * (inputCount ? inputCount - 1 : 0));
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].get_size () * (inputCount ? inputCount - 1 : 0));
     return context_lookup (APPLY_ARG,
 			   inputCount, input,
-			   lookupCount, &lookupRecord,
+			   lookupCount, lookupRecord,
 			   lookup_context);
   }
 
@@ -433,14 +433,14 @@ struct ContextFormat3
     if (likely (index == NOT_COVERED))
       return false;
 
-    const LookupRecord &lookupRecord = StructAtOffset<LookupRecord> (coverage, coverage[0].get_size () * glyphCount);
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].get_size () * glyphCount);
     struct ContextLookupContext lookup_context = {
       {match_coverage, apply_func},
        CharP(this)
     };
     return context_lookup (APPLY_ARG,
 			   glyphCount, (const USHORT *) (coverage + 1),
-			   lookupCount, &lookupRecord,
+			   lookupCount, lookupRecord,
 			   lookup_context);
   }
 
@@ -451,8 +451,8 @@ struct ContextFormat3
     if (!SANITIZE_ARRAY (coverage, OffsetTo<Coverage>::get_size (), glyphCount)) return false;
     for (unsigned int i = 0; i < count; i++)
       if (!SANITIZE_WITH_BASE (this, coverage[i])) return false;
-    LookupRecord &lookupRecord = StructAtOffset<LookupRecord> (coverage, OffsetTo<Coverage>::get_size () * glyphCount);
-    return SANITIZE_ARRAY (&lookupRecord, LookupRecord::get_size (), lookupCount);
+    LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, OffsetTo<Coverage>::get_size () * glyphCount);
+    return SANITIZE_ARRAY (lookupRecord, LookupRecord::get_size (), lookupCount);
   }
 
   private:
commit 27e302dc8e794ff6bf878bc76e17d336d510849e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 00:26:16 2010 -0400

    I keep changing my mind about this

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 9254e44..bdffa95 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -195,7 +195,7 @@ struct hb_sanitize_context_t
 	       this->start, this->end,
 	       ret ? "pass" : "FAIL");
 
-    return ret;
+    return likely (ret);
   }
 
   inline bool check_array (const char *base, unsigned int record_size, unsigned int len) const
@@ -211,7 +211,7 @@ struct hb_sanitize_context_t
 	       this->start, this->end,
 	       !overflows ? "does not overflow" : "OVERFLOWS FAIL");
 
-    return likely (!overflows) && this->check (base, record_size * len);
+    return likely (!overflows && this->check (base, record_size * len));
   }
 
   inline bool can_edit (const char *base HB_UNUSED, unsigned int len HB_UNUSED)
@@ -230,21 +230,11 @@ struct hb_sanitize_context_t
     return this->writable;
   }
 
-  inline const char *get_start (void) const { return start; }
-  inline const char *get_end (void) const { return end; }
-  inline bool is_writable (void) const { return writable; }
-  inline unsigned int get_edit_count (void) const { return this->edit_count; }
-
-  inline void reset_edit_count (void) { this->edit_count = 0; }
-
-  public:
-  unsigned int debug_depth;
-
-  private:
   const char *start, *end;
   bool writable;
   unsigned int edit_count;
   hb_blob_t *blob;
+  unsigned int debug_depth;
 };
 
 
@@ -275,28 +265,28 @@ struct Sanitizer
 
     context->init (blob);
 
-    Type *t = CastP<Type> (const_cast<char *> (context->get_start ()));
+    Type *t = CastP<Type> (const_cast<char *> (context->start));
 
     sane = t->sanitize (context);
     if (sane) {
-      if (context->get_edit_count ()) {
+      if (context->edit_count) {
 	if (HB_DEBUG_SANITIZE)
 	  fprintf (stderr, "Sanitizer %p passed first round with %d edits; doing a second round %s\n",
-		   blob, context->get_edit_count (), HB_FUNC);
+		   blob, context->edit_count, HB_FUNC);
 
         /* sanitize again to ensure no toe-stepping */
-        context->reset_edit_count ();
+        context->edit_count = 0;
 	sane = t->sanitize (context);
-	if (context->get_edit_count ()) {
+	if (context->edit_count) {
 	  if (HB_DEBUG_SANITIZE)
 	    fprintf (stderr, "Sanitizer %p requested %d edits in second round; FAILLING %s\n",
-		     blob, context->get_edit_count (), HB_FUNC);
+		     blob, context->edit_count, HB_FUNC);
 	  sane = false;
 	}
       }
       context->finish ();
     } else {
-      unsigned int edit_count = context->get_edit_count ();
+      unsigned int edit_count = context->edit_count;
       context->finish ();
       if (edit_count && !hb_blob_is_writable (blob) && hb_blob_try_writable (blob)) {
         /* ok, we made it writable by relocating.  try again */
commit 39840474afd2cda9ff576c08aff9c87095496c27
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 00:23:19 2010 -0400

    Remove SANITIZE_ARG_DEF and SANITIZE_ARG

diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index 547cef0..ed9369b 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -49,7 +49,7 @@ typedef struct TableDirectory
 {
   static inline unsigned int get_size () { return sizeof (TableDirectory); }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -98,7 +98,7 @@ typedef struct OffsetTable
   }
 
   public:
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF () && SANITIZE_ARRAY (tableDir, TableDirectory::get_size (), numTables);
   }
@@ -124,7 +124,7 @@ struct TTCHeaderVersion1
   inline unsigned int get_face_count (void) const { return table.len; }
   inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, table);
   }
@@ -162,12 +162,12 @@ struct TTCHeader
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.header.version)) return false;
     switch (u.header.version) {
     case 2: /* version 2 is compatible with version 1 */
-    case 1: return u.version1->sanitize (SANITIZE_ARG);
+    case 1: return u.version1->sanitize (context);
     default:return true;
     }
   }
@@ -224,15 +224,15 @@ struct OpenTypeFontFile
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.tag)) return false;
     switch (u.tag) {
     case CFFTag:	/* All the non-collection tags */
     case TrueTag:
     case Typ1Tag:
-    case TrueTypeTag:	return u.fontFace->sanitize (SANITIZE_ARG);
-    case TTCTag:	return u.ttcHeader->sanitize (SANITIZE_ARG);
+    case TrueTypeTag:	return u.fontFace->sanitize (context);
+    case TTCTag:	return u.ttcHeader->sanitize (context);
     default:		return true;
     }
   }
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 2a0dccb..9254e44 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -153,11 +153,6 @@ struct hb_trace_t<0> {
 	trace.log ("SANITIZE", HB_FUNC, this);
 
 
-#define SANITIZE_ARG_DEF \
-	hb_sanitize_context_t *context
-#define SANITIZE_ARG \
-	context
-
 struct hb_sanitize_context_t
 {
   inline void init (hb_blob_t *blob)
@@ -253,9 +248,9 @@ struct hb_sanitize_context_t
 };
 
 
-#define SANITIZE(X) likely ((X).sanitize (SANITIZE_ARG))
+#define SANITIZE(X) likely ((X).sanitize (context))
 
-#define SANITIZE_WITH_BASE(B,X) likely ((X).sanitize (SANITIZE_ARG, CharP(B)))
+#define SANITIZE_WITH_BASE(B,X) likely ((X).sanitize (context, CharP(B)))
 
 #define SANITIZE_SELF() SANITIZE_MEM(this, sizeof (*this))
 
@@ -282,7 +277,7 @@ struct Sanitizer
 
     Type *t = CastP<Type> (const_cast<char *> (context->get_start ()));
 
-    sane = t->sanitize (SANITIZE_ARG);
+    sane = t->sanitize (context);
     if (sane) {
       if (context->get_edit_count ()) {
 	if (HB_DEBUG_SANITIZE)
@@ -291,7 +286,7 @@ struct Sanitizer
 
         /* sanitize again to ensure no toe-stepping */
         context->reset_edit_count ();
-	sane = t->sanitize (SANITIZE_ARG);
+	sane = t->sanitize (context);
 	if (context->get_edit_count ()) {
 	  if (HB_DEBUG_SANITIZE)
 	    fprintf (stderr, "Sanitizer %p requested %d edits in second round; FAILLING %s\n",
@@ -373,7 +368,7 @@ struct IntType
   inline operator Type(void) const { return v; }
   inline bool operator == (const IntType<Type> &o) const { return v == o.v; }
   inline bool operator != (const IntType<Type> &o) const { return v != o.v; }
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -435,7 +430,7 @@ struct FixedVersion
 {
   inline operator uint32_t (void) const { return (major << 16) + minor; }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -462,27 +457,27 @@ struct GenericOffsetTo : OffsetType
     return StructAtOffset<Type> (*CharP(base), offset);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base) {
+  inline bool sanitize (hb_sanitize_context_t *context, void *base) {
     TRACE_SANITIZE ();
     if (!SANITIZE_SELF ()) return false;
     unsigned int offset = *this;
     if (unlikely (!offset)) return true;
     Type &obj = StructAtOffset<Type> (*CharP(base), offset);
-    return likely (obj.sanitize (SANITIZE_ARG)) || neuter (SANITIZE_ARG);
+    return likely (obj.sanitize (context)) || neuter (context);
   }
   template <typename T>
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base, T user_data) {
+  inline bool sanitize (hb_sanitize_context_t *context, void *base, T user_data) {
     TRACE_SANITIZE ();
     if (!SANITIZE_SELF ()) return false;
     unsigned int offset = *this;
     if (unlikely (!offset)) return true;
     Type &obj = StructAtOffset<Type> (*CharP(base), offset);
-    return likely (obj.sanitize (SANITIZE_ARG, user_data)) || neuter (SANITIZE_ARG);
+    return likely (obj.sanitize (context, user_data)) || neuter (context);
   }
 
   private:
   /* Set the offset to Null */
-  inline bool neuter (SANITIZE_ARG_DEF) {
+  inline bool neuter (hb_sanitize_context_t *context) {
     if (context->can_edit (CharP(this), this->get_size ())) {
       this->set (0); /* 0 is Null offset */
       return true;
@@ -530,9 +525,9 @@ struct GenericArrayOf
   inline unsigned int get_size () const
   { return len.get_size () + len * Type::get_size (); }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    if (!likely (sanitize_shallow (SANITIZE_ARG))) return false;
+    if (!likely (sanitize_shallow (context))) return false;
     /* Note: for structs that do not reference other structs,
      * we do not need to call their sanitize() as we already did
      * a bound check on the aggregate array size, hence the return.
@@ -547,28 +542,28 @@ struct GenericArrayOf
         return false;
     return true;
   }
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base) {
+  inline bool sanitize (hb_sanitize_context_t *context, void *base) {
     TRACE_SANITIZE ();
-    if (!likely (sanitize_shallow (SANITIZE_ARG))) return false;
+    if (!likely (sanitize_shallow (context))) return false;
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
-      if (!array()[i].sanitize (SANITIZE_ARG, base))
+      if (!array()[i].sanitize (context, base))
         return false;
     return true;
   }
   template <typename T>
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base, T user_data) {
+  inline bool sanitize (hb_sanitize_context_t *context, void *base, T user_data) {
     TRACE_SANITIZE ();
-    if (!likely (sanitize_shallow (SANITIZE_ARG))) return false;
+    if (!likely (sanitize_shallow (context))) return false;
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
-      if (!array()[i].sanitize (SANITIZE_ARG, base, user_data))
+      if (!array()[i].sanitize (context, base, user_data))
         return false;
     return true;
   }
 
   private:
-  inline bool sanitize_shallow (SANITIZE_ARG_DEF) {
+  inline bool sanitize_shallow (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF() && SANITIZE_ARRAY (this, Type::get_size (), len);
   }
@@ -608,14 +603,14 @@ struct OffsetListOf : OffsetArrayOf<Type>
     return this+this->array()[i];
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    return OffsetArrayOf<Type>::sanitize (SANITIZE_ARG, CharP(this));
+    return OffsetArrayOf<Type>::sanitize (context, CharP(this));
   }
   template <typename T>
-  inline bool sanitize (SANITIZE_ARG_DEF, T user_data) {
+  inline bool sanitize (hb_sanitize_context_t *context, T user_data) {
     TRACE_SANITIZE ();
-    return OffsetArrayOf<Type>::sanitize (SANITIZE_ARG, CharP(this), user_data);
+    return OffsetArrayOf<Type>::sanitize (context, CharP(this), user_data);
   }
 };
 
@@ -636,13 +631,13 @@ struct HeadlessArrayOf
   inline unsigned int get_size () const
   { return len.get_size () + (len ? len - 1 : 0) * Type::get_size (); }
 
-  inline bool sanitize_shallow (SANITIZE_ARG_DEF) {
+  inline bool sanitize_shallow (hb_sanitize_context_t *context) {
     return SANITIZE_SELF() && SANITIZE_ARRAY (this, Type::get_size (), len);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    if (!likely (sanitize_shallow (SANITIZE_ARG))) return false;
+    if (!likely (sanitize_shallow (context))) return false;
     /* Note: for structs that do not reference other structs,
      * we do not need to call their sanitize() as we already did
      * a bound check on the aggregate array size, hence the return.
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 2c1c988..d9b2da3 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -53,7 +53,7 @@ struct Record
 {
   static inline unsigned int get_size () { return sizeof (Record<Type>); }
 
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base) {
+  inline bool sanitize (hb_sanitize_context_t *context, void *base) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ()
 	&& SANITIZE_WITH_BASE (base, offset);
@@ -110,9 +110,9 @@ struct RecordListOf : RecordArrayOf<Type>
   inline const Type& operator [] (unsigned int i) const
   { return this+RecordArrayOf<Type>::operator [](i).offset; }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    return RecordArrayOf<Type>::sanitize (SANITIZE_ARG, CharP(this));
+    return RecordArrayOf<Type>::sanitize (context, CharP(this));
   }
 };
 
@@ -164,7 +164,7 @@ struct LangSys
    return reqFeatureIndex;;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF () && SANITIZE (featureIndex);
   }
@@ -201,7 +201,7 @@ struct Script
   inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
   inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, defaultLangSys)
 	&& SANITIZE_WITH_BASE (this, langSys);
@@ -232,7 +232,7 @@ struct Feature
 					  unsigned int *lookup_tags /* OUT */) const
   { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF () && SANITIZE (lookupIndex);
   }
@@ -282,10 +282,10 @@ struct Lookup
     return flag;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     /* Real sanitize of the subtables is done by GSUB/GPOS/... */
-    if (!(SANITIZE_SELF () && likely (subTable.sanitize (SANITIZE_ARG)))) return false;
+    if (!(SANITIZE_SELF () && likely (subTable.sanitize (context)))) return false;
     if (unlikely (lookupFlag & LookupFlag::UseMarkFilteringSet))
     {
       USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
@@ -331,7 +331,7 @@ struct CoverageFormat1
     return NOT_COVERED;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE (glyphArray);
   }
@@ -358,7 +358,7 @@ struct CoverageRangeRecord
   }
 
   public:
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -390,7 +390,7 @@ struct CoverageFormat2
     return NOT_COVERED;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE (rangeRecord);
   }
@@ -417,12 +417,12 @@ struct Coverage
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
-    case 2: return u.format2->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
+    case 2: return u.format2->sanitize (context);
     default:return true;
     }
   }
@@ -452,7 +452,7 @@ struct ClassDefFormat1
     return 0;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF () && SANITIZE (classValue);
   }
@@ -479,7 +479,7 @@ struct ClassRangeRecord
   }
 
   public:
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -510,7 +510,7 @@ struct ClassDefFormat2
     return 0;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE (rangeRecord);
   }
@@ -535,12 +535,12 @@ struct ClassDef
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
-    case 2: return u.format2->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
+    case 2: return u.format2->sanitize (context);
     default:return true;
     }
   }
@@ -592,7 +592,7 @@ struct Device
     return USHORT::get_size () * (4 + ((endSize - startSize) >> (4 - f)));
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF() && SANITIZE_MEM (this, this->get_size ());
   }
diff --git a/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh
index da49fac..65b2414 100644
--- a/src/hb-ot-layout-gdef-private.hh
+++ b/src/hb-ot-layout-gdef-private.hh
@@ -67,7 +67,7 @@ struct AttachList
     return points.len;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE_WITH_BASE (this, attachPoint);
@@ -98,7 +98,7 @@ struct CaretValueFormat1
     return _hb_16dot16_mul_round (context->font->x_scale, coordinate);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -124,7 +124,7 @@ struct CaretValueFormat2
       return 0;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -146,7 +146,7 @@ struct CaretValueFormat3
 	   ((this+deviceTable).get_delta (context->font->x_ppem) << 16);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ()
 	&& SANITIZE_WITH_BASE (this, deviceTable);
@@ -174,13 +174,13 @@ struct CaretValue
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
-    case 2: return u.format2->sanitize (SANITIZE_ARG);
-    case 3: return u.format3->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
+    case 2: return u.format2->sanitize (context);
+    case 3: return u.format3->sanitize (context);
     default:return true;
     }
   }
@@ -212,7 +212,7 @@ struct LigGlyph
     return carets.len;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, carets);
   }
@@ -244,7 +244,7 @@ struct LigCaretList
     return lig_glyph.get_lig_carets (context, glyph_id, start_offset, caret_count, caret_array);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE_WITH_BASE (this, ligGlyph);
@@ -266,7 +266,7 @@ struct MarkGlyphSetsFormat1
   inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
   { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage);
   }
@@ -289,11 +289,11 @@ struct MarkGlyphSets
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
     default:return true;
     }
   }
@@ -349,7 +349,7 @@ struct GDEF
   inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
   { return version >= 0x00010002 && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE (version) && likely (version.major == 1)
 	&& SANITIZE_WITH_BASE (this, glyphClassDef)
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 9837c04..8c75c9f 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -129,7 +129,7 @@ struct ValueFormat : USHORT
   }
 
   private:
-  inline bool sanitize_value_devices (SANITIZE_ARG_DEF, void *base, const Value *values) {
+  inline bool sanitize_value_devices (hb_sanitize_context_t *context, void *base, const Value *values) {
     unsigned int format = *this;
 
     if (format & xPlacement) values++;
@@ -152,14 +152,14 @@ struct ValueFormat : USHORT
     return (format & devices) != 0;
   }
 
-  inline bool sanitize_value (SANITIZE_ARG_DEF, void *base, const Value *values) {
+  inline bool sanitize_value (hb_sanitize_context_t *context, void *base, const Value *values) {
     TRACE_SANITIZE ();
 
     return SANITIZE_MEM (values, get_size ()) &&
-	   (!has_device () || sanitize_value_devices (SANITIZE_ARG, base, values));
+	   (!has_device () || sanitize_value_devices (context, base, values));
   }
 
-  inline bool sanitize_values (SANITIZE_ARG_DEF, void *base, const Value *values, unsigned int count) {
+  inline bool sanitize_values (hb_sanitize_context_t *context, void *base, const Value *values, unsigned int count) {
     TRACE_SANITIZE ();
     unsigned int len = get_len ();
 
@@ -168,7 +168,7 @@ struct ValueFormat : USHORT
     if (!has_device ()) return true;
 
     for (unsigned int i = 0; i < count; i++) {
-      if (!sanitize_value_devices (SANITIZE_ARG, base, values))
+      if (!sanitize_value_devices (context, base, values))
         return false;
       values += len;
     }
@@ -177,13 +177,13 @@ struct ValueFormat : USHORT
   }
 
   /* Just sanitize referenced Device tables.  Doesn't check the values themselves. */
-  inline bool sanitize_values_stride_unsafe (SANITIZE_ARG_DEF, void *base, const Value *values, unsigned int count, unsigned int stride) {
+  inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *context, void *base, const Value *values, unsigned int count, unsigned int stride) {
     TRACE_SANITIZE ();
 
     if (!has_device ()) return true;
 
     for (unsigned int i = 0; i < count; i++) {
-      if (!sanitize_value_devices (SANITIZE_ARG, base, values))
+      if (!sanitize_value_devices (context, base, values))
         return false;
       values += stride;
     }
@@ -206,7 +206,7 @@ struct AnchorFormat1
       *y = _hb_16dot16_mul_round (layout_context->font->y_scale, yCoordinate);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -237,7 +237,7 @@ struct AnchorFormat2
       *y = y_ppem && ret ? cy : _hb_16dot16_mul_round (layout_context->font->y_scale, yCoordinate);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -268,7 +268,7 @@ struct AnchorFormat3
 	*y += (this+yDeviceTable).get_delta (layout_context->font->y_ppem) << 16;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ()
 	&& SANITIZE_WITH_BASE (this, xDeviceTable)
@@ -304,13 +304,13 @@ struct Anchor
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
-    case 2: return u.format2->sanitize (SANITIZE_ARG);
-    case 3: return u.format3->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
+    case 2: return u.format2->sanitize (context);
+    case 3: return u.format3->sanitize (context);
     default:return true;
     }
   }
@@ -332,7 +332,7 @@ struct AnchorMatrix
     return this+matrix[row * cols + col];
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF, unsigned int cols) {
+  inline bool sanitize (hb_sanitize_context_t *context, unsigned int cols) {
     TRACE_SANITIZE ();
     if (!SANITIZE_SELF ()) return false;
     if (unlikely (cols >= ((unsigned int) -1) / rows)) return false;
@@ -358,7 +358,7 @@ struct MarkRecord
 
   static inline unsigned int get_size () { return sizeof (MarkRecord); }
 
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base) {
+  inline bool sanitize (hb_sanitize_context_t *context, void *base) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ()
 	&& SANITIZE_WITH_BASE (base, markAnchor);
@@ -402,7 +402,7 @@ struct MarkArray
     return true;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, markRecord);
   }
@@ -434,11 +434,11 @@ struct SinglePosFormat1
     return true;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ()
 	&& SANITIZE_WITH_BASE (this, coverage)
-	&& valueFormat.sanitize_value (SANITIZE_ARG, CharP(this), values);
+	&& valueFormat.sanitize_value (context, CharP(this), values);
   }
 
   private:
@@ -477,11 +477,11 @@ struct SinglePosFormat2
     return true;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ()
 	&& SANITIZE_WITH_BASE (this, coverage)
-	&& valueFormat.sanitize_values (SANITIZE_ARG, CharP(this), values, valueCount);
+	&& valueFormat.sanitize_values (context, CharP(this), values, valueCount);
   }
 
   private:
@@ -512,12 +512,12 @@ struct SinglePos
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
-    case 2: return u.format2->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
+    case 2: return u.format2->sanitize (context);
     default:return true;
     }
   }
@@ -549,7 +549,7 @@ struct PairSet
   friend struct PairPosFormat1;
 
   /* Note: Doesn't sanitize the Device entries in the ValueRecord */
-  inline bool sanitize (SANITIZE_ARG_DEF, unsigned int format_len) {
+  inline bool sanitize (hb_sanitize_context_t *context, unsigned int format_len) {
     TRACE_SANITIZE ();
     if (!SANITIZE_SELF ()) return false;
     unsigned int count = (1 + format_len) * len;
@@ -612,7 +612,7 @@ struct PairPosFormat1
     return false;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
 
     unsigned int len1 = valueFormat1.get_len ();
@@ -620,7 +620,7 @@ struct PairPosFormat1
 
     if (!(SANITIZE_SELF ()
        && SANITIZE_WITH_BASE (this, coverage)
-       && likely (pairSet.sanitize (SANITIZE_ARG, CharP(this), len1 + len2)))) return false;
+       && likely (pairSet.sanitize (context, CharP(this), len1 + len2)))) return false;
 
     if (!(valueFormat1.has_device () || valueFormat2.has_device ())) return true;
 
@@ -632,8 +632,8 @@ struct PairPosFormat1
 
       unsigned int count2 = pair_set.len;
       const PairValueRecord *record = pair_set.array;
-      if (!(valueFormat1.sanitize_values_stride_unsafe (SANITIZE_ARG, CharP(this), &record->values[0], count2, stride) &&
-	    valueFormat2.sanitize_values_stride_unsafe (SANITIZE_ARG, CharP(this), &record->values[len1], count2, stride)))
+      if (!(valueFormat1.sanitize_values_stride_unsafe (context, CharP(this), &record->values[0], count2, stride) &&
+	    valueFormat2.sanitize_values_stride_unsafe (context, CharP(this), &record->values[len1], count2, stride)))
         return false;
     }
 
@@ -701,7 +701,7 @@ struct PairPosFormat2
     return true;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!(SANITIZE_SELF ()
        && SANITIZE_WITH_BASE (this, coverage)
@@ -714,8 +714,8 @@ struct PairPosFormat2
     unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
     unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
     return SANITIZE_ARRAY (values, record_size, count) &&
-	   valueFormat1.sanitize_values_stride_unsafe (SANITIZE_ARG, CharP(this), &values[0], count, stride) &&
-	   valueFormat2.sanitize_values_stride_unsafe (SANITIZE_ARG, CharP(this), &values[len1], count, stride);
+	   valueFormat1.sanitize_values_stride_unsafe (context, CharP(this), &values[0], count, stride) &&
+	   valueFormat2.sanitize_values_stride_unsafe (context, CharP(this), &values[len1], count, stride);
   }
 
   private:
@@ -762,12 +762,12 @@ struct PairPos
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
-    case 2: return u.format2->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
+    case 2: return u.format2->sanitize (context);
     default:return true;
     }
   }
@@ -785,7 +785,7 @@ struct EntryExitRecord
 {
   static inline unsigned int get_size () { return sizeof (EntryExitRecord); }
 
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base) {
+  inline bool sanitize (hb_sanitize_context_t *context, void *base) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (base, entryAnchor)
 	&& SANITIZE_WITH_BASE (base, exitAnchor);
@@ -982,7 +982,7 @@ struct CursivePosFormat1
     return true;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE_WITH_BASE (this, entryExitRecord);
@@ -1013,11 +1013,11 @@ struct CursivePos
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
     default:return true;
     }
   }
@@ -1070,13 +1070,13 @@ struct MarkBasePosFormat1
     return (this+markArray).apply (APPLY_ARG, mark_index, base_index, this+baseArray, classCount, j);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ()
         && SANITIZE_WITH_BASE (this, markCoverage)
 	&& SANITIZE_WITH_BASE (this, baseCoverage)
 	&& SANITIZE_WITH_BASE (this, markArray)
-	&& likely (baseArray.sanitize (SANITIZE_ARG, CharP(this), (unsigned int) classCount));
+	&& likely (baseArray.sanitize (context, CharP(this), (unsigned int) classCount));
   }
 
   private:
@@ -1111,11 +1111,11 @@ struct MarkBasePos
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
     default:return true;
     }
   }
@@ -1194,13 +1194,13 @@ struct MarkLigPosFormat1
     return (this+markArray).apply (APPLY_ARG, mark_index, comp_index, lig_attach, classCount, j);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ()
         && SANITIZE_WITH_BASE (this, markCoverage)
 	&& SANITIZE_WITH_BASE (this, ligatureCoverage)
 	&& SANITIZE_WITH_BASE (this, markArray)
-	&& likely (ligatureArray.sanitize (SANITIZE_ARG, CharP(this), (unsigned int) classCount));
+	&& likely (ligatureArray.sanitize (context, CharP(this), (unsigned int) classCount));
   }
 
   private:
@@ -1236,11 +1236,11 @@ struct MarkLigPos
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
     default:return true;
     }
   }
@@ -1297,13 +1297,13 @@ struct MarkMarkPosFormat1
     return (this+mark1Array).apply (APPLY_ARG, mark1_index, mark2_index, this+mark2Array, classCount, j);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ()
 	&& SANITIZE_WITH_BASE (this, mark1Coverage)
 	&& SANITIZE_WITH_BASE (this, mark2Coverage)
 	&& SANITIZE_WITH_BASE (this, mark1Array)
-	&& likely (mark2Array.sanitize (SANITIZE_ARG, CharP(this), (unsigned int) classCount));
+	&& likely (mark2Array.sanitize (context, CharP(this), (unsigned int) classCount));
   }
 
   private:
@@ -1340,11 +1340,11 @@ struct MarkMarkPos
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
     default:return true;
     }
   }
@@ -1398,7 +1398,7 @@ struct ExtensionPos : Extension
 
   inline bool apply (APPLY_ARG_DEF) const;
 
-  inline bool sanitize (SANITIZE_ARG_DEF);
+  inline bool sanitize (hb_sanitize_context_t *context);
 };
 
 
@@ -1441,19 +1441,19 @@ struct PosLookupSubTable
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case Single:		return u.single->sanitize (SANITIZE_ARG);
-    case Pair:			return u.pair->sanitize (SANITIZE_ARG);
-    case Cursive:		return u.cursive->sanitize (SANITIZE_ARG);
-    case MarkBase:		return u.markBase->sanitize (SANITIZE_ARG);
-    case MarkLig:		return u.markLig->sanitize (SANITIZE_ARG);
-    case MarkMark:		return u.markMark->sanitize (SANITIZE_ARG);
-    case Context:		return u.context->sanitize (SANITIZE_ARG);
-    case ChainContext:		return u.chainContext->sanitize (SANITIZE_ARG);
-    case Extension:		return u.extension->sanitize (SANITIZE_ARG);
+    case Single:		return u.single->sanitize (context);
+    case Pair:			return u.pair->sanitize (context);
+    case Cursive:		return u.cursive->sanitize (context);
+    case MarkBase:		return u.markBase->sanitize (context);
+    case MarkLig:		return u.markLig->sanitize (context);
+    case MarkMark:		return u.markMark->sanitize (context);
+    case Context:		return u.context->sanitize (context);
+    case ChainContext:		return u.chainContext->sanitize (context);
+    case Extension:		return u.extension->sanitize (context);
     default:return true;
     }
   }
@@ -1536,9 +1536,9 @@ struct PosLookup : Lookup
     return ret;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    if (unlikely (!Lookup::sanitize (SANITIZE_ARG))) return false;
+    if (unlikely (!Lookup::sanitize (context))) return false;
     OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable);
     return SANITIZE_WITH_BASE (this, list);
   }
@@ -1564,9 +1564,9 @@ struct GPOS : GSUBGPOS
 			       hb_mask_t     mask) const
   { return get_lookup (lookup_index).apply_string (layout_context, buffer, mask); }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    if (unlikely (!GSUBGPOS::sanitize (SANITIZE_ARG))) return false;
+    if (unlikely (!GSUBGPOS::sanitize (context))) return false;
     OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList);
     return SANITIZE_WITH_BASE (this, list);
   }
@@ -1582,10 +1582,10 @@ inline bool ExtensionPos::apply (APPLY_ARG_DEF) const
   return get_subtable ().apply (APPLY_ARG, get_type ());
 }
 
-inline bool ExtensionPos::sanitize (SANITIZE_ARG_DEF)
+inline bool ExtensionPos::sanitize (hb_sanitize_context_t *context)
 {
   TRACE_SANITIZE ();
-  if (unlikely (!Extension::sanitize (SANITIZE_ARG))) return false;
+  if (unlikely (!Extension::sanitize (context))) return false;
   unsigned int offset = get_offset ();
   if (unlikely (!offset)) return true;
   return SANITIZE (StructAtOffset<PosLookupSubTable> (*this, offset));
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 3632c1f..2dfe7c2 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -54,7 +54,7 @@ struct SingleSubstFormat1
     return true;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE (deltaGlyphID);
@@ -97,7 +97,7 @@ struct SingleSubstFormat2
     return true;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE (substitute);
@@ -130,12 +130,12 @@ struct SingleSubst
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
-    case 2: return u.format2->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
+    case 2: return u.format2->sanitize (context);
     default:return true;
     }
   }
@@ -180,7 +180,7 @@ struct Sequence
   }
 
   public:
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE (substitute);
   }
@@ -208,7 +208,7 @@ struct MultipleSubstFormat1
     return (this+sequence[index]).apply (APPLY_ARG);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE_WITH_BASE (this, sequence);
@@ -240,11 +240,11 @@ struct MultipleSubst
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
     default:return true;
     }
   }
@@ -304,7 +304,7 @@ struct AlternateSubstFormat1
     return true;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE_WITH_BASE (this, alternateSet);
@@ -336,11 +336,11 @@ struct AlternateSubst
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
     default:return true;
     }
   }
@@ -422,7 +422,7 @@ struct Ligature
   }
 
   public:
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE (ligGlyph) && SANITIZE (component);
   }
@@ -456,7 +456,7 @@ struct LigatureSet
   }
 
   public:
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, ligature);
   }
@@ -488,7 +488,7 @@ struct LigatureSubstFormat1
     return lig_set.apply (APPLY_ARG, first_is_mark);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE_WITH_BASE (this, ligatureSet);
@@ -519,11 +519,11 @@ struct LigatureSubst
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
     default:return true;
     }
   }
@@ -579,7 +579,7 @@ struct ExtensionSubst : Extension
 
   inline bool apply (APPLY_ARG_DEF) const;
 
-  inline bool sanitize (SANITIZE_ARG_DEF);
+  inline bool sanitize (hb_sanitize_context_t *context);
 
   inline bool is_reverse (void) const;
 };
@@ -619,7 +619,7 @@ struct ReverseChainSingleSubstFormat1
     return false;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!(SANITIZE_WITH_BASE (this, coverage)
        && SANITIZE_WITH_BASE (this, backtrack)))
@@ -664,11 +664,11 @@ struct ReverseChainSingleSubst
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
     default:return true;
     }
   }
@@ -717,18 +717,18 @@ struct SubstLookupSubTable
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case Single:		return u.single->sanitize (SANITIZE_ARG);
-    case Multiple:		return u.multiple->sanitize (SANITIZE_ARG);
-    case Alternate:		return u.alternate->sanitize (SANITIZE_ARG);
-    case Ligature:		return u.ligature->sanitize (SANITIZE_ARG);
-    case Context:		return u.context->sanitize (SANITIZE_ARG);
-    case ChainContext:		return u.chainContext->sanitize (SANITIZE_ARG);
-    case Extension:		return u.extension->sanitize (SANITIZE_ARG);
-    case ReverseChainSingle:	return u.reverseChainContextSingle->sanitize (SANITIZE_ARG);
+    case Single:		return u.single->sanitize (context);
+    case Multiple:		return u.multiple->sanitize (context);
+    case Alternate:		return u.alternate->sanitize (context);
+    case Ligature:		return u.ligature->sanitize (context);
+    case Context:		return u.context->sanitize (context);
+    case ChainContext:		return u.chainContext->sanitize (context);
+    case Extension:		return u.extension->sanitize (context);
+    case ReverseChainSingle:	return u.reverseChainContextSingle->sanitize (context);
     default:return true;
     }
   }
@@ -847,9 +847,9 @@ struct SubstLookup : Lookup
     return ret;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    if (unlikely (!Lookup::sanitize (SANITIZE_ARG))) return false;
+    if (unlikely (!Lookup::sanitize (context))) return false;
     OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable);
     return SANITIZE_WITH_BASE (this, list);
   }
@@ -876,9 +876,9 @@ struct GSUB : GSUBGPOS
   { return get_lookup (lookup_index).apply_string (layout_context, buffer, mask); }
 
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
-    if (unlikely (!GSUBGPOS::sanitize (SANITIZE_ARG))) return false;
+    if (unlikely (!GSUBGPOS::sanitize (context))) return false;
     OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList);
     return SANITIZE_WITH_BASE (this, list);
   }
@@ -894,10 +894,10 @@ inline bool ExtensionSubst::apply (APPLY_ARG_DEF) const
   return get_subtable ().apply (APPLY_ARG, get_type ());
 }
 
-inline bool ExtensionSubst::sanitize (SANITIZE_ARG_DEF)
+inline bool ExtensionSubst::sanitize (hb_sanitize_context_t *context)
 {
   TRACE_SANITIZE ();
-  if (unlikely (!Extension::sanitize (SANITIZE_ARG))) return false;
+  if (unlikely (!Extension::sanitize (context))) return false;
   unsigned int offset = get_offset ();
   if (unlikely (!offset)) return true;
   return SANITIZE (StructAtOffset<SubstLookupSubTable> (*this, offset));
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index c3a622b..71fe8a6 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -179,7 +179,7 @@ struct LookupRecord
 {
   static inline unsigned int get_size () { return sizeof (LookupRecord); }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -289,7 +289,7 @@ struct Rule
   }
 
   public:
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!(SANITIZE (inputCount) && SANITIZE (lookupCount))) return false;
     return SANITIZE_MEM (input,
@@ -324,7 +324,7 @@ struct RuleSet
     return false;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, rule);
   }
@@ -356,7 +356,7 @@ struct ContextFormat1
     return rule_set.apply (APPLY_ARG, lookup_context);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE_WITH_BASE (this, ruleSet);
@@ -399,7 +399,7 @@ struct ContextFormat2
     return rule_set.apply (APPLY_ARG, lookup_context);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
         && SANITIZE_WITH_BASE (this, classDef)
@@ -444,7 +444,7 @@ struct ContextFormat3
 			   lookup_context);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE_SELF ()) return false;
     unsigned int count = glyphCount;
@@ -482,13 +482,13 @@ struct Context
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
-    case 2: return u.format2->sanitize (SANITIZE_ARG);
-    case 3: return u.format3->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
+    case 2: return u.format2->sanitize (context);
+    case 3: return u.format3->sanitize (context);
     default:return true;
     }
   }
@@ -568,7 +568,7 @@ struct ChainRule
   }
 
   public:
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (backtrack)) return false;
     HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
@@ -611,7 +611,7 @@ struct ChainRuleSet
     return false;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, rule);
   }
@@ -643,7 +643,7 @@ struct ChainContextFormat1
     return rule_set.apply (APPLY_ARG, lookup_context);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE_WITH_BASE (this, ruleSet);
@@ -690,7 +690,7 @@ struct ChainContextFormat2
     return rule_set.apply (APPLY_ARG, lookup_context);
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_WITH_BASE (this, coverage)
 	&& SANITIZE_WITH_BASE (this, backtrackClassDef)
@@ -752,7 +752,7 @@ struct ChainContextFormat3
     return false;
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE_WITH_BASE (this, backtrack)) return false;
     OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
@@ -797,13 +797,13 @@ struct ChainContext
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
-    case 2: return u.format2->sanitize (SANITIZE_ARG);
-    case 3: return u.format3->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
+    case 2: return u.format2->sanitize (context);
+    case 3: return u.format3->sanitize (context);
     default:return true;
     }
   }
@@ -826,7 +826,7 @@ struct ExtensionFormat1
   inline unsigned int get_type (void) const { return extensionLookupType; }
   inline unsigned int get_offset (void) const { return extensionOffset; }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE_SELF ();
   }
@@ -858,11 +858,11 @@ struct Extension
     }
   }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     if (!SANITIZE (u.format)) return false;
     switch (u.format) {
-    case 1: return u.format1->sanitize (SANITIZE_ARG);
+    case 1: return u.format1->sanitize (context);
     default:return true;
     }
   }
@@ -915,7 +915,7 @@ struct GSUBGPOS
   inline const Lookup& get_lookup (unsigned int i) const
   { return (this+lookupList)[i]; }
 
-  inline bool sanitize (SANITIZE_ARG_DEF) {
+  inline bool sanitize (hb_sanitize_context_t *context) {
     TRACE_SANITIZE ();
     return SANITIZE (version) && likely (version.major == 1)
 	&& SANITIZE_WITH_BASE (this, scriptList)
commit b261e2ad5c5a065599ce1dbc4ba437caa2cee1e9
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 00:20:16 2010 -0400

    Remove trace from sanitize_shallow()

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 5dbf89d..2a0dccb 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -637,7 +637,6 @@ struct HeadlessArrayOf
   { return len.get_size () + (len ? len - 1 : 0) * Type::get_size (); }
 
   inline bool sanitize_shallow (SANITIZE_ARG_DEF) {
-    TRACE_SANITIZE ();
     return SANITIZE_SELF() && SANITIZE_ARRAY (this, Type::get_size (), len);
   }
 
commit dfc8cbe85479dde1ffdc6b2e73f4907331d77a19
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 5 00:19:46 2010 -0400

    Add hb_trace_t

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index dcaea21..5dbf89d 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -113,22 +113,28 @@ ASSERT_STATIC (sizeof (Type) + 1 <= sizeof (_Null##Type))
 
 
 /*
- * Debug
+ * Trace
  */
 
-/* Helper object to increment debug_depth and decrement
- * when returning from the object. */
-template <int debug_level>
-struct hb_auto_debug_depth_t {
-  explicit hb_auto_debug_depth_t (unsigned int *p) : p(p) { ++*p; }
-  ~hb_auto_debug_depth_t (void) { --*p; }
+
+template <int max_depth>
+struct hb_trace_t {
+  explicit hb_trace_t (unsigned int *pdepth) : pdepth(pdepth) { if (max_depth) ++*pdepth; }
+  ~hb_trace_t (void) { if (max_depth) --*pdepth; }
+
+  inline void log (const char *what, const char *function, const void *obj)
+  {
+    if (*pdepth < max_depth)
+      fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, *pdepth, *pdepth, function);
+  }
 
   private:
-  unsigned int *p;
+  unsigned int *pdepth;
 };
-template <> /* Optimize when debugging is disabled */
-struct hb_auto_debug_depth_t<0> {
-  explicit hb_auto_debug_depth_t (unsigned int *p) {}
+template <> /* Optimize when tracing is disabled */
+struct hb_trace_t<0> {
+  explicit hb_trace_t (unsigned int *p) {}
+  inline void log (const char *what, const char *function, const void *obj) {};
 };
 
 
@@ -143,9 +149,8 @@ struct hb_auto_debug_depth_t<0> {
 
 
 #define TRACE_SANITIZE() \
-	hb_auto_debug_depth_t<HB_DEBUG_SANITIZE> auto_debug_depth (&context->debug_depth); \
-	if (HB_DEBUG_SANITIZE) \
-	  _hb_trace ("SANITIZE", HB_FUNC, this, context->debug_depth, HB_DEBUG_SANITIZE); \
+	hb_trace_t<HB_DEBUG_SANITIZE> trace (&context->debug_depth); \
+	trace.log ("SANITIZE", HB_FUNC, this);
 
 
 #define SANITIZE_ARG_DEF \
commit 20e3dd5d292b65f70d2eae63b8d8713a1c889d47
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue May 4 23:21:57 2010 -0400

    Make sanitize_depth variable automatic and not passed through function args

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 72dd3c8..dcaea21 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -112,6 +112,26 @@ ASSERT_STATIC (sizeof (Type) + 1 <= sizeof (_Null##Type))
 #define Null(Type) Null<Type>()
 
 
+/*
+ * Debug
+ */
+
+/* Helper object to increment debug_depth and decrement
+ * when returning from the object. */
+template <int debug_level>
+struct hb_auto_debug_depth_t {
+  explicit hb_auto_debug_depth_t (unsigned int *p) : p(p) { ++*p; }
+  ~hb_auto_debug_depth_t (void) { --*p; }
+
+  private:
+  unsigned int *p;
+};
+template <> /* Optimize when debugging is disabled */
+struct hb_auto_debug_depth_t<0> {
+  explicit hb_auto_debug_depth_t (unsigned int *p) {}
+};
+
+
 
 /*
  * Sanitize
@@ -121,19 +141,17 @@ ASSERT_STATIC (sizeof (Type) + 1 <= sizeof (_Null##Type))
 #define HB_DEBUG_SANITIZE HB_DEBUG+0
 #endif
 
+
 #define TRACE_SANITIZE() \
-	HB_STMT_START { \
-	  if (HB_DEBUG_SANITIZE) \
-		  _hb_trace ("SANITIZE", HB_FUNC, this, sanitize_depth, HB_DEBUG_SANITIZE); \
-	} HB_STMT_END
+	hb_auto_debug_depth_t<HB_DEBUG_SANITIZE> auto_debug_depth (&context->debug_depth); \
+	if (HB_DEBUG_SANITIZE) \
+	  _hb_trace ("SANITIZE", HB_FUNC, this, context->debug_depth, HB_DEBUG_SANITIZE); \
 
 
 #define SANITIZE_ARG_DEF \
-	hb_sanitize_context_t *context, \
-	unsigned int sanitize_depth HB_UNUSED
+	hb_sanitize_context_t *context
 #define SANITIZE_ARG \
-	context, \
-	(HB_DEBUG_SANITIZE ? sanitize_depth + 1 : 0)
+	context
 
 struct hb_sanitize_context_t
 {
@@ -144,6 +162,7 @@ struct hb_sanitize_context_t
     this->end = this->start + hb_blob_get_length (blob);
     this->writable = hb_blob_is_writable (blob);
     this->edit_count = 0;
+    this->debug_depth = 0;
 
     if (HB_DEBUG_SANITIZE)
       fprintf (stderr, "sanitize %p init [%p..%p] (%u bytes)\n",
@@ -162,18 +181,16 @@ struct hb_sanitize_context_t
     this->start = this->end = NULL;
   }
 
-  inline bool check (unsigned int sanitize_depth,
-		     const char *base,
-		     unsigned int len) const
+  inline bool check (const char *base, unsigned int len) const
   {
     bool ret = this->start <= base &&
 	       base <= this->end &&
 	       (unsigned int) (this->end - base) >= len;
 
-    if (HB_DEBUG_SANITIZE && (int) sanitize_depth < (int) HB_DEBUG_SANITIZE) \
+    if (HB_DEBUG_SANITIZE && (int) this->debug_depth < (int) HB_DEBUG_SANITIZE) \
       fprintf (stderr, "SANITIZE(%p) %-*d-> check [%p..%p] (%d bytes) in [%p..%p] -> %s\n", \
 	       base,
-	       sanitize_depth, sanitize_depth,
+	       this->debug_depth, this->debug_depth,
 	       base, base+len, len,
 	       this->start, this->end,
 	       ret ? "pass" : "FAIL");
@@ -181,35 +198,30 @@ struct hb_sanitize_context_t
     return ret;
   }
 
-  inline bool check_array (unsigned int sanitize_depth,
-			   const char *base,
-			   unsigned int record_size,
-			   unsigned int len) const
+  inline bool check_array (const char *base, unsigned int record_size, unsigned int len) const
   {
     bool overflows = len >= ((unsigned int) -1) / record_size;
 
 
-    if (HB_DEBUG_SANITIZE && (int) sanitize_depth < (int) HB_DEBUG_SANITIZE)
+    if (HB_DEBUG_SANITIZE && (int) this->debug_depth < (int) HB_DEBUG_SANITIZE)
       fprintf (stderr, "SANITIZE(%p) %-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s\n", \
 	       base,
-	       sanitize_depth, sanitize_depth,
+	       this->debug_depth, this->debug_depth,
 	       base, base + (record_size * len), record_size, len, (unsigned long) record_size * len,
 	       this->start, this->end,
 	       !overflows ? "does not overflow" : "OVERFLOWS FAIL");
 
-    return likely (!overflows) && this->check (sanitize_depth, base, record_size * len);
+    return likely (!overflows) && this->check (base, record_size * len);
   }
 
-  inline bool can_edit (unsigned int sanitize_depth,
-			const char *base HB_UNUSED,
-			unsigned int len HB_UNUSED)
+  inline bool can_edit (const char *base HB_UNUSED, unsigned int len HB_UNUSED)
   {
     this->edit_count++;
 
-    if (HB_DEBUG_SANITIZE && (int) sanitize_depth < (int) HB_DEBUG_SANITIZE)
+    if (HB_DEBUG_SANITIZE && (int) this->debug_depth < (int) HB_DEBUG_SANITIZE)
       fprintf (stderr, "SANITIZE(%p) %-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s\n", \
 	       base,
-	       sanitize_depth, sanitize_depth,
+	       this->debug_depth, this->debug_depth,
 	       this->edit_count,
 	       base, base+len, len,
 	       this->start, this->end,
@@ -225,6 +237,9 @@ struct hb_sanitize_context_t
 
   inline void reset_edit_count (void) { this->edit_count = 0; }
 
+  public:
+  unsigned int debug_depth;
+
   private:
   const char *start, *end;
   bool writable;
@@ -239,9 +254,9 @@ struct hb_sanitize_context_t
 
 #define SANITIZE_SELF() SANITIZE_MEM(this, sizeof (*this))
 
-#define SANITIZE_MEM(B,L) likely (context->check (sanitize_depth, CharP(B), (L)))
+#define SANITIZE_MEM(B,L) likely (context->check (CharP(B), (L)))
 
-#define SANITIZE_ARRAY(A,S,L) likely (context->check_array (sanitize_depth, CharP(A), S, L))
+#define SANITIZE_ARRAY(A,S,L) likely (context->check_array (CharP(A), S, L))
 
 
 /* Template to sanitize an object. */
@@ -250,7 +265,6 @@ struct Sanitizer
 {
   static hb_blob_t *sanitize (hb_blob_t *blob) {
     hb_sanitize_context_t context[1];
-    unsigned int sanitize_depth = 0;
     bool sane;
 
     /* TODO is_sane() stuff */
@@ -464,7 +478,7 @@ struct GenericOffsetTo : OffsetType
   private:
   /* Set the offset to Null */
   inline bool neuter (SANITIZE_ARG_DEF) {
-    if (context->can_edit (sanitize_depth, CharP(this), this->get_size ())) {
+    if (context->can_edit (CharP(this), this->get_size ())) {
       this->set (0); /* 0 is Null offset */
       return true;
     }
commit 4a446ac35136eff23d55f47bdd7b40095ad707ab
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue May 4 22:46:21 2010 -0400

    Use function template for pass-thru argument

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index a240fdb..72dd3c8 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -451,15 +451,8 @@ struct GenericOffsetTo : OffsetType
     Type &obj = StructAtOffset<Type> (*CharP(base), offset);
     return likely (obj.sanitize (SANITIZE_ARG)) || neuter (SANITIZE_ARG);
   }
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base, void *base2) {
-    TRACE_SANITIZE ();
-    if (!SANITIZE_SELF ()) return false;
-    unsigned int offset = *this;
-    if (unlikely (!offset)) return true;
-    Type &obj = StructAtOffset<Type> (*CharP(base), offset);
-    return likely (obj.sanitize (SANITIZE_ARG, base2)) || neuter (SANITIZE_ARG);
-  }
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base, unsigned int user_data) {
+  template <typename T>
+  inline bool sanitize (SANITIZE_ARG_DEF, void *base, T user_data) {
     TRACE_SANITIZE ();
     if (!SANITIZE_SELF ()) return false;
     unsigned int offset = *this;
@@ -544,16 +537,8 @@ struct GenericArrayOf
         return false;
     return true;
   }
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base, void *base2) {
-    TRACE_SANITIZE ();
-    if (!likely (sanitize_shallow (SANITIZE_ARG))) return false;
-    unsigned int count = len;
-    for (unsigned int i = 0; i < count; i++)
-      if (!array()[i].sanitize (SANITIZE_ARG, base, base2))
-        return false;
-    return true;
-  }
-  inline bool sanitize (SANITIZE_ARG_DEF, void *base, unsigned int user_data) {
+  template <typename T>
+  inline bool sanitize (SANITIZE_ARG_DEF, void *base, T user_data) {
     TRACE_SANITIZE ();
     if (!likely (sanitize_shallow (SANITIZE_ARG))) return false;
     unsigned int count = len;
@@ -608,7 +593,8 @@ struct OffsetListOf : OffsetArrayOf<Type>
     TRACE_SANITIZE ();
     return OffsetArrayOf<Type>::sanitize (SANITIZE_ARG, CharP(this));
   }
-  inline bool sanitize (SANITIZE_ARG_DEF, unsigned int user_data) {
+  template <typename T>
+  inline bool sanitize (SANITIZE_ARG_DEF, T user_data) {
     TRACE_SANITIZE ();
     return OffsetArrayOf<Type>::sanitize (SANITIZE_ARG, CharP(this), user_data);
   }
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 5f38751..9837c04 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -1076,7 +1076,7 @@ struct MarkBasePosFormat1
         && SANITIZE_WITH_BASE (this, markCoverage)
 	&& SANITIZE_WITH_BASE (this, baseCoverage)
 	&& SANITIZE_WITH_BASE (this, markArray)
-	&& likely (baseArray.sanitize (SANITIZE_ARG, CharP(this), classCount));
+	&& likely (baseArray.sanitize (SANITIZE_ARG, CharP(this), (unsigned int) classCount));
   }
 
   private:
@@ -1200,7 +1200,7 @@ struct MarkLigPosFormat1
         && SANITIZE_WITH_BASE (this, markCoverage)
 	&& SANITIZE_WITH_BASE (this, ligatureCoverage)
 	&& SANITIZE_WITH_BASE (this, markArray)
-	&& likely (ligatureArray.sanitize (SANITIZE_ARG, CharP(this), classCount));
+	&& likely (ligatureArray.sanitize (SANITIZE_ARG, CharP(this), (unsigned int) classCount));
   }
 
   private:
@@ -1303,7 +1303,7 @@ struct MarkMarkPosFormat1
 	&& SANITIZE_WITH_BASE (this, mark1Coverage)
 	&& SANITIZE_WITH_BASE (this, mark2Coverage)
 	&& SANITIZE_WITH_BASE (this, mark1Array)
-	&& likely (mark2Array.sanitize (SANITIZE_ARG, CharP(this), classCount));
+	&& likely (mark2Array.sanitize (SANITIZE_ARG, CharP(this), (unsigned int) classCount));
   }
 
   private:
commit 98daaf183d6dbf2b68959da608cd9876ba55d7aa
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue May 4 22:42:49 2010 -0400

    Make _hb_sanitize_*() methods of the context object

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 75a539b..a240fdb 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -137,95 +137,101 @@ ASSERT_STATIC (sizeof (Type) + 1 <= sizeof (_Null##Type))
 
 struct hb_sanitize_context_t
 {
-  const char *start, *end;
-  hb_bool_t writable;
-  unsigned int edit_count;
-};
+  inline void init (hb_blob_t *blob)
+  {
+    this->blob = hb_blob_reference (blob);
+    this->start = hb_blob_lock (blob);
+    this->end = this->start + hb_blob_get_length (blob);
+    this->writable = hb_blob_is_writable (blob);
+    this->edit_count = 0;
 
+    if (HB_DEBUG_SANITIZE)
+      fprintf (stderr, "sanitize %p init [%p..%p] (%u bytes)\n",
+	       this->blob, this->start, this->end, this->end - this->start);
+  }
 
-static inline void
-_hb_sanitize_init (hb_sanitize_context_t *context,
-		   hb_blob_t *blob)
-{
-  context->start = hb_blob_lock (blob);
-  context->end = context->start + hb_blob_get_length (blob);
-  context->writable = hb_blob_is_writable (blob);
-  context->edit_count = 0;
-
-  if (HB_DEBUG_SANITIZE)
-    fprintf (stderr, "sanitize %p init [%p..%p] (%u bytes)\n",
-	     blob, context->start, context->end, context->end - context->start);
-}
+  inline void finish (void)
+  {
+    if (HB_DEBUG_SANITIZE)
+      fprintf (stderr, "sanitize %p fini [%p..%p] %u edit requests\n",
+	       this->blob, this->start, this->end, this->edit_count);
 
-static inline void
-_hb_sanitize_fini (hb_sanitize_context_t *context HB_UNUSED,
-		   hb_blob_t *blob)
-{
-  if (HB_DEBUG_SANITIZE)
-    fprintf (stderr, "sanitize %p fini [%p..%p] %u edit requests\n",
-	     blob, context->start, context->end, context->edit_count);
+    hb_blob_unlock (this->blob);
+    hb_blob_destroy (this->blob);
+    this->blob = NULL;
+    this->start = this->end = NULL;
+  }
 
-  hb_blob_unlock (blob);
-}
+  inline bool check (unsigned int sanitize_depth,
+		     const char *base,
+		     unsigned int len) const
+  {
+    bool ret = this->start <= base &&
+	       base <= this->end &&
+	       (unsigned int) (this->end - base) >= len;
+
+    if (HB_DEBUG_SANITIZE && (int) sanitize_depth < (int) HB_DEBUG_SANITIZE) \
+      fprintf (stderr, "SANITIZE(%p) %-*d-> check [%p..%p] (%d bytes) in [%p..%p] -> %s\n", \
+	       base,
+	       sanitize_depth, sanitize_depth,
+	       base, base+len, len,
+	       this->start, this->end,
+	       ret ? "pass" : "FAIL");
+
+    return ret;
+  }
 
-static inline bool
-_hb_sanitize_check (SANITIZE_ARG_DEF,
-		    const char *base,
-		    unsigned int len)
-{
-  bool ret = context->start <= base &&
-	     base <= context->end &&
-	     (unsigned int) (context->end - base) >= len;
-
-  if (HB_DEBUG_SANITIZE && (int) sanitize_depth < (int) HB_DEBUG_SANITIZE) \
-    fprintf (stderr, "SANITIZE(%p) %-*d-> check [%p..%p] (%d bytes) in [%p..%p] -> %s\n", \
-	     base,
-	     sanitize_depth, sanitize_depth,
-	     base, base+len, len,
-	     context->start, context->end,
-	     ret ? "pass" : "FAIL");
-
-  return ret;
-}
+  inline bool check_array (unsigned int sanitize_depth,
+			   const char *base,
+			   unsigned int record_size,
+			   unsigned int len) const
+  {
+    bool overflows = len >= ((unsigned int) -1) / record_size;
 
-static inline bool
-_hb_sanitize_array (SANITIZE_ARG_DEF,
-		    const char *base,
-		    unsigned int record_size,
-		    unsigned int len)
-{
-  bool overflows = len >= ((unsigned int) -1) / record_size;
 
+    if (HB_DEBUG_SANITIZE && (int) sanitize_depth < (int) HB_DEBUG_SANITIZE)
+      fprintf (stderr, "SANITIZE(%p) %-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s\n", \
+	       base,
+	       sanitize_depth, sanitize_depth,
+	       base, base + (record_size * len), record_size, len, (unsigned long) record_size * len,
+	       this->start, this->end,
+	       !overflows ? "does not overflow" : "OVERFLOWS FAIL");
 
-  if (HB_DEBUG_SANITIZE && (int) sanitize_depth < (int) HB_DEBUG_SANITIZE)
-    fprintf (stderr, "SANITIZE(%p) %-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s\n", \
-	     base,
-	     sanitize_depth, sanitize_depth,
-	     base, base + (record_size * len), record_size, len, (unsigned long) record_size * len,
-	     context->start, context->end,
-	     !overflows ? "does not overflow" : "OVERFLOWS FAIL");
+    return likely (!overflows) && this->check (sanitize_depth, base, record_size * len);
+  }
 
-  return likely (!overflows) && _hb_sanitize_check (SANITIZE_ARG, base, record_size * len);
-}
+  inline bool can_edit (unsigned int sanitize_depth,
+			const char *base HB_UNUSED,
+			unsigned int len HB_UNUSED)
+  {
+    this->edit_count++;
+
+    if (HB_DEBUG_SANITIZE && (int) sanitize_depth < (int) HB_DEBUG_SANITIZE)
+      fprintf (stderr, "SANITIZE(%p) %-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s\n", \
+	       base,
+	       sanitize_depth, sanitize_depth,
+	       this->edit_count,
+	       base, base+len, len,
+	       this->start, this->end,
+	       this->writable ? "granted" : "REJECTED");
+
+    return this->writable;
+  }
+
+  inline const char *get_start (void) const { return start; }
+  inline const char *get_end (void) const { return end; }
+  inline bool is_writable (void) const { return writable; }
+  inline unsigned int get_edit_count (void) const { return this->edit_count; }
+
+  inline void reset_edit_count (void) { this->edit_count = 0; }
+
+  private:
+  const char *start, *end;
+  bool writable;
+  unsigned int edit_count;
+  hb_blob_t *blob;
+};
 
-static inline bool
-_hb_sanitize_edit (SANITIZE_ARG_DEF,
-		   const char *base HB_UNUSED,
-		   unsigned int len HB_UNUSED)
-{
-  context->edit_count++;
-
-  if (HB_DEBUG_SANITIZE && (int) sanitize_depth < (int) HB_DEBUG_SANITIZE)
-    fprintf (stderr, "SANITIZE(%p) %-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s\n", \
-	     base,
-	     sanitize_depth, sanitize_depth,
-	     context->edit_count,
-	     base, base+len, len,
-	     context->start, context->end,
-	     context->writable ? "granted" : "REJECTED");
-
-  return context->writable;
-}
 
 #define SANITIZE(X) likely ((X).sanitize (SANITIZE_ARG))
 
@@ -233,9 +239,9 @@ _hb_sanitize_edit (SANITIZE_ARG_DEF,
 
 #define SANITIZE_SELF() SANITIZE_MEM(this, sizeof (*this))
 
-#define SANITIZE_MEM(B,L) likely (_hb_sanitize_check (SANITIZE_ARG, CharP(B), (L)))
+#define SANITIZE_MEM(B,L) likely (context->check (sanitize_depth, CharP(B), (L)))
 
-#define SANITIZE_ARRAY(A,S,L) likely (_hb_sanitize_array (SANITIZE_ARG, CharP(A), S, L))
+#define SANITIZE_ARRAY(A,S,L) likely (context->check_array (sanitize_depth, CharP(A), S, L))
 
 
 /* Template to sanitize an object. */
@@ -253,31 +259,31 @@ struct Sanitizer
     if (HB_DEBUG_SANITIZE)
       fprintf (stderr, "Sanitizer %p start %s\n", blob, HB_FUNC);
 
-    _hb_sanitize_init (context, blob);
+    context->init (blob);
 
-    Type *t = CastP<Type> (const_cast<char *> (context->start));
+    Type *t = CastP<Type> (const_cast<char *> (context->get_start ()));
 
     sane = t->sanitize (SANITIZE_ARG);
     if (sane) {
-      if (context->edit_count) {
+      if (context->get_edit_count ()) {
 	if (HB_DEBUG_SANITIZE)
 	  fprintf (stderr, "Sanitizer %p passed first round with %d edits; doing a second round %s\n",
-		   blob, context->edit_count, HB_FUNC);
+		   blob, context->get_edit_count (), HB_FUNC);
 
         /* sanitize again to ensure no toe-stepping */
-        context->edit_count = 0;
+        context->reset_edit_count ();
 	sane = t->sanitize (SANITIZE_ARG);
-	if (context->edit_count) {
+	if (context->get_edit_count ()) {
 	  if (HB_DEBUG_SANITIZE)
 	    fprintf (stderr, "Sanitizer %p requested %d edits in second round; FAILLING %s\n",
-		     blob, context->edit_count, HB_FUNC);
+		     blob, context->get_edit_count (), HB_FUNC);
 	  sane = false;
 	}
       }
-      _hb_sanitize_fini (context, blob);
+      context->finish ();
     } else {
-      unsigned int edit_count = context->edit_count;
-      _hb_sanitize_fini (context, blob);
+      unsigned int edit_count = context->get_edit_count ();
+      context->finish ();
       if (edit_count && !hb_blob_is_writable (blob) && hb_blob_try_writable (blob)) {
         /* ok, we made it writable by relocating.  try again */
 	if (HB_DEBUG_SANITIZE)
@@ -465,7 +471,7 @@ struct GenericOffsetTo : OffsetType
   private:
   /* Set the offset to Null */
   inline bool neuter (SANITIZE_ARG_DEF) {
-    if (_hb_sanitize_edit (SANITIZE_ARG, CharP(this), this->get_size ())) {
+    if (context->can_edit (sanitize_depth, CharP(this), this->get_size ())) {
       this->set (0); /* 0 is Null offset */
       return true;
     }



More information about the HarfBuzz mailing list