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

Behdad Esfahbod behdad at kemper.freedesktop.org
Mon Jul 25 17:41:49 PDT 2011


 src/hb-blob.cc                       |   35 ++++-------
 src/hb-buffer-private.hh             |   25 +++++++-
 src/hb-buffer.cc                     |   36 +++++++++--
 src/hb-object-private.hh             |    9 +-
 src/hb-open-type-private.hh          |   97 ++++++++++---------------------
 src/hb-ot-layout-gsub-private.hh     |    6 -
 src/hb-ot-layout-gsubgpos-private.hh |   14 +++-
 src/hb-ot-layout.cc                  |    1 
 src/hb-ot-shape.cc                   |   95 +++++++++++++-----------------
 src/hb-private.hh                    |  109 ++++++++++++++++++++++++++++++++---
 10 files changed, 256 insertions(+), 171 deletions(-)

New commits:
commit cc06c243d8be3ebb1190281653d2dba504c16c0f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Jul 25 20:25:44 2011 -0400

    Streamline debugging infrastructure even more

diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index f6537cd..2d0c016 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -243,27 +243,27 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
 #endif
 
   if ((uintptr_t) -1L == pagesize) {
-    DEBUG_MSG (BLOB, "%p %s: failed to get pagesize: %s\n", (void *) blob, HB_FUNC, strerror (errno));
+    DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno));
     return FALSE;
   }
-  DEBUG_MSG (BLOB, "%p %s: pagesize is %lu\n", (void *) blob, HB_FUNC, (unsigned long) pagesize);
+  DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize);
 
   mask = ~(pagesize-1);
   addr = (const char *) (((uintptr_t) blob->data) & mask);
   length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask)  - addr;
-  DEBUG_MSG (BLOB, "%p %s: calling mprotect on [%p..%p] (%lu bytes)\n",
-		   (void *) blob, HB_FUNC,
-		   addr, addr+length, (unsigned long) length);
+  DEBUG_MSG_FUNC (BLOB, blob,
+		  "calling mprotect on [%p..%p] (%lu bytes)",
+		  addr, addr+length, (unsigned long) length);
   if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
-    DEBUG_MSG (BLOB, "%p %s: %s\n", (void *) blob, HB_FUNC, strerror (errno));
+    DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno));
     return FALSE;
   }
 
   blob->mode = HB_MEMORY_MODE_WRITABLE;
 
-  DEBUG_MSG (BLOB, "%p %s: successfully made [%p..%p] (%lu bytes) writable\n",
-		   (void *) blob, HB_FUNC,
-		   addr, addr+length, (unsigned long) length);
+  DEBUG_MSG_FUNC (BLOB, blob,
+		  "successfully made [%p..%p] (%lu bytes) writable\n",
+		  addr, addr+length, (unsigned long) length);
   return TRUE;
 #else
   return FALSE;
@@ -273,12 +273,12 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
 static bool
 _try_writable_inplace (hb_blob_t *blob)
 {
-  DEBUG_MSG (BLOB, "%p %s: making writable inplace\n", (void *) blob, HB_FUNC);
+  DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n");
 
   if (_try_make_writable_inplace_unix (blob))
     return TRUE;
 
-  DEBUG_MSG (BLOB, "%p %s: making writable -> FAILED\n", (void *) blob, HB_FUNC);
+  DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n");
 
   /* Failed to make writable inplace, mark that */
   blob->mode = HB_MEMORY_MODE_READONLY;
@@ -301,7 +301,7 @@ _try_writable (hb_blob_t *blob)
     return TRUE;
 
 
-  DEBUG_MSG (BLOB, "%p %s -> %p\n", (void *) blob, HB_FUNC, blob->data);
+  DEBUG_MSG_FUNC (BLOB, blob, "currect data is -> %p\n", blob->data);
 
   char *new_data;
 
@@ -309,7 +309,7 @@ _try_writable (hb_blob_t *blob)
   if (unlikely (!new_data))
     return FALSE;
 
-  DEBUG_MSG (BLOB, "%p %s: dupped successfully -> %p\n", (void *) blob, HB_FUNC, blob->data);
+  DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data);
 
   memcpy (new_data, blob->data, blob->length);
   _hb_blob_destroy_user_data (blob);
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 37b4703..1b25443 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -191,10 +191,10 @@ struct _hb_object_header_t {
   }
 
   inline void trace (const char *function) const {
-    DEBUG_MSG (OBJECT, "OBJECT(%p) refcount=%d %s\n",
-		       (void *) this,
-		       this ? ref_count.get () : 0,
-		       function);
+    DEBUG_MSG (OBJECT, (void *) this,
+	       "refcount=%d %s",
+	       this ? ref_count.get () : 0,
+	       function);
   }
 
 };
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index b20e5ca..ab2a346 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -144,29 +144,6 @@ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
 #define Null(Type) Null<Type>()
 
 
-/*
- * Trace
- */
-
-
-template <int max_depth>
-struct hb_trace_t {
-  explicit hb_trace_t (unsigned int *pdepth_, const char *what, const char *function, const void *obj) : pdepth(pdepth_) {
-    (void) (*pdepth < max_depth &&
-	    fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, *pdepth, *pdepth, function));
-    if (max_depth) ++*pdepth;
-  }
-  ~hb_trace_t (void) { if (max_depth) --*pdepth; }
-
-  private:
-  unsigned int *pdepth;
-};
-template <> /* Optimize when tracing is disabled */
-struct hb_trace_t<0> {
-  explicit hb_trace_t (unsigned int *pdepth HB_UNUSED, const char *what HB_UNUSED, const char *function HB_UNUSED, const void *obj HB_UNUSED) {}
-};
-
-
 
 /*
  * Sanitize
@@ -178,7 +155,7 @@ struct hb_trace_t<0> {
 
 
 #define TRACE_SANITIZE() \
-	hb_trace_t<HB_DEBUG_SANITIZE> trace (&c->debug_depth, "SANITIZE", HB_FUNC, this); \
+	hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&c->debug_depth, "SANITIZE", this, NULL, HB_FUNC);
 
 
 struct hb_sanitize_context_t
@@ -196,15 +173,17 @@ struct hb_sanitize_context_t
     this->edit_count = 0;
     this->debug_depth = 0;
 
-    DEBUG_MSG (SANITIZE, "sanitize %p init [%p..%p] (%lu bytes)\n",
-			 (void *) this->blob, this->start, this->end,
-			 (unsigned long) (this->end - this->start));
+    DEBUG_MSG (SANITIZE, this->blob,
+	       "init [%p..%p] (%lu bytes)",
+	       this->start, this->end,
+	       (unsigned long) (this->end - this->start));
   }
 
   inline void finish (void)
   {
-    DEBUG_MSG (SANITIZE, "sanitize %p fini [%p..%p] %u edit requests\n",
-			 (void *) this->blob, this->start, this->end, this->edit_count);
+    DEBUG_MSG (SANITIZE, this->blob,
+	       "fini [%p..%p] %u edit requests",
+	       this->start, this->end, this->edit_count);
 
     hb_blob_destroy (this->blob);
     this->blob = NULL;
@@ -218,9 +197,8 @@ struct hb_sanitize_context_t
 	       p <= this->end &&
 	       (unsigned int) (this->end - p) >= len;
 
-    DEBUG_MSG_LEVEL (SANITIZE, this->debug_depth,
-		     "SANITIZE(%p) %-*d-> range [%p..%p] (%d bytes) in [%p..%p] -> %s\n",
-		     p,
+    DEBUG_MSG_LEVEL (SANITIZE, this->blob, this->debug_depth,
+		     "%-*d-> range [%p..%p] (%d bytes) in [%p..%p] -> %s",
 		     this->debug_depth, this->debug_depth,
 		     p, p + len, len,
 		     this->start, this->end,
@@ -234,9 +212,8 @@ struct hb_sanitize_context_t
     const char *p = (const char *) base;
     bool overflows = _hb_unsigned_int_mul_overflows (len, record_size);
 
-    DEBUG_MSG_LEVEL (SANITIZE, this->debug_depth,
-		     "SANITIZE(%p) %-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s\n",
-		     p,
+    DEBUG_MSG_LEVEL (SANITIZE, this->blob, this->debug_depth,
+		     "%-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s",
 		     this->debug_depth, this->debug_depth,
 		     p, p + (record_size * len), record_size, len, (unsigned long) record_size * len,
 		     this->start, this->end,
@@ -256,9 +233,8 @@ struct hb_sanitize_context_t
     const char *p = (const char *) base;
     this->edit_count++;
 
-    DEBUG_MSG_LEVEL (SANITIZE, this->debug_depth,
-		     "SANITIZE(%p) %-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s\n",
-		     p,
+    DEBUG_MSG_LEVEL (SANITIZE, this->blob, this->debug_depth,
+		     "%-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
 		     this->debug_depth, this->debug_depth,
 		     this->edit_count,
 		     p, p + len, len,
@@ -290,7 +266,7 @@ struct Sanitizer
     c->init (blob);
 
   retry:
-    DEBUG_MSG (SANITIZE, "Sanitizer %p start %s\n", (void *) blob, HB_FUNC);
+    DEBUG_MSG_FUNC (SANITIZE, blob, "start");
 
     c->setup ();
 
@@ -304,15 +280,13 @@ struct Sanitizer
     sane = t->sanitize (c);
     if (sane) {
       if (c->edit_count) {
-	DEBUG_MSG (SANITIZE, "Sanitizer %p passed first round with %d edits; doing a second round %s\n",
-			     (void *) blob, c->edit_count, HB_FUNC);
+	DEBUG_MSG_FUNC (SANITIZE, blob, "passed first round with %d edits; going for second round", c->edit_count);
 
         /* sanitize again to ensure no toe-stepping */
         c->edit_count = 0;
 	sane = t->sanitize (c);
 	if (c->edit_count) {
-	  DEBUG_MSG (SANITIZE, "Sanitizer %p requested %d edits in second round; FAILLING %s\n",
-			       (void *) blob, c->edit_count, HB_FUNC);
+	  DEBUG_MSG_FUNC (SANITIZE, blob, "requested %d edits in second round; FAILLING", c->edit_count);
 	  sane = false;
 	}
       }
@@ -325,7 +299,7 @@ struct Sanitizer
 	if (c->start) {
 	  c->writable = true;
 	  /* ok, we made it writable by relocating.  try again */
-	  DEBUG_MSG (SANITIZE, "Sanitizer %p retry %s\n", (void *) blob, HB_FUNC);
+	  DEBUG_MSG_FUNC (SANITIZE, blob, "retry");
 	  goto retry;
 	}
       }
@@ -333,7 +307,7 @@ struct Sanitizer
 
     c->finish ();
 
-    DEBUG_MSG (SANITIZE, "Sanitizer %p %s %s\n", (void *) blob, sane ? "passed" : "FAILED", HB_FUNC);
+    DEBUG_MSG_FUNC (SANITIZE, blob, sane ? "PASSED" : "FAILED");
     if (sane)
       return blob;
     else {
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 1d75253..3dcfb21 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -51,7 +51,7 @@ static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
 #endif
 
 #define TRACE_APPLY() \
-	hb_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", HB_FUNC, this); \
+	hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", this, NULL, HB_FUNC);
 
 
 HB_BEGIN_DECLS
diff --git a/src/hb-private.hh b/src/hb-private.hh
index f7731df..9482795 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -45,6 +45,7 @@
  * someway around that. */
 #include <stdio.h>
 #include <errno.h>
+#include <stdarg.h>
 
 HB_BEGIN_DECLS
 
@@ -124,9 +125,11 @@ ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
 #if __GNUC__ >= 3
 #define HB_PURE_FUNC	__attribute__((pure))
 #define HB_CONST_FUNC	__attribute__((const))
+#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
 #else
 #define HB_PURE_FUNC
 #define HB_CONST_FUNC
+#define HB_PRINTF_FUCN(format_idx, arg_idx)
 #endif
 #if __GNUC__ >= 4
 #define HB_UNUSED	__attribute__((unused))
@@ -462,27 +465,113 @@ static inline unsigned char TOLOWER (unsigned char c)
 
 /* Debug */
 
+HB_END_DECLS
+
 #ifndef HB_DEBUG
 #define HB_DEBUG 0
 #endif
 
-#define DEBUG_LEVEL(WHAT, LEVEL) (HB_DEBUG_##WHAT && (int) (LEVEL) < (int) (HB_DEBUG_##WHAT))
+static inline bool
+_hb_debug (unsigned int level,
+	   unsigned int max_level)
+{
+  return level < max_level;
+}
+
+#define DEBUG_LEVEL(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
 #define DEBUG(WHAT) (DEBUG_LEVEL (WHAT, 0))
 
-#define DEBUG_MSG_LEVEL(WHAT, LEVEL, ...) (void) (DEBUG_LEVEL (WHAT, LEVEL)  && fprintf (stderr, __VA_ARGS__))
-#define DEBUG_MSG(WHAT, ...) DEBUG_MSG_LEVEL (WHAT, 0, __VA_ARGS__)
+template <int max_level> inline bool /* always returns TRUE */
+_hb_debug_msg (const char *what,
+	       const void *obj,
+	       const char *func,
+	       bool indented,
+	       int level,
+	       const char *message,
+	       ...) HB_PRINTF_FUNC(6, 7);
+template <int max_level> inline bool /* always returns TRUE */
+_hb_debug_msg (const char *what,
+	       const void *obj,
+	       const char *func,
+	       bool indented,
+	       int level,
+	       const char *message,
+	       ...)
+{
+  va_list ap;
+  va_start (ap, message);
+
+  (void) (_hb_debug (level, max_level) &&
+	  fprintf (stderr, "%s(%p): ", what, obj) &&
+	  (func && fprintf (stderr, "%s: ", func), TRUE) &&
+	  (indented && fprintf (stderr, "%-*d-> ", level + 1, level), TRUE) &&
+	  vfprintf (stderr, message, ap) &&
+	  fprintf (stderr, "\n"));
+
+  va_end (ap);
 
-static inline bool /* always returns TRUE */
-_hb_trace (const char *what,
-	   const char *message,
-	   const void *obj,
-	   unsigned int depth,
-	   unsigned int max_depth)
+  return TRUE;
+}
+template <> inline bool /* always returns TRUE */
+_hb_debug_msg<0> (const char *what,
+		  const void *obj,
+		  const char *func,
+		  bool indented,
+		  int level,
+		  const char *message,
+		  ...) HB_PRINTF_FUNC(6, 7);
+template <> inline bool /* always returns TRUE */
+_hb_debug_msg<0> (const char *what,
+		  const void *obj,
+		  const char *func,
+		  bool indented,
+		  int level,
+		  const char *message,
+		  ...)
 {
-  (void) ((depth < max_depth) && fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, depth, depth, message));
   return TRUE;
 }
 
+#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, FALSE, (LEVEL), __VA_ARGS__)
+#define DEBUG_MSG(WHAT, OBJ, ...) DEBUG_MSG_LEVEL (WHAT, OBJ, 0, __VA_ARGS__)
+#define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, FALSE, 0, __VA_ARGS__)
+
+
+/*
+ * Trace
+ */
+
+template <int max_level>
+struct hb_auto_trace_t {
+  explicit inline hb_auto_trace_t (unsigned int *plevel_,
+				   const char *what,
+				   const void *obj,
+				   const char *func,
+				   const char *message) : plevel(plevel_)
+  {
+    if (max_level) ++*plevel;
+    /* TODO support variadic args here */
+    _hb_debug_msg<max_level> (what, obj, func, TRUE, *plevel, "%s", message);
+  }
+  ~hb_auto_trace_t (void) { if (max_level) --*plevel; }
+
+  private:
+  unsigned int *plevel;
+};
+template <> /* Optimize when tracing is disabled */
+struct hb_auto_trace_t<0> {
+  explicit inline hb_auto_trace_t (unsigned int *plevel_,
+				   const char *what,
+				   const void *obj,
+				   const char *func,
+				   const char *message) {}
+};
+
+HB_BEGIN_DECLS
+
+
+/* Misc */
+
 
 /* Pre-mature optimization:
  * Checks for lo <= u <= hi but with an optimization if lo and hi
commit 43ff203d8ea3e1b09e316e3aae1a4e5ec15bfdd2
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Jul 25 17:35:24 2011 -0400

    Use variadic macros for debugging
    
    Looks *so* much nicer!

diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index 5443e57..f6537cd 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -243,27 +243,27 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
 #endif
 
   if ((uintptr_t) -1L == pagesize) {
-    DEBUG (BLOB, fprintf (stderr, "%p %s: failed to get pagesize: %s\n", (void *) blob, HB_FUNC, strerror (errno)));
+    DEBUG_MSG (BLOB, "%p %s: failed to get pagesize: %s\n", (void *) blob, HB_FUNC, strerror (errno));
     return FALSE;
   }
-  DEBUG (BLOB, fprintf (stderr, "%p %s: pagesize is %lu\n", (void *) blob, HB_FUNC, (unsigned long) pagesize));
+  DEBUG_MSG (BLOB, "%p %s: pagesize is %lu\n", (void *) blob, HB_FUNC, (unsigned long) pagesize);
 
   mask = ~(pagesize-1);
   addr = (const char *) (((uintptr_t) blob->data) & mask);
   length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask)  - addr;
-  DEBUG (BLOB, fprintf (stderr, "%p %s: calling mprotect on [%p..%p] (%lu bytes)\n",
-	       (void *) blob, HB_FUNC,
-	       addr, addr+length, (unsigned long) length));
+  DEBUG_MSG (BLOB, "%p %s: calling mprotect on [%p..%p] (%lu bytes)\n",
+		   (void *) blob, HB_FUNC,
+		   addr, addr+length, (unsigned long) length);
   if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
-    DEBUG (BLOB, fprintf (stderr, "%p %s: %s\n", (void *) blob, HB_FUNC, strerror (errno)));
+    DEBUG_MSG (BLOB, "%p %s: %s\n", (void *) blob, HB_FUNC, strerror (errno));
     return FALSE;
   }
 
   blob->mode = HB_MEMORY_MODE_WRITABLE;
 
-  DEBUG (BLOB, fprintf (stderr, "%p %s: successfully made [%p..%p] (%lu bytes) writable\n",
-	       (void *) blob, HB_FUNC,
-	       addr, addr+length, (unsigned long) length));
+  DEBUG_MSG (BLOB, "%p %s: successfully made [%p..%p] (%lu bytes) writable\n",
+		   (void *) blob, HB_FUNC,
+		   addr, addr+length, (unsigned long) length);
   return TRUE;
 #else
   return FALSE;
@@ -273,12 +273,12 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
 static bool
 _try_writable_inplace (hb_blob_t *blob)
 {
-  DEBUG (BLOB, fprintf (stderr, "%p %s: making writable inplace\n", (void *) blob, HB_FUNC));
+  DEBUG_MSG (BLOB, "%p %s: making writable inplace\n", (void *) blob, HB_FUNC);
 
   if (_try_make_writable_inplace_unix (blob))
     return TRUE;
 
-  DEBUG (BLOB, fprintf (stderr, "%p %s: making writable -> FAILED\n", (void *) blob, HB_FUNC));
+  DEBUG_MSG (BLOB, "%p %s: making writable -> FAILED\n", (void *) blob, HB_FUNC);
 
   /* Failed to make writable inplace, mark that */
   blob->mode = HB_MEMORY_MODE_READONLY;
@@ -301,7 +301,7 @@ _try_writable (hb_blob_t *blob)
     return TRUE;
 
 
-  DEBUG (BLOB, fprintf (stderr, "%p %s -> %p\n", (void *) blob, HB_FUNC, blob->data));
+  DEBUG_MSG (BLOB, "%p %s -> %p\n", (void *) blob, HB_FUNC, blob->data);
 
   char *new_data;
 
@@ -309,7 +309,7 @@ _try_writable (hb_blob_t *blob)
   if (unlikely (!new_data))
     return FALSE;
 
-  DEBUG (BLOB, fprintf (stderr, "%p %s: dupped successfully -> %p\n", (void *) blob, HB_FUNC, blob->data));
+  DEBUG_MSG (BLOB, "%p %s: dupped successfully -> %p\n", (void *) blob, HB_FUNC, blob->data);
 
   memcpy (new_data, blob->data, blob->length);
   _hb_blob_destroy_user_data (blob);
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index bdb1b36..37b4703 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -191,10 +191,10 @@ struct _hb_object_header_t {
   }
 
   inline void trace (const char *function) const {
-    DEBUG (OBJECT, fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
-		   (void *) this,
-		   this ? ref_count.get () : 0,
-		   function));
+    DEBUG_MSG (OBJECT, "OBJECT(%p) refcount=%d %s\n",
+		       (void *) this,
+		       this ? ref_count.get () : 0,
+		       function);
   }
 
 };
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index a6499ee..b20e5ca 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -196,17 +196,15 @@ struct hb_sanitize_context_t
     this->edit_count = 0;
     this->debug_depth = 0;
 
-    (void) (HB_DEBUG_SANITIZE &&
-      fprintf (stderr, "sanitize %p init [%p..%p] (%lu bytes)\n",
-	       (void *) this->blob, this->start, this->end,
-	       (unsigned long) (this->end - this->start)));
+    DEBUG_MSG (SANITIZE, "sanitize %p init [%p..%p] (%lu bytes)\n",
+			 (void *) this->blob, this->start, this->end,
+			 (unsigned long) (this->end - this->start));
   }
 
   inline void finish (void)
   {
-    (void) (HB_DEBUG_SANITIZE &&
-      fprintf (stderr, "sanitize %p fini [%p..%p] %u edit requests\n",
-	       (void *) this->blob, this->start, this->end, this->edit_count));
+    DEBUG_MSG (SANITIZE, "sanitize %p fini [%p..%p] %u edit requests\n",
+			 (void *) this->blob, this->start, this->end, this->edit_count);
 
     hb_blob_destroy (this->blob);
     this->blob = NULL;
@@ -220,13 +218,13 @@ struct hb_sanitize_context_t
 	       p <= this->end &&
 	       (unsigned int) (this->end - p) >= len;
 
-    DEBUG_DEPTH (SANITIZE, this->debug_depth,
-		 fprintf (stderr, "SANITIZE(%p) %-*d-> range [%p..%p] (%d bytes) in [%p..%p] -> %s\n",
-			  p,
-			  this->debug_depth, this->debug_depth,
-			  p, p + len, len,
-			  this->start, this->end,
-			  ret ? "pass" : "FAIL"));
+    DEBUG_MSG_LEVEL (SANITIZE, this->debug_depth,
+		     "SANITIZE(%p) %-*d-> range [%p..%p] (%d bytes) in [%p..%p] -> %s\n",
+		     p,
+		     this->debug_depth, this->debug_depth,
+		     p, p + len, len,
+		     this->start, this->end,
+		     ret ? "pass" : "FAIL");
 
     return likely (ret);
   }
@@ -236,13 +234,13 @@ struct hb_sanitize_context_t
     const char *p = (const char *) base;
     bool overflows = _hb_unsigned_int_mul_overflows (len, record_size);
 
-    DEBUG_DEPTH (SANITIZE, this->debug_depth,
-		 fprintf (stderr, "SANITIZE(%p) %-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s\n",
-			  p,
-			  this->debug_depth, this->debug_depth,
-			  p, p + (record_size * len), record_size, len, (unsigned long) record_size * len,
-			  this->start, this->end,
-			  !overflows ? "does not overflow" : "OVERFLOWS FAIL"));
+    DEBUG_MSG_LEVEL (SANITIZE, this->debug_depth,
+		     "SANITIZE(%p) %-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s\n",
+		     p,
+		     this->debug_depth, this->debug_depth,
+		     p, p + (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_range (base, record_size * len));
   }
@@ -258,14 +256,14 @@ struct hb_sanitize_context_t
     const char *p = (const char *) base;
     this->edit_count++;
 
-    DEBUG_DEPTH (SANITIZE, this->debug_depth,
-		 fprintf (stderr, "SANITIZE(%p) %-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s\n",
-			  p,
-			  this->debug_depth, this->debug_depth,
-			  this->edit_count,
-			  p, p + len, len,
-			  this->start, this->end,
-			  this->writable ? "granted" : "REJECTED"));
+    DEBUG_MSG_LEVEL (SANITIZE, this->debug_depth,
+		     "SANITIZE(%p) %-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s\n",
+		     p,
+		     this->debug_depth, this->debug_depth,
+		     this->edit_count,
+		     p, p + len, len,
+		     this->start, this->end,
+		     this->writable ? "granted" : "REJECTED");
 
     return this->writable;
   }
@@ -292,8 +290,7 @@ struct Sanitizer
     c->init (blob);
 
   retry:
-    (void) (HB_DEBUG_SANITIZE &&
-      fprintf (stderr, "Sanitizer %p start %s\n", (void *) blob, HB_FUNC));
+    DEBUG_MSG (SANITIZE, "Sanitizer %p start %s\n", (void *) blob, HB_FUNC);
 
     c->setup ();
 
@@ -307,17 +304,15 @@ struct Sanitizer
     sane = t->sanitize (c);
     if (sane) {
       if (c->edit_count) {
-	(void) (HB_DEBUG_SANITIZE &&
-	  fprintf (stderr, "Sanitizer %p passed first round with %d edits; doing a second round %s\n",
-		   (void *) blob, c->edit_count, HB_FUNC));
+	DEBUG_MSG (SANITIZE, "Sanitizer %p passed first round with %d edits; doing a second round %s\n",
+			     (void *) blob, c->edit_count, HB_FUNC);
 
         /* sanitize again to ensure no toe-stepping */
         c->edit_count = 0;
 	sane = t->sanitize (c);
 	if (c->edit_count) {
-	  (void) (HB_DEBUG_SANITIZE &&
-	    fprintf (stderr, "Sanitizer %p requested %d edits in second round; FAILLING %s\n",
-		     (void *) blob, c->edit_count, HB_FUNC));
+	  DEBUG_MSG (SANITIZE, "Sanitizer %p requested %d edits in second round; FAILLING %s\n",
+			       (void *) blob, c->edit_count, HB_FUNC);
 	  sane = false;
 	}
       }
@@ -330,8 +325,7 @@ struct Sanitizer
 	if (c->start) {
 	  c->writable = true;
 	  /* ok, we made it writable by relocating.  try again */
-	  (void) (HB_DEBUG_SANITIZE &&
-	    fprintf (stderr, "Sanitizer %p retry %s\n", (void *) blob, HB_FUNC));
+	  DEBUG_MSG (SANITIZE, "Sanitizer %p retry %s\n", (void *) blob, HB_FUNC);
 	  goto retry;
 	}
       }
@@ -339,8 +333,7 @@ struct Sanitizer
 
     c->finish ();
 
-    (void) (HB_DEBUG_SANITIZE &&
-      fprintf (stderr, "Sanitizer %p %s %s\n", (void *) blob, sane ? "passed" : "FAILED", HB_FUNC));
+    DEBUG_MSG (SANITIZE, "Sanitizer %p %s %s\n", (void *) blob, sane ? "passed" : "FAILED", HB_FUNC);
     if (sane)
       return blob;
     else {
diff --git a/src/hb-private.hh b/src/hb-private.hh
index b5e85c0..f7731df 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -466,8 +466,11 @@ static inline unsigned char TOLOWER (unsigned char c)
 #define HB_DEBUG 0
 #endif
 
-#define DEBUG(WHAT, CODE) (void) (HB_DEBUG_##WHAT && (CODE))
-#define DEBUG_DEPTH(WHAT, DEPTH, CODE) (void) (HB_DEBUG_##WHAT && (int) (DEPTH) < (int) (HB_DEBUG_##WHAT) && (CODE))
+#define DEBUG_LEVEL(WHAT, LEVEL) (HB_DEBUG_##WHAT && (int) (LEVEL) < (int) (HB_DEBUG_##WHAT))
+#define DEBUG(WHAT) (DEBUG_LEVEL (WHAT, 0))
+
+#define DEBUG_MSG_LEVEL(WHAT, LEVEL, ...) (void) (DEBUG_LEVEL (WHAT, LEVEL)  && fprintf (stderr, __VA_ARGS__))
+#define DEBUG_MSG(WHAT, ...) DEBUG_MSG_LEVEL (WHAT, 0, __VA_ARGS__)
 
 static inline bool /* always returns TRUE */
 _hb_trace (const char *what,
commit decd4e3e16424dc311e9fb5b663170414a11556a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Jul 25 16:47:02 2011 -0400

    Add sugar syntax for debug messages
    
    Buffer debugging coming soon.

diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index db972a1..5443e57 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -243,32 +243,27 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
 #endif
 
   if ((uintptr_t) -1L == pagesize) {
-    (void) (HB_DEBUG_BLOB &&
-      fprintf (stderr, "%p %s: failed to get pagesize: %s\n", (void *) blob, HB_FUNC, strerror (errno)));
+    DEBUG (BLOB, fprintf (stderr, "%p %s: failed to get pagesize: %s\n", (void *) blob, HB_FUNC, strerror (errno)));
     return FALSE;
   }
-  (void) (HB_DEBUG_BLOB &&
-    fprintf (stderr, "%p %s: pagesize is %lu\n", (void *) blob, HB_FUNC, (unsigned long) pagesize));
+  DEBUG (BLOB, fprintf (stderr, "%p %s: pagesize is %lu\n", (void *) blob, HB_FUNC, (unsigned long) pagesize));
 
   mask = ~(pagesize-1);
   addr = (const char *) (((uintptr_t) blob->data) & mask);
   length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask)  - addr;
-  (void) (HB_DEBUG_BLOB &&
-    fprintf (stderr, "%p %s: calling mprotect on [%p..%p] (%lu bytes)\n",
-	     (void *) blob, HB_FUNC,
-	     addr, addr+length, (unsigned long) length));
+  DEBUG (BLOB, fprintf (stderr, "%p %s: calling mprotect on [%p..%p] (%lu bytes)\n",
+	       (void *) blob, HB_FUNC,
+	       addr, addr+length, (unsigned long) length));
   if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
-    (void) (HB_DEBUG_BLOB &&
-      fprintf (stderr, "%p %s: %s\n", (void *) blob, HB_FUNC, strerror (errno)));
+    DEBUG (BLOB, fprintf (stderr, "%p %s: %s\n", (void *) blob, HB_FUNC, strerror (errno)));
     return FALSE;
   }
 
   blob->mode = HB_MEMORY_MODE_WRITABLE;
 
-  (void) (HB_DEBUG_BLOB &&
-    fprintf (stderr, "%p %s: successfully made [%p..%p] (%lu bytes) writable\n",
-	     (void *) blob, HB_FUNC,
-	     addr, addr+length, (unsigned long) length));
+  DEBUG (BLOB, fprintf (stderr, "%p %s: successfully made [%p..%p] (%lu bytes) writable\n",
+	       (void *) blob, HB_FUNC,
+	       addr, addr+length, (unsigned long) length));
   return TRUE;
 #else
   return FALSE;
@@ -278,14 +273,12 @@ _try_make_writable_inplace_unix (hb_blob_t *blob)
 static bool
 _try_writable_inplace (hb_blob_t *blob)
 {
-  (void) (HB_DEBUG_BLOB &&
-    fprintf (stderr, "%p %s: making writable inplace\n", (void *) blob, HB_FUNC));
+  DEBUG (BLOB, fprintf (stderr, "%p %s: making writable inplace\n", (void *) blob, HB_FUNC));
 
   if (_try_make_writable_inplace_unix (blob))
     return TRUE;
 
-  (void) (HB_DEBUG_BLOB &&
-    fprintf (stderr, "%p %s: making writable -> FAILED\n", (void *) blob, HB_FUNC));
+  DEBUG (BLOB, fprintf (stderr, "%p %s: making writable -> FAILED\n", (void *) blob, HB_FUNC));
 
   /* Failed to make writable inplace, mark that */
   blob->mode = HB_MEMORY_MODE_READONLY;
@@ -308,8 +301,7 @@ _try_writable (hb_blob_t *blob)
     return TRUE;
 
 
-  (void) (HB_DEBUG_BLOB &&
-    fprintf (stderr, "%p %s -> %p\n", (void *) blob, HB_FUNC, blob->data));
+  DEBUG (BLOB, fprintf (stderr, "%p %s -> %p\n", (void *) blob, HB_FUNC, blob->data));
 
   char *new_data;
 
@@ -317,8 +309,7 @@ _try_writable (hb_blob_t *blob)
   if (unlikely (!new_data))
     return FALSE;
 
-  (void) (HB_DEBUG_BLOB &&
-    fprintf (stderr, "%p %s: dupped successfully -> %p\n", (void *) blob, HB_FUNC, blob->data));
+  DEBUG (BLOB, fprintf (stderr, "%p %s: dupped successfully -> %p\n", (void *) blob, HB_FUNC, blob->data));
 
   memcpy (new_data, blob->data, blob->length);
   _hb_blob_destroy_user_data (blob);
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index acd1b9e..bdb1b36 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -191,11 +191,10 @@ struct _hb_object_header_t {
   }
 
   inline void trace (const char *function) const {
-    (void) (HB_DEBUG_OBJECT &&
-	    fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
-		     (void *) this,
-		     this ? ref_count.get () : 0,
-		     function));
+    DEBUG (OBJECT, fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
+		   (void *) this,
+		   this ? ref_count.get () : 0,
+		   function));
   }
 
 };
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index ea763e9..a6499ee 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -220,13 +220,13 @@ struct hb_sanitize_context_t
 	       p <= this->end &&
 	       (unsigned int) (this->end - p) >= len;
 
-    (void) (HB_DEBUG_SANITIZE && (int) this->debug_depth < (int) HB_DEBUG_SANITIZE &&
-      fprintf (stderr, "SANITIZE(%p) %-*d-> range [%p..%p] (%d bytes) in [%p..%p] -> %s\n",
-	       p,
-	       this->debug_depth, this->debug_depth,
-	       p, p + len, len,
-	       this->start, this->end,
-	       ret ? "pass" : "FAIL"));
+    DEBUG_DEPTH (SANITIZE, this->debug_depth,
+		 fprintf (stderr, "SANITIZE(%p) %-*d-> range [%p..%p] (%d bytes) in [%p..%p] -> %s\n",
+			  p,
+			  this->debug_depth, this->debug_depth,
+			  p, p + len, len,
+			  this->start, this->end,
+			  ret ? "pass" : "FAIL"));
 
     return likely (ret);
   }
@@ -236,13 +236,13 @@ struct hb_sanitize_context_t
     const char *p = (const char *) base;
     bool overflows = _hb_unsigned_int_mul_overflows (len, record_size);
 
-    (void) (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",
-	       p,
-	       this->debug_depth, this->debug_depth,
-	       p, p + (record_size * len), record_size, len, (unsigned long) record_size * len,
-	       this->start, this->end,
-	       !overflows ? "does not overflow" : "OVERFLOWS FAIL"));
+    DEBUG_DEPTH (SANITIZE, this->debug_depth,
+		 fprintf (stderr, "SANITIZE(%p) %-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s\n",
+			  p,
+			  this->debug_depth, this->debug_depth,
+			  p, p + (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_range (base, record_size * len));
   }
@@ -258,14 +258,14 @@ struct hb_sanitize_context_t
     const char *p = (const char *) base;
     this->edit_count++;
 
-    (void) (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",
-	       p,
-	       this->debug_depth, this->debug_depth,
-	       this->edit_count,
-	       p, p + len, len,
-	       this->start, this->end,
-	       this->writable ? "granted" : "REJECTED"));
+    DEBUG_DEPTH (SANITIZE, this->debug_depth,
+		 fprintf (stderr, "SANITIZE(%p) %-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s\n",
+			  p,
+			  this->debug_depth, this->debug_depth,
+			  this->edit_count,
+			  p, p + len, len,
+			  this->start, this->end,
+			  this->writable ? "granted" : "REJECTED"));
 
     return this->writable;
   }
diff --git a/src/hb-private.hh b/src/hb-private.hh
index b5745e7..b5e85c0 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -466,14 +466,17 @@ static inline unsigned char TOLOWER (unsigned char c)
 #define HB_DEBUG 0
 #endif
 
+#define DEBUG(WHAT, CODE) (void) (HB_DEBUG_##WHAT && (CODE))
+#define DEBUG_DEPTH(WHAT, DEPTH, CODE) (void) (HB_DEBUG_##WHAT && (int) (DEPTH) < (int) (HB_DEBUG_##WHAT) && (CODE))
+
 static inline bool /* always returns TRUE */
 _hb_trace (const char *what,
-	   const char *function,
+	   const char *message,
 	   const void *obj,
 	   unsigned int depth,
 	   unsigned int max_depth)
 {
-  (void) ((depth < max_depth) && fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, depth, depth, function));
+  (void) ((depth < max_depth) && fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, depth, depth, message));
   return TRUE;
 }
 
commit 3a81b1db89beba91fb91791918b9fdd9f8fc9fa0
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Jul 25 16:30:32 2011 -0400

    Minor, fix leak from my previous refactorings

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 2b5760d..159600e 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -34,7 +34,7 @@
 HB_BEGIN_DECLS
 
 
-static hb_buffer_t Xhb_buffer_nil = {
+static hb_buffer_t _hb_buffer_nil = {
   HB_OBJECT_HEADER_STATIC,
 
   &_hb_unicode_funcs_default,
@@ -140,9 +140,9 @@ hb_buffer_t::reset (void)
     return;
 
   hb_unicode_funcs_destroy (unicode);
-  unicode = Xhb_buffer_nil.unicode;
+  unicode = _hb_buffer_nil.unicode;
 
-  props = Xhb_buffer_nil.props;
+  props = _hb_buffer_nil.props;
 
   in_error = FALSE;
   have_output = FALSE;
@@ -417,13 +417,13 @@ hb_buffer_create (unsigned int pre_alloc_size)
   hb_buffer_t *buffer;
 
   if (!(buffer = hb_object_create<hb_buffer_t> ()))
-    return &Xhb_buffer_nil;
+    return &_hb_buffer_nil;
 
   buffer->reset ();
 
   if (pre_alloc_size && !buffer->ensure (pre_alloc_size)) {
     hb_buffer_destroy (buffer);
-    return &Xhb_buffer_nil;
+    return &_hb_buffer_nil;
   }
 
   return buffer;
@@ -432,7 +432,7 @@ hb_buffer_create (unsigned int pre_alloc_size)
 hb_buffer_t *
 hb_buffer_get_empty (void)
 {
-  return &Xhb_buffer_nil;
+  return &_hb_buffer_nil;
 }
 
 hb_buffer_t *
@@ -479,7 +479,7 @@ hb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
     return;
 
   if (!unicode)
-    unicode = Xhb_buffer_nil.unicode;
+    unicode = _hb_buffer_nil.unicode;
 
   hb_unicode_funcs_reference (unicode);
   hb_unicode_funcs_destroy (buffer->unicode);
commit f4a579bc42fb811ff5c391a0e97b7d8656ef59b1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Jul 25 16:20:16 2011 -0400

    Add internal API for buffer var allocation

diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index f544c82..d83d130 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -66,13 +66,15 @@ struct _hb_buffer_t {
   unsigned int len; /* Length of ->info and ->pos arrays */
   unsigned int out_len; /* Length of ->out array if have_output */
 
-  unsigned int serial;
-
   unsigned int allocated; /* Length of allocated arrays */
   hb_glyph_info_t     *info;
   hb_glyph_info_t     *out_info;
   hb_glyph_position_t *pos;
 
+  unsigned int serial;
+  uint8_t allocated_var_bytes[8];
+  const char *allocated_var_owner[8];
+
 
   /* Methods */
 
@@ -82,6 +84,25 @@ struct _hb_buffer_t {
   { return have_output? out_len : idx; }
   inline unsigned int next_serial (void) { return serial++; }
 
+
+  HB_INTERNAL void allocate_var (unsigned int byte_i, unsigned int count, const char *owner);
+  HB_INTERNAL void deallocate_var (unsigned int byte_i, unsigned int count, const char *owner);
+
+  inline void allocate_var_8 (unsigned int var_num, unsigned int i, const char *owner)
+  { assert (var_num < 2 && i < 4); allocate_var (var_num * 4 + i, 1, owner); }
+  inline void allocate_var_16 (unsigned int var_num, unsigned int i, const char *owner)
+  { assert (var_num < 2 && i < 2); allocate_var (var_num * 4 + i * 2, 2, owner); }
+  inline void allocate_var_32 (unsigned int var_num, const char *owner)
+  { assert (var_num < 2); allocate_var (var_num * 4, 4, owner); }
+
+  inline void deallocate_var_8 (unsigned int var_num, unsigned int i, const char *owner)
+  { assert (var_num < 2 && i < 4); deallocate_var (var_num * 4 + i, 1, owner); }
+  inline void deallocate_var_16 (unsigned int var_num, unsigned int i, const char *owner)
+  { assert (var_num < 2 && i < 2); deallocate_var (var_num * 4 + i * 2, 2, owner); }
+  inline void deallocate_var_32 (unsigned int var_num, const char *owner)
+  { assert (var_num < 2); deallocate_var (var_num * 4, 4, owner); }
+
+
   HB_INTERNAL void add (hb_codepoint_t  codepoint,
 			hb_mask_t       mask,
 			unsigned int    cluster);
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 716f858..2b5760d 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -153,6 +153,8 @@ hb_buffer_t::reset (void)
   out_len = 0;
 
   serial = 0;
+  memset (allocated_var_bytes, 0, sizeof allocated_var_bytes);
+  memset (allocated_var_owner, 0, sizeof allocated_var_owner);
 
   out_info = info;
 }
@@ -387,6 +389,26 @@ hb_buffer_t::reverse_clusters (void)
 }
 
 
+void hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const char *owner)
+{
+  assert (byte_i < 8 && byte_i + count < 8);
+  for (unsigned int i = byte_i; i < byte_i + count; i++) {
+    assert (!allocated_var_bytes[i]);
+    allocated_var_bytes[i]++;
+    allocated_var_owner[i] = owner;
+  }
+}
+
+void hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner)
+{
+  assert (byte_i < 8 && byte_i + count < 8);
+  for (unsigned int i = byte_i; i < byte_i + count; i++) {
+    assert (allocated_var_bytes[i] && allocated_var_owner[i] == owner);
+    allocated_var_bytes[i]--;
+  }
+}
+
+
 /* Public API */
 
 hb_buffer_t *
commit 651e8dd79ec8eaca5ab75a61e8ce961ff7bd26eb
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Jul 25 14:54:08 2011 -0400

    Start cleaning up buffer var allocation
    
    I've messed up a lot of stuff recently, different parts of the
    shaping process are stumbling on eachother's toes because
    manually tracking what's in which buffer var is hard.  I'm
    going to add some internal API to track those such that mistakes
    are discovered as soon as they are introduced.

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 2d07a6f..1d75253 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -34,7 +34,6 @@
 
 HB_BEGIN_DECLS
 
-
 /* buffer var allocations */
 #define lig_id() var2.u8[2] /* unique ligature id */
 #define lig_comp() var2.u8[3] /* component number in the ligature (0 = base) */
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index a49f339..1da4792 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -444,6 +444,7 @@ void
 hb_ot_layout_substitute_start (hb_buffer_t  *buffer)
 {
   unsigned int count = buffer->len;
+  /* XXX */
   for (unsigned int i = 0; i < count; i++)
     buffer->info[i].var1.u32 = buffer->info[i].var2.u32 = 0;
 }
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index a1893ef..9b362bd 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -170,14 +170,6 @@ hb_ensure_native_direction (hb_buffer_t *buffer)
   }
 }
 
-static void
-hb_reset_glyph_infos (hb_buffer_t *buffer)
-{
-  unsigned int count = buffer->len;
-  for (unsigned int i = 0; i < count; i++)
-    buffer->info[i].var1.u32 = buffer->info[i].var2.u32 = 0;
-}
-
 
 /* Substitute */
 
@@ -352,8 +344,6 @@ hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
   /* Save the original direction, we use it later. */
   c->target_direction = c->buffer->props.direction;
 
-  hb_reset_glyph_infos (c->buffer); /* BUFFER: Clear buffer var1 and var2 */
-
   _hb_set_unicode_props (c->buffer); /* BUFFER: Set general_category and combining_class in var1 */
 
   hb_form_clusters (c->buffer);
commit c86f932015bdf5803572b0904d343d3bc033e009
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Jul 25 00:44:50 2011 -0400

    Move code around

diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 929a662..a1893ef 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -129,49 +129,6 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
 }
 
 
-static void
-hb_ot_substitute_complex (hb_ot_shape_context_t *c)
-{
-  if (!hb_ot_layout_has_substitution (c->face))
-    return;
-
-  c->plan->map.substitute (c->face, c->buffer);
-
-  c->applied_substitute_complex = TRUE;
-  return;
-}
-
-static void
-hb_ot_position_complex (hb_ot_shape_context_t *c)
-{
-
-  if (!hb_ot_layout_has_positioning (c->face))
-    return;
-
-  unsigned int count = c->buffer->len;
-  for (unsigned int i = 0; i < count; i++) {
-    hb_font_add_glyph_origin_for_direction (c->font, c->buffer->info[i].codepoint,
-					    HB_DIRECTION_LTR,
-					    &c->buffer->pos[i].x_offset,
-					    &c->buffer->pos[i].y_offset);
-  }
-
-  c->plan->map.position (c->font, c->buffer);
-
-  for (unsigned int i = 0; i < count; i++) {
-    hb_font_subtract_glyph_origin_for_direction (c->font, c->buffer->info[i].codepoint,
-						 HB_DIRECTION_LTR,
-						 &c->buffer->pos[i].x_offset,
-						 &c->buffer->pos[i].y_offset);
-  }
-
-  hb_ot_layout_position_finish (c->buffer);
-
-  c->applied_position_complex = TRUE;
-  return;
-}
-
-
 /* Main shaper */
 
 /* Prepare */
@@ -280,6 +237,18 @@ hb_substitute_default (hb_ot_shape_context_t *c)
 }
 
 static void
+hb_ot_substitute_complex (hb_ot_shape_context_t *c)
+{
+  if (!hb_ot_layout_has_substitution (c->face))
+    return;
+
+  c->plan->map.substitute (c->face, c->buffer);
+
+  c->applied_substitute_complex = TRUE;
+  return;
+}
+
+static void
 hb_substitute_complex_fallback (hb_ot_shape_context_t *c HB_UNUSED)
 {
   /* TODO Arabic */
@@ -307,6 +276,36 @@ hb_position_default (hb_ot_shape_context_t *c)
 }
 
 static void
+hb_ot_position_complex (hb_ot_shape_context_t *c)
+{
+
+  if (!hb_ot_layout_has_positioning (c->face))
+    return;
+
+  unsigned int count = c->buffer->len;
+  for (unsigned int i = 0; i < count; i++) {
+    hb_font_add_glyph_origin_for_direction (c->font, c->buffer->info[i].codepoint,
+					    HB_DIRECTION_LTR,
+					    &c->buffer->pos[i].x_offset,
+					    &c->buffer->pos[i].y_offset);
+  }
+
+  c->plan->map.position (c->font, c->buffer);
+
+  for (unsigned int i = 0; i < count; i++) {
+    hb_font_subtract_glyph_origin_for_direction (c->font, c->buffer->info[i].codepoint,
+						 HB_DIRECTION_LTR,
+						 &c->buffer->pos[i].x_offset,
+						 &c->buffer->pos[i].y_offset);
+  }
+
+  hb_ot_layout_position_finish (c->buffer);
+
+  c->applied_position_complex = TRUE;
+  return;
+}
+
+static void
 hb_position_complex_fallback (hb_ot_shape_context_t *c HB_UNUSED)
 {
   /* TODO Mark pos */
commit 18c42850c9327ab4479ff150660a76d4ff6f3e9c
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Jul 25 00:36:58 2011 -0400

    Shrink space used for ligature ids
    
    This frees 16bits in the glyph_info struct during the ot_layout process.
    We can use the freed space in the shapers now.

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 8be4312..2d07a6f 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -36,11 +36,11 @@ HB_BEGIN_DECLS
 
 
 /* buffer var allocations */
-#define lig_id() var2.u16[0] /* unique ligature id */
-#define lig_comp() var2.u16[1] /* component number in the ligature (0 = base) */
+#define lig_id() var2.u8[2] /* unique ligature id */
+#define lig_comp() var2.u8[3] /* component number in the ligature (0 = base) */
 
-static inline uint16_t allocate_lig_id (hb_buffer_t *buffer) {
-  uint16_t lig_id = buffer->next_serial ();
+static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
+  uint8_t lig_id = buffer->next_serial ();
   if (unlikely (!lig_id)) lig_id = buffer->next_serial (); /* in case of overflow */
   return lig_id;
 }
commit d8787493c9aa420544096cef07c29a591a0c1a99
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Jul 25 00:36:01 2011 -0400

    Minor

diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 09ebc31..b9161bf 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -407,12 +407,6 @@ struct Ligature
     return true;
   }
 
-  inline uint16_t allocate_lig_id (hb_buffer_t *buffer) const {
-    uint16_t lig_id = buffer->next_serial ();
-    if (unlikely (!lig_id)) lig_id = buffer->next_serial (); /* in case of overflow */
-    return lig_id;
-  }
-
   public:
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 7ccbdf0..8be4312 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -39,6 +39,13 @@ HB_BEGIN_DECLS
 #define lig_id() var2.u16[0] /* unique ligature id */
 #define lig_comp() var2.u16[1] /* component number in the ligature (0 = base) */
 
+static inline uint16_t allocate_lig_id (hb_buffer_t *buffer) {
+  uint16_t lig_id = buffer->next_serial ();
+  if (unlikely (!lig_id)) lig_id = buffer->next_serial (); /* in case of overflow */
+  return lig_id;
+}
+
+
 
 #ifndef HB_DEBUG_APPLY
 #define HB_DEBUG_APPLY (HB_DEBUG+0)



More information about the HarfBuzz mailing list