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

Behdad Esfahbod behdad at kemper.freedesktop.org
Thu Nov 4 16:07:16 PDT 2010


 TODO                                 |    4 
 src/hb-blob.c                        |   50 +++---
 src/hb-buffer-private.hh             |   83 ++--------
 src/hb-buffer.cc                     |  136 +++--------------
 src/hb-buffer.h                      |    6 
 src/hb-common.h                      |   10 +
 src/hb-object-private.h              |   12 -
 src/hb-open-type-private.hh          |   84 +++++-----
 src/hb-ot-layout-common-private.hh   |   17 +-
 src/hb-ot-layout-gdef-private.hh     |   27 +++
 src/hb-ot-layout-gpos-private.hh     |  124 ++++++++++++---
 src/hb-ot-layout-gsub-private.hh     |  105 +++++--------
 src/hb-ot-layout-gsubgpos-private.hh |   48 ++++--
 src/hb-ot-layout-private.hh          |   47 ++---
 src/hb-ot-layout.cc                  |  276 ++++++-----------------------------
 src/hb-ot-layout.h                   |   30 ---
 src/hb-ot-shape-complex-arabic.cc    |   16 +-
 src/hb-ot-shape-private.hh           |    6 
 src/hb-ot-shape.cc                   |   40 ++++-
 src/hb-private.h                     |    3 
 src/main.cc                          |    4 
 21 files changed, 470 insertions(+), 658 deletions(-)

New commits:
commit 3a852ae7fe6edfaadd75625d27515a3689503395
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Nov 3 16:37:24 2010 -0400

    Save general category and combining class in the buffer for reuse

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 4d8a855..b0088fb 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -39,9 +39,10 @@ HB_BEGIN_DECLS
 
 
 /* buffer var allocations */
-#define props_cache() var1.u16[0] /* glyph_props cache */
+#define props_cache() var1.u16[1] /* glyph_props cache */
 
 
+/* XXX cleanup */
 typedef enum {
   HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED	= 0x0001,
   HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH	= 0x0002,
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 2401c36..a63060c 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -28,6 +28,11 @@
 
 HB_BEGIN_DECLS
 
+
+/* buffer var allocations */
+#define arabic_shaping_action() var2.u32 /* arabic shaping action */
+
+
 /*
  * Bits used in the joining tables
  */
@@ -686,20 +691,19 @@ _hb_ot_shape_complex_setup_masks_arabic	(hb_ot_shape_context_t *c)
 
   for (unsigned int i = 0; i < count; i++)
   {
-
-    unsigned int this_type = get_joining_type (c->buffer->info[i].codepoint, c->buffer->unicode->v.get_general_category (c->buffer->info[i].codepoint));
+    unsigned int this_type = get_joining_type (c->buffer->info[i].codepoint, (hb_category_t) c->buffer->info[i].general_category());
 
     if (unlikely (this_type == JOINING_TYPE_T)) {
-      c->buffer->info[i].var2.u32 = NONE;
+      c->buffer->info[i].arabic_shaping_action() = NONE;
       continue;
     }
 
     const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
 
     if (entry->prev_action != NONE)
-      c->buffer->info[prev].var2.u32 = entry->prev_action;
+      c->buffer->info[prev].arabic_shaping_action() = entry->prev_action;
 
-    c->buffer->info[i].var2.u32 = entry->curr_action;
+    c->buffer->info[i].arabic_shaping_action() = entry->curr_action;
 
     prev = i;
     state = entry->next_state;
@@ -711,7 +715,7 @@ _hb_ot_shape_complex_setup_masks_arabic	(hb_ot_shape_context_t *c)
     mask_array[i] = c->plan->map.get_1_mask (arabic_syriac_features[i]);
 
   for (unsigned int i = 0; i < count; i++)
-    c->buffer->info[i].mask |= mask_array[c->buffer->info[i].var2.u32];
+    c->buffer->info[i].mask |= mask_array[c->buffer->info[i].arabic_shaping_action()];
 }
 
 
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 0794fbf..6197406 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -35,6 +35,12 @@
 
 HB_BEGIN_DECLS
 
+
+/* buffer var allocations */
+#define general_category() var1.u8[0] /* unicode general_category (hb_category_t) */
+#define combining_class() var1.u8[1] /* unicode combining_class (uint8_t) */
+
+
 enum hb_ot_complex_shaper_t {
   hb_ot_complex_shaper_none,
   hb_ot_complex_shaper_arabic
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index a4e568d..346cb37 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -86,7 +86,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
   hb_mask_t global_mask = c->plan->map.get_global_mask ();
   c->buffer->reset_masks (global_mask);
 
-  hb_ot_shape_complex_setup_masks (c);
+  hb_ot_shape_complex_setup_masks (c); /* BUFFER: Clobbers var2 */
 
   for (unsigned int i = 0; i < c->num_user_features; i++)
   {
@@ -141,11 +141,25 @@ is_variation_selector (hb_codepoint_t unicode)
 }
 
 static void
+hb_set_unicode_props (hb_ot_shape_context_t *c)
+{
+  hb_unicode_get_general_category_func_t get_general_category = c->buffer->unicode->v.get_general_category;
+  hb_unicode_get_combining_class_func_t get_combining_class = c->buffer->unicode->v.get_combining_class;
+  hb_glyph_info_t *info = c->buffer->info;
+
+  unsigned int count = c->buffer->len;
+  for (unsigned int i = 1; i < count; i++) {
+    info[i].general_category() = get_general_category (info[i].codepoint);
+    info[i].combining_class() = get_combining_class (info[i].codepoint);
+  }
+}
+
+static void
 hb_form_clusters (hb_ot_shape_context_t *c)
 {
   unsigned int count = c->buffer->len;
   for (unsigned int i = 1; i < count; i++)
-    if (c->buffer->unicode->v.get_general_category (c->buffer->info[i].codepoint) == HB_CATEGORY_NON_SPACING_MARK)
+    if (c->buffer->info[i].general_category() == HB_CATEGORY_NON_SPACING_MARK)
       c->buffer->info[i].cluster = c->buffer->info[i - 1].cluster;
 }
 
@@ -282,11 +296,13 @@ hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
   /* Save the original direction, we use it later. */
   c->original_direction = c->buffer->props.direction;
 
-  hb_form_clusters (c);
+  hb_reset_glyph_infos (c); /* BUFFER: Clear buffer var1 and var2 */
 
-  hb_ot_shape_setup_masks (c);
+  hb_set_unicode_props (c); /* BUFFER: Set general_category and combining_class in var1 */
+
+  hb_form_clusters (c);
 
-  hb_reset_glyph_infos (c);
+  hb_ot_shape_setup_masks (c); /* BUFFER: Clobbers var2 */
 
   /* SUBSTITUTE */
   {
commit a5ab682b9ba8224fc132624f93e6fef9973a68ca
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Nov 3 15:50:36 2010 -0400

    More "unreached code" warning fixes
    
    Ugly :(.

diff --git a/src/hb-blob.c b/src/hb-blob.c
index 3c98052..37e7787 100644
--- a/src/hb-blob.c
+++ b/src/hb-blob.c
@@ -182,9 +182,9 @@ hb_blob_lock (hb_blob_t *blob)
 
   hb_mutex_lock (blob->lock);
 
-  if (HB_DEBUG_BLOB)
+  (void) (HB_DEBUG_BLOB &&
     fprintf (stderr, "%p %s (%d) -> %p\n", blob, __FUNCTION__,
-	     blob->lock_count, blob->data);
+	     blob->lock_count, blob->data));
 
   blob->lock_count++;
 
@@ -201,9 +201,9 @@ hb_blob_unlock (hb_blob_t *blob)
 
   hb_mutex_lock (blob->lock);
 
-  if (HB_DEBUG_BLOB)
+  (void) (HB_DEBUG_BLOB &&
     fprintf (stderr, "%p %s (%d) -> %p\n", blob, __FUNCTION__,
-	     blob->lock_count, blob->data);
+	     blob->lock_count, blob->data));
 
   assert (blob->lock_count > 0);
   blob->lock_count--;
@@ -245,30 +245,30 @@ _try_make_writable_inplace_unix_locked (hb_blob_t *blob)
 #endif
 
   if ((uintptr_t) -1L == pagesize) {
-    if (HB_DEBUG_BLOB)
-      fprintf (stderr, "%p %s: failed to get pagesize: %s\n", blob, __FUNCTION__, strerror (errno));
+    (void) (HB_DEBUG_BLOB &&
+      fprintf (stderr, "%p %s: failed to get pagesize: %s\n", blob, __FUNCTION__, strerror (errno)));
     return FALSE;
   }
-  if (HB_DEBUG_BLOB)
-    fprintf (stderr, "%p %s: pagesize is %lu\n", blob, __FUNCTION__, (unsigned long) pagesize);
+  (void) (HB_DEBUG_BLOB &&
+    fprintf (stderr, "%p %s: pagesize is %lu\n", blob, __FUNCTION__, (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;
-  if (HB_DEBUG_BLOB)
+  (void) (HB_DEBUG_BLOB &&
     fprintf (stderr, "%p %s: calling mprotect on [%p..%p] (%lu bytes)\n",
 	     blob, __FUNCTION__,
-	     addr, addr+length, (unsigned long) length);
+	     addr, addr+length, (unsigned long) length));
   if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
-    if (HB_DEBUG_BLOB)
-      fprintf (stderr, "%p %s: %s\n", blob, __FUNCTION__, strerror (errno));
+    (void) (HB_DEBUG_BLOB &&
+      fprintf (stderr, "%p %s: %s\n", blob, __FUNCTION__, strerror (errno)));
     return FALSE;
   }
 
-  if (HB_DEBUG_BLOB)
+  (void) (HB_DEBUG_BLOB &&
     fprintf (stderr, "%p %s: successfully made [%p..%p] (%lu bytes) writable\n",
 	     blob, __FUNCTION__,
-	     addr, addr+length, (unsigned long) length);
+	     addr, addr+length, (unsigned long) length));
   return TRUE;
 #else
   return FALSE;
@@ -278,16 +278,16 @@ _try_make_writable_inplace_unix_locked (hb_blob_t *blob)
 static void
 try_writable_inplace_locked (hb_blob_t *blob)
 {
-  if (HB_DEBUG_BLOB)
-    fprintf (stderr, "%p %s: making writable\n", blob, __FUNCTION__);
+  (void) (HB_DEBUG_BLOB &&
+    fprintf (stderr, "%p %s: making writable\n", blob, __FUNCTION__));
 
   if (_try_make_writable_inplace_unix_locked (blob)) {
-    if (HB_DEBUG_BLOB)
-      fprintf (stderr, "%p %s: making writable -> succeeded\n", blob, __FUNCTION__);
+    (void) (HB_DEBUG_BLOB &&
+      fprintf (stderr, "%p %s: making writable -> succeeded\n", blob, __FUNCTION__));
     blob->mode = HB_MEMORY_MODE_WRITABLE;
   } else {
-    if (HB_DEBUG_BLOB)
-      fprintf (stderr, "%p %s: making writable -> FAILED\n", blob, __FUNCTION__);
+    (void) (HB_DEBUG_BLOB &&
+      fprintf (stderr, "%p %s: making writable -> FAILED\n", blob, __FUNCTION__));
     /* Failed to make writable inplace, mark that */
     blob->mode = HB_MEMORY_MODE_READONLY;
   }
@@ -330,17 +330,17 @@ hb_blob_try_writable (hb_blob_t *blob)
   {
     char *new_data;
 
-    if (HB_DEBUG_BLOB)
+    (void) (HB_DEBUG_BLOB &&
       fprintf (stderr, "%p %s (%d) -> %p\n", blob, __FUNCTION__,
-	       blob->lock_count, blob->data);
+	       blob->lock_count, blob->data));
 
     if (blob->lock_count)
       goto done;
 
     new_data = malloc (blob->length);
     if (new_data) {
-      if (HB_DEBUG_BLOB)
-	fprintf (stderr, "%p %s: dupped successfully -> %p\n", blob, __FUNCTION__, blob->data);
+      (void) (HB_DEBUG_BLOB &&
+	fprintf (stderr, "%p %s: dupped successfully -> %p\n", blob, __FUNCTION__, blob->data));
       memcpy (new_data, blob->data, blob->length);
       _hb_blob_destroy_user_data (blob);
       blob->mode = HB_MEMORY_MODE_WRITABLE;
commit 4e22c7e94102c9f00c32b8cb6aaa832f83909149
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Nov 3 15:47:12 2010 -0400

    Add comment

diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 2855425..9ff5ca9 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -78,6 +78,9 @@ template <typename Type>
 struct RecordArrayOf : SortedArrayOf<Record<Type> > {
   inline const Tag& get_tag (unsigned int i) const
   {
+    /* We cheat slightly and don't define separate Null objects
+     * for Record types.  Instead, we return the correct Null(Tag)
+     * here. */
     if (unlikely (i >= this->len)) return Null(Tag);
     return (*this)[i].tag;
   }
commit 0342034d1cb577d34b42f7204da7fb930c12a464
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Nov 3 15:40:07 2010 -0400

    Pedantic

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 0dc8d17..11bb286 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -240,7 +240,7 @@ struct AnchorFormat2
       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;
+      hb_bool_t ret = false;
 
       if (x_ppem || y_ppem)
 	ret = hb_font_get_contour_point (layout->font, layout->face, anchorPoint, glyph_id, &cx, &cy);
commit 4a2d844c2f12dc1b858ab4ddd737ded7c0852221
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Nov 3 15:28:56 2010 -0400

    Minor code shuffling

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index dddbb60..4d8a855 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -99,28 +99,13 @@ HB_INTERNAL hb_bool_t
 _hb_ot_layout_check_glyph_property (hb_face_t    *face,
 				    hb_glyph_info_t *ginfo,
 				    unsigned int  lookup_props,
-				    unsigned int *property);
+				    unsigned int *property_out);
 
-static inline hb_bool_t
+HB_INTERNAL hb_bool_t
 _hb_ot_layout_skip_mark (hb_face_t    *face,
 			 hb_glyph_info_t *ginfo,
 			 unsigned int  lookup_props,
-			 unsigned int *property_out)
-{
-  unsigned int property;
-
-  property = _hb_ot_layout_get_glyph_property (face, ginfo);
-  if (property_out)
-    *property_out = property;
-
-  /* If it's a mark, skip it we don't accept it. */
-  if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
-    return !_hb_ot_layout_check_glyph_property (face, ginfo, lookup_props, NULL);
-
-  /* If not a mark, don't skip. */
-  return false;
-}
-
+			 unsigned int *property_out);
 
 
 HB_END_DECLS
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 755b483..fc4b1d3 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -115,43 +115,72 @@ _hb_ot_layout_get_glyph_property (hb_face_t       *face,
   return info->props_cache();
 }
 
-hb_bool_t
-_hb_ot_layout_check_glyph_property (hb_face_t    *face,
-				    hb_glyph_info_t *ginfo,
-				    unsigned int  lookup_props,
-				    unsigned int *property_out)
+static hb_bool_t
+_hb_ot_layout_match_properties (hb_face_t      *face,
+				hb_codepoint_t  codepoint,
+				unsigned int    glyph_props,
+				unsigned int    lookup_props)
 {
-  unsigned int property;
-
-  property = _hb_ot_layout_get_glyph_property (face, ginfo);
-  if (property_out)
-    *property_out = property;
-
   /* Not covered, if, for example, glyph class is ligature and
    * lookup_props includes LookupFlags::IgnoreLigatures
    */
-  if (property & lookup_props & LookupFlag::IgnoreFlags)
+  if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
     return false;
 
-  if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
+  if (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
   {
     /* If using mark filtering sets, the high short of
      * lookup_props has the set index.
      */
     if (lookup_props & LookupFlag::UseMarkFilteringSet)
-      return _get_gdef (face).mark_set_covers (lookup_props >> 16, ginfo->codepoint);
+      return _get_gdef (face).mark_set_covers (lookup_props >> 16, codepoint);
 
     /* The second byte of lookup_props has the meaning
      * "ignore marks of attachment type different than
      * the attachment type specified."
      */
-    if (lookup_props & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType)
-      return (lookup_props & LookupFlag::MarkAttachmentType) == (property & LookupFlag::MarkAttachmentType);
+    if (lookup_props & LookupFlag::MarkAttachmentType && glyph_props & LookupFlag::MarkAttachmentType)
+      return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
   }
 
   return true;
 }
 
+hb_bool_t
+_hb_ot_layout_check_glyph_property (hb_face_t    *face,
+				    hb_glyph_info_t *ginfo,
+				    unsigned int  lookup_props,
+				    unsigned int *property_out)
+{
+  unsigned int property;
+
+  property = _hb_ot_layout_get_glyph_property (face, ginfo);
+  (void) (property_out && (*property_out = property));
+
+  return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
+}
+
+hb_bool_t
+_hb_ot_layout_skip_mark (hb_face_t    *face,
+			 hb_glyph_info_t *ginfo,
+			 unsigned int  lookup_props,
+			 unsigned int *property_out)
+{
+  unsigned int property;
+
+  property = _hb_ot_layout_get_glyph_property (face, ginfo);
+  (void) (property_out && (*property_out = property));
+
+  /* If it's a mark, skip it we don't accept it. */
+  if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
+    return !_hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
+
+  /* If not a mark, don't skip. */
+  return false;
+}
+
+
+
 unsigned int
 hb_ot_layout_get_attach_points (hb_face_t      *face,
 				hb_codepoint_t  glyph,
commit 11e3ec444a85fc72541823c2e98cc92c4ceb19af
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Nov 3 15:11:04 2010 -0400

    Fix a few more "unreachable code" warnings

diff --git a/src/hb-blob.c b/src/hb-blob.c
index 926481d..3c98052 100644
--- a/src/hb-blob.c
+++ b/src/hb-blob.c
@@ -42,7 +42,7 @@ HB_BEGIN_DECLS
 
 
 #ifndef HB_DEBUG_BLOB
-#define HB_DEBUG_BLOB HB_DEBUG+0
+#define HB_DEBUG_BLOB (HB_DEBUG+0)
 #endif
 
 hb_blob_t _hb_blob_nil = {
diff --git a/src/hb-object-private.h b/src/hb-object-private.h
index 57f5f94..4e98a95 100644
--- a/src/hb-object-private.h
+++ b/src/hb-object-private.h
@@ -60,7 +60,7 @@ typedef struct {
 /* Debug */
 
 #ifndef HB_DEBUG_OBJECT
-#define HB_DEBUG_OBJECT HB_DEBUG+0
+#define HB_DEBUG_OBJECT (HB_DEBUG+0)
 #endif
 
 static inline void
@@ -68,11 +68,11 @@ _hb_trace_object (const void *obj,
 		  hb_reference_count_t *ref_count,
 		  const char *function)
 {
-  if (HB_DEBUG_OBJECT)
-    fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
-	     obj,
-	     HB_REFERENCE_COUNT_GET_VALUE (*ref_count),
-	     function);
+  (void) (HB_DEBUG_OBJECT &&
+	  fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
+		   obj,
+		   HB_REFERENCE_COUNT_GET_VALUE (*ref_count),
+		   function));
 }
 
 #define TRACE_OBJECT(obj) _hb_trace_object (obj, &obj->ref_count, __FUNCTION__)
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 38ba3a3..8f3001b 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -152,8 +152,8 @@ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
 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) {
-    if (*pdepth < max_depth)
-      fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, *pdepth, *pdepth, function);
+    (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; }
@@ -173,7 +173,7 @@ struct hb_trace_t<0> {
  */
 
 #ifndef HB_DEBUG_SANITIZE
-#define HB_DEBUG_SANITIZE HB_DEBUG+0
+#define HB_DEBUG_SANITIZE (HB_DEBUG+0)
 #endif
 
 
@@ -192,17 +192,17 @@ struct hb_sanitize_context_t
     this->edit_count = 0;
     this->debug_depth = 0;
 
-    if (HB_DEBUG_SANITIZE)
+    (void) (HB_DEBUG_SANITIZE &&
       fprintf (stderr, "sanitize %p init [%p..%p] (%lu bytes)\n",
 	       this->blob, this->start, this->end,
-	       (unsigned long) (this->end - this->start));
+	       (unsigned long) (this->end - this->start)));
   }
 
   inline void finish (void)
   {
-    if (HB_DEBUG_SANITIZE)
+    (void) (HB_DEBUG_SANITIZE &&
       fprintf (stderr, "sanitize %p fini [%p..%p] %u edit requests\n",
-	       this->blob, this->start, this->end, this->edit_count);
+	       this->blob, this->start, this->end, this->edit_count));
 
     hb_blob_unlock (this->blob);
     hb_blob_destroy (this->blob);
@@ -217,13 +217,13 @@ struct hb_sanitize_context_t
 	       p <= this->end &&
 	       (unsigned int) (this->end - p) >= len;
 
-    if (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", \
+    (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");
+	       ret ? "pass" : "FAIL"));
 
     return likely (ret);
   }
@@ -233,13 +233,13 @@ struct hb_sanitize_context_t
     const char *p = (const char *) base;
     bool overflows = record_size > 0 && len >= ((unsigned int) -1) / record_size;
 
-    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", \
+    (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");
+	       !overflows ? "does not overflow" : "OVERFLOWS FAIL"));
 
     return likely (!overflows && this->check_range (base, record_size * len));
   }
@@ -255,14 +255,14 @@ struct hb_sanitize_context_t
     const char *p = (const char *) base;
     this->edit_count++;
 
-    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", \
+    (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");
+	       this->writable ? "granted" : "REJECTED"));
 
     return this->writable;
   }
@@ -290,8 +290,8 @@ struct Sanitizer
       return hb_blob_create_empty ();
 
   retry:
-    if (HB_DEBUG_SANITIZE)
-      fprintf (stderr, "Sanitizer %p start %s\n", blob, HB_FUNC);
+    (void) (HB_DEBUG_SANITIZE &&
+      fprintf (stderr, "Sanitizer %p start %s\n", blob, HB_FUNC));
 
     c->init (blob);
 
@@ -305,17 +305,17 @@ struct Sanitizer
     sane = t->sanitize (c);
     if (sane) {
       if (c->edit_count) {
-	if (HB_DEBUG_SANITIZE)
+	(void) (HB_DEBUG_SANITIZE &&
 	  fprintf (stderr, "Sanitizer %p passed first round with %d edits; doing a second round %s\n",
-		   blob, c->edit_count, HB_FUNC);
+		   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) {
-	  if (HB_DEBUG_SANITIZE)
+	  (void) (HB_DEBUG_SANITIZE &&
 	    fprintf (stderr, "Sanitizer %p requested %d edits in second round; FAILLING %s\n",
-		     blob, c->edit_count, HB_FUNC);
+		     blob, c->edit_count, HB_FUNC));
 	  sane = false;
 	}
       }
@@ -325,14 +325,14 @@ struct Sanitizer
       c->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)
-	  fprintf (stderr, "Sanitizer %p retry %s\n", blob, HB_FUNC);
+	(void) (HB_DEBUG_SANITIZE &&
+	  fprintf (stderr, "Sanitizer %p retry %s\n", blob, HB_FUNC));
         goto retry;
       }
     }
 
-    if (HB_DEBUG_SANITIZE)
-      fprintf (stderr, "Sanitizer %p %s %s\n", blob, sane ? "passed" : "FAILED", HB_FUNC);
+    (void) (HB_DEBUG_SANITIZE &&
+      fprintf (stderr, "Sanitizer %p %s %s\n", blob, sane ? "passed" : "FAILED", HB_FUNC));
     if (sane)
       return blob;
     else {
@@ -577,18 +577,16 @@ struct GenericArrayOf
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
     if (unlikely (!sanitize_shallow (c))) 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.
+     * a bound check on the aggregate array size.  We just include
+     * a small unreachable expression to make sure the structs
+     * pointed to do have a simple sanitize(), ie. they do not
+     * reference other structs via offsets.
      */
-    return true;
-    /* We do keep this code though to make sure the structs pointed
-     * to do have a simple sanitize(), ie. they do not reference
-     * other structs. */
-    unsigned int count = len;
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!array[i].sanitize (c)))
-        return false;
+    (void) (false && array[0].sanitize (c));
+
     return true;
   }
   inline bool sanitize (hb_sanitize_context_t *c, void *base) {
@@ -688,18 +686,16 @@ struct HeadlessArrayOf
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
     if (unlikely (!sanitize_shallow (c))) 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.
+     * a bound check on the aggregate array size.  We just include
+     * a small unreachable expression to make sure the structs
+     * pointed to do have a simple sanitize(), ie. they do not
+     * reference other structs via offsets.
      */
-    return true;
-    /* We do keep this code though to make sure the structs pointed
-     * to do have a simple sanitize(), ie. they do not reference
-     * other structs. */
-    unsigned int count = len ? len - 1 : 0;
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!array[i].sanitize (c)))
-        return false;
+    (void) (false && array[0].sanitize (c));
+
     return true;
   }
 
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index b99941e..caba1cf 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -41,7 +41,7 @@ HB_BEGIN_DECLS
 
 
 #ifndef HB_DEBUG_APPLY
-#define HB_DEBUG_APPLY HB_DEBUG+0
+#define HB_DEBUG_APPLY (HB_DEBUG+0)
 #endif
 
 #define TRACE_APPLY() \
diff --git a/src/hb-private.h b/src/hb-private.h
index 1d4cfc9..96b9464 100644
--- a/src/hb-private.h
+++ b/src/hb-private.h
@@ -257,8 +257,7 @@ _hb_trace (const char *what,
 	   unsigned int depth,
 	   unsigned int max_depth)
 {
-  if (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, function));
   return TRUE;
 }
 
commit 2304856340782c72cb30873f7907191dc359e921
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Nov 3 12:46:58 2010 -0400

    Remove another couple lines of dead code

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index afa27ed..b99941e 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -600,7 +600,6 @@ struct ChainRule
 				 lookahead.len, lookahead.array,
 				 lookup.len, lookup.array,
 				 lookup_context);
-    return false;
   }
 
   public:
@@ -786,7 +785,6 @@ struct ChainContextFormat3
 				 lookahead.len, (const USHORT *) lookahead.array,
 				 lookup.len, lookup.array,
 				 lookup_context);
-    return false;
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) {
commit b8783c85ac5dd9ea8f5a66eacb92dfcfbf649a6d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Nov 3 11:50:21 2010 -0400

    Fix unreachable-code warning

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index bcdbfe8..0dc8d17 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -979,8 +979,8 @@ struct MarkBasePosFormat1
     } while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], LookupFlag::IgnoreMarks, &property));
 
     /* The following assertion is too strong, so we've disabled it. */
-    if (false && !(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH))
-      return false;
+    if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH))
+    {/*return false;*/}
 
     unsigned int base_index = (this+baseCoverage) (c->buffer->info[j].codepoint);
     if (base_index == NOT_COVERED)
@@ -1081,8 +1081,8 @@ struct MarkLigPosFormat1
     } while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], LookupFlag::IgnoreMarks, &property));
 
     /* The following assertion is too strong, so we've disabled it. */
-    if (false && !(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE))
-      return false;
+    if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE))
+    {/*return false;*/}
 
     unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoint);
     if (lig_index == NOT_COVERED)
commit c2709119c8c610a0d4d71884a7d4fdba7cb65b72
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 23:18:51 2010 -0400

    Move things around some more

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 782df5f..bcdbfe8 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -1100,9 +1100,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 (c->buffer->info[j].lig_id() && c->buffer->info[j].lig_id() == c->buffer->info[c->buffer->i].lig_id() && c->buffer->info[c->buffer->i].component())
+    if (c->buffer->info[j].lig_id() && c->buffer->info[j].lig_id() == c->buffer->info[c->buffer->i].lig_id() && c->buffer->info[c->buffer->i].lig_comp())
     {
-      comp_index = c->buffer->info[c->buffer->i].component() - 1;
+      comp_index = c->buffer->info[c->buffer->i].lig_comp() - 1;
       if (comp_index >= comp_count)
 	comp_index = comp_count - 1;
     }
@@ -1205,8 +1205,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 ((c->buffer->info[j].component() != c->buffer->info[c->buffer->i].component()) ||
-	(c->buffer->info[j].component() && c->buffer->info[j].lig_id() != c->buffer->info[c->buffer->i].lig_id()))
+    if ((c->buffer->info[j].lig_comp() != c->buffer->info[c->buffer->i].lig_comp()) ||
+	(c->buffer->info[j].lig_comp() && c->buffer->info[j].lig_id() != c->buffer->info[c->buffer->i].lig_id()))
       return false;
 
     unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoint);
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index f63386b..169290b 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -372,7 +372,7 @@ struct Ligature
 
     /* Allocate new ligature id */
     unsigned int lig_id = allocate_lig_id (c->buffer);
-    c->buffer->info[c->buffer->i].component() = 0;
+    c->buffer->info[c->buffer->i].lig_comp() = 0;
     c->buffer->info[c->buffer->i].lig_id() = lig_id;
 
     if (j == c->buffer->i + i) /* No input glyphs skipped */
@@ -394,7 +394,7 @@ struct Ligature
       {
 	while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_props, NULL))
 	{
-	  c->buffer->info[c->buffer->i].component() = i;
+	  c->buffer->info[c->buffer->i].lig_comp() = i;
 	  c->buffer->info[c->buffer->i].lig_id() = lig_id;
 	  c->replace_glyph (c->buffer->info[c->buffer->i].codepoint);
 	}
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 5dd6b31..afa27ed 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -35,6 +35,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) */
+
+
 #ifndef HB_DEBUG_APPLY
 #define HB_DEBUG_APPLY HB_DEBUG+0
 #endif
@@ -72,13 +77,13 @@ struct hb_apply_context_t
 
   inline void guess_glyph_class (unsigned int klass)
   {
-//    buffer->info[buffer->i].gproperty() = klass;
+//    buffer->info[buffer->i].props_cache() = klass;
   }
 
   private:
   inline void clear_property (void) const
   {
-    buffer->info[buffer->i].gproperty() = 0;
+    buffer->info[buffer->i].props_cache() = 0;
   }
 };
 
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 8b475b4..dddbb60 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -38,10 +38,9 @@
 HB_BEGIN_DECLS
 
 
-/* XXX */
-#define component() var1.u16[0]
-#define lig_id() var1.u16[1]
-#define gproperty() var2.u32
+/* buffer var allocations */
+#define props_cache() var1.u16[0] /* glyph_props cache */
+
 
 typedef enum {
   HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED	= 0x0001,
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index fb6914d..755b483 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -106,13 +106,13 @@ unsigned int
 _hb_ot_layout_get_glyph_property (hb_face_t       *face,
 				  hb_glyph_info_t *info)
 {
-  if (!info->gproperty())
+  if (!info->props_cache())
   {
     const GDEF &gdef = _get_gdef (face);
-    info->gproperty() = gdef.get_glyph_props (info->codepoint);
+    info->props_cache() = gdef.get_glyph_props (info->codepoint);
   }
 
-  return info->gproperty();
+  return info->props_cache();
 }
 
 hb_bool_t
commit 194d4566ec054db03fa31d369a9f1c6cf4941e74
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 23:09:10 2010 -0400

    Move buffer var allocation local

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 4903709..782df5f 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -34,6 +34,11 @@
 HB_BEGIN_DECLS
 
 
+/* buffer var allocations */
+#define attach_lookback() var.u16[0] /* number of glyphs to go back to attach this glyph to its base */
+#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */
+
+
 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
 
 typedef USHORT Value;
@@ -402,9 +407,9 @@ struct MarkArray : ArrayOf<MarkRecord>	/* Array of MarkRecords--in Coverage orde
     glyph_anchor.get_anchor (c->layout, c->buffer->info[glyph_pos].codepoint, &base_x, &base_y);
 
     hb_glyph_position_t &o = c->buffer->pos[c->buffer->i];
-    o.x_offset  = base_x - mark_x;
-    o.y_offset  = base_y - mark_y;
-    o.back()    = c->buffer->i - glyph_pos;
+    o.x_offset = base_x - mark_x;
+    o.y_offset = base_y - mark_y;
+    o.attach_lookback() = c->buffer->i - glyph_pos;
 
     c->buffer->i++;
     return true;
@@ -1522,9 +1527,9 @@ GPOS::position_finish (hb_buffer_t *buffer)
 
   /* Handle attachments */
   for (i = 0; i < len; i++)
-    if (pos[i].back())
+    if (pos[i].attach_lookback())
     {
-      unsigned int back = i - pos[i].back();
+      unsigned int back = i - pos[i].attach_lookback();
       pos[i].x_offset += pos[back].x_offset;
       pos[i].y_offset += pos[back].y_offset;
 
@@ -1574,6 +1579,10 @@ static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i
 }
 
 
+#undef attach_lookback
+#undef cursive_chain
+
+
 HB_END_DECLS
 
 #endif /* HB_OT_LAYOUT_GPOS_PRIVATE_HH */
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 4513676..8b475b4 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -42,8 +42,6 @@ HB_BEGIN_DECLS
 #define component() var1.u16[0]
 #define lig_id() var1.u16[1]
 #define gproperty() var2.u32
-#define back() var.u16[0] /* number of glyphs to go back for drawing current glyph */
-#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */
 
 typedef enum {
   HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED	= 0x0001,
commit 1e7c1fcbc33599faefc32d4a28e5d8506d2c56fa
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 22:48:31 2010 -0400

    Move code around

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 2cfabf9..4903709 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -1472,6 +1472,8 @@ struct GPOS : GSUBGPOS
 			       hb_mask_t     mask) const
   { return get_lookup (lookup_index).apply_string (layout, buffer, mask); }
 
+  static inline void position_finish (hb_buffer_t *buffer);
+
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
     if (unlikely (!GSUBGPOS::sanitize (c))) return false;
@@ -1482,6 +1484,63 @@ struct GPOS : GSUBGPOS
   DEFINE_SIZE_STATIC (10);
 };
 
+void
+GPOS::position_finish (hb_buffer_t *buffer)
+{
+  unsigned int i, j;
+  unsigned int len = hb_buffer_get_length (buffer);
+  hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer);
+  hb_direction_t direction = buffer->props.direction;
+
+  /* Handle cursive connections:
+   * First handle all chain-back connections, then handle all chain-forward connections. */
+  if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
+  {
+    for (j = 0; j < len; j++) {
+      if (pos[j].cursive_chain() < 0)
+	pos[j].y_offset += pos[j + pos[j].cursive_chain()].y_offset;
+    }
+    for (i = len; i > 0; i--) {
+      j = i - 1;
+      if (pos[j].cursive_chain() > 0)
+	pos[j].y_offset += pos[j + pos[j].cursive_chain()].y_offset;
+    }
+  }
+  else
+  {
+    for (j = 0; j < len; j++) {
+      if (pos[j].cursive_chain() < 0)
+	pos[j].x_offset += pos[j + pos[j].cursive_chain()].x_offset;
+    }
+    for (i = len; i > 0; i--) {
+      j = i - 1;
+      if (pos[j].cursive_chain() > 0)
+	pos[j].x_offset += pos[j + pos[j].cursive_chain()].x_offset;
+    }
+  }
+
+
+  /* Handle attachments */
+  for (i = 0; i < len; i++)
+    if (pos[i].back())
+    {
+      unsigned int back = i - pos[i].back();
+      pos[i].x_offset += pos[back].x_offset;
+      pos[i].y_offset += pos[back].y_offset;
+
+      if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+	for (j = back + 1; j < i + 1; j++) {
+	  pos[i].x_offset += pos[j].x_advance;
+	  pos[i].y_offset += pos[j].y_advance;
+	}
+      else
+	for (j = back; j < i; j++) {
+	  pos[i].x_offset -= pos[j].x_advance;
+	  pos[i].y_offset -= pos[j].y_advance;
+	}
+    }
+}
+
 
 /* Out-of-class implementation for methods recursing */
 
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 98004e9..fb6914d 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -447,64 +447,9 @@ hb_ot_layout_position_lookup   (hb_font_t    *font,
 }
 
 void
-hb_ot_layout_position_finish (hb_font_t    *font HB_UNUSED,
-			      hb_face_t    *face HB_UNUSED,
-			      hb_buffer_t  *buffer)
+hb_ot_layout_position_finish (hb_buffer_t  *buffer)
 {
-  unsigned int i, j;
-  unsigned int len = hb_buffer_get_length (buffer);
-  hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer);
-  hb_direction_t direction = buffer->props.direction;
-
-  /* TODO: Vertical */
-
-  /* Handle cursive connections:
-   * First handle all chain-back connections, then handle all chain-forward connections. */
-  if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
-  {
-    for (j = 0; j < len; j++) {
-      if (pos[j].cursive_chain() < 0)
-	pos[j].y_offset += pos[j + pos[j].cursive_chain()].y_offset;
-    }
-    for (i = len; i > 0; i--) {
-      j = i - 1;
-      if (pos[j].cursive_chain() > 0)
-	pos[j].y_offset += pos[j + pos[j].cursive_chain()].y_offset;
-    }
-  }
-  else
-  {
-    for (j = 0; j < len; j++) {
-      if (pos[j].cursive_chain() < 0)
-	pos[j].x_offset += pos[j + pos[j].cursive_chain()].x_offset;
-    }
-    for (i = len; i > 0; i--) {
-      j = i - 1;
-      if (pos[j].cursive_chain() > 0)
-	pos[j].x_offset += pos[j + pos[j].cursive_chain()].x_offset;
-    }
-  }
-
-
-  /* Handle attachments */
-  for (i = 0; i < len; i++)
-    if (pos[i].back())
-    {
-      unsigned int back = i - pos[i].back();
-      pos[i].x_offset += pos[back].x_offset;
-      pos[i].y_offset += pos[back].y_offset;
-
-      if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
-	for (j = back + 1; j < i + 1; j++) {
-	  pos[i].x_offset += pos[j].x_advance;
-	  pos[i].y_offset += pos[j].y_advance;
-	}
-      else
-	for (j = back; j < i; j++) {
-	  pos[i].x_offset -= pos[j].x_advance;
-	  pos[i].y_offset -= pos[j].y_advance;
-	}
-    }
+  GPOS::position_finish (buffer);
 }
 
 
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 58c0fbe..9619eb7 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -188,9 +188,7 @@ hb_ot_layout_position_lookup (hb_font_t    *font,
 
 /* Should be called after all the position_lookup's are done */
 void
-hb_ot_layout_position_finish (hb_font_t    *font,
-			      hb_face_t    *face,
-			      hb_buffer_t  *buffer);
+hb_ot_layout_position_finish (hb_buffer_t  *buffer);
 
 
 HB_END_DECLS
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 06316bc..a4e568d 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -121,7 +121,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
 
   c->plan->map.position (c->font, c->face, c->buffer);
 
-  hb_ot_layout_position_finish (c->font, c->face, c->buffer);
+  hb_ot_layout_position_finish (c->buffer);
 
   c->applied_position_complex = TRUE;
   return;
commit bf94b3ad22b2fe4730d4e64d673c63154fc5b5fe
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 22:37:59 2010 -0400

    Move some more code around

diff --git a/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh
index 209f00a..4172a7c 100644
--- a/src/hb-ot-layout-gdef-private.hh
+++ b/src/hb-ot-layout-gdef-private.hh
@@ -374,6 +374,27 @@ struct GDEF
 	&& (version < 0x00010002 || markGlyphSetsDef[0].sanitize (c, this));
   }
 
+
+  /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
+   * glyph class and other bits, and high 8-bit gthe mark attachment type (if any).
+   * Not to be confused with lookup_props which is very similar. */
+  inline unsigned int get_glyph_props (hb_codepoint_t glyph) const
+  {
+    unsigned int klass = get_glyph_class (glyph);
+
+    switch (klass) {
+    default:
+    case UnclassifiedGlyph:	return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
+    case BaseGlyph:		return HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
+    case LigatureGlyph:		return HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE;
+    case ComponentGlyph:	return HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT;
+    case MarkGlyph:
+	  klass = get_mark_attachment_type (glyph);
+	  return HB_OT_LAYOUT_GLYPH_CLASS_MARK | (klass << 8);
+    }
+  }
+
+
   private:
   FixedVersion	version;		/* Version of the GDEF table--currently
 					 * 0x00010002 */
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index d9d65a5..4513676 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -46,11 +46,11 @@ HB_BEGIN_DECLS
 #define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */
 
 typedef enum {
+  HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED	= 0x0001,
   HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH	= 0x0002,
   HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE	= 0x0004,
   HB_OT_LAYOUT_GLYPH_CLASS_MARK		= 0x0008,
-  HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT	= 0x0010,
-  HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED	= 0x0020
+  HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT	= 0x0010
 } hb_ot_layout_glyph_class_t;
 
 
@@ -94,17 +94,36 @@ _hb_ot_layout_free (hb_ot_layout_t *layout);
  * GDEF
  */
 
+HB_INTERNAL unsigned int
+_hb_ot_layout_get_glyph_property (hb_face_t       *face,
+				  hb_glyph_info_t *info);
+
 HB_INTERNAL hb_bool_t
 _hb_ot_layout_check_glyph_property (hb_face_t    *face,
 				    hb_glyph_info_t *ginfo,
 				    unsigned int  lookup_props,
 				    unsigned int *property);
 
-HB_INTERNAL hb_bool_t
+static inline hb_bool_t
 _hb_ot_layout_skip_mark (hb_face_t    *face,
 			 hb_glyph_info_t *ginfo,
 			 unsigned int  lookup_props,
-			 unsigned int *property);
+			 unsigned int *property_out)
+{
+  unsigned int property;
+
+  property = _hb_ot_layout_get_glyph_property (face, ginfo);
+  if (property_out)
+    *property_out = property;
+
+  /* If it's a mark, skip it we don't accept it. */
+  if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
+    return !_hb_ot_layout_check_glyph_property (face, ginfo, lookup_props, NULL);
+
+  /* If not a mark, don't skip. */
+  return false;
+}
+
 
 
 HB_END_DECLS
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index ca13a4d..98004e9 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -73,19 +73,19 @@ _hb_ot_layout_free (hb_ot_layout_t *layout)
   free (layout);
 }
 
-static const GDEF&
+static inline const GDEF&
 _get_gdef (hb_face_t *face)
 {
   return likely (face->ot_layout && face->ot_layout->gdef) ? *face->ot_layout->gdef : Null(GDEF);
 }
 
-static const GSUB&
+static inline const GSUB&
 _get_gsub (hb_face_t *face)
 {
   return likely (face->ot_layout && face->ot_layout->gsub) ? *face->ot_layout->gsub : Null(GSUB);
 }
 
-static const GPOS&
+static inline const GPOS&
 _get_gpos (hb_face_t *face)
 {
   return likely (face->ot_layout && face->ot_layout->gpos) ? *face->ot_layout->gpos : Null(GPOS);
@@ -102,35 +102,15 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face)
   return _get_gdef (face).has_glyph_classes ();
 }
 
-static unsigned int
-_hb_ot_layout_get_glyph_property_from_gdef (hb_face_t       *face,
-					    hb_glyph_info_t *info)
-{
-  hb_codepoint_t glyph = info->codepoint;
-
-  unsigned int klass;
-  const GDEF &gdef = _get_gdef (face);
-
-  klass = gdef.get_glyph_class (glyph);
-
-  switch (klass) {
-  default:
-  case GDEF::UnclassifiedGlyph:	return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
-  case GDEF::BaseGlyph:		return HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
-  case GDEF::LigatureGlyph:	return HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE;
-  case GDEF::ComponentGlyph:	return HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT;
-  case GDEF::MarkGlyph:
-	klass = gdef.get_mark_attachment_type (glyph);
-	return HB_OT_LAYOUT_GLYPH_CLASS_MARK | (klass << 8);
-  }
-}
-
-static inline unsigned int
+unsigned int
 _hb_ot_layout_get_glyph_property (hb_face_t       *face,
 				  hb_glyph_info_t *info)
 {
   if (!info->gproperty())
-    info->gproperty() = _hb_ot_layout_get_glyph_property_from_gdef (face, info);
+  {
+    const GDEF &gdef = _get_gdef (face);
+    info->gproperty() = gdef.get_glyph_props (info->codepoint);
+  }
 
   return info->gproperty();
 }
@@ -172,26 +152,6 @@ _hb_ot_layout_check_glyph_property (hb_face_t    *face,
   return true;
 }
 
-hb_bool_t
-_hb_ot_layout_skip_mark (hb_face_t    *face,
-			 hb_glyph_info_t *ginfo,
-			 unsigned int  lookup_props,
-			 unsigned int *property_out)
-{
-  unsigned int property;
-
-  property = _hb_ot_layout_get_glyph_property (face, ginfo);
-  if (property_out)
-    *property_out = property;
-
-  /* If it's a mark, skip it we don't accept it. */
-  if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
-    return !_hb_ot_layout_check_glyph_property (face, ginfo, lookup_props, NULL);
-
-  /* If not a mark, don't skip. */
-  return false;
-}
-
 unsigned int
 hb_ot_layout_get_attach_points (hb_face_t      *face,
 				hb_codepoint_t  glyph,
commit 6334658fe79d6acfb46a2a147721b78f92510ebb
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 22:11:32 2010 -0400

    Simplify mark skipping logic

diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index e4f5e2d..ca13a4d 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -184,22 +184,11 @@ _hb_ot_layout_skip_mark (hb_face_t    *face,
   if (property_out)
     *property_out = property;
 
+  /* If it's a mark, skip it we don't accept it. */
   if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
-  {
-    /* Skip mark if lookup_props includes LookupFlags::IgnoreMarks */
-    if (lookup_props & LookupFlag::IgnoreMarks)
-      return true;
-
-    /* If using mark filtering sets, the high short of lookup_props has the set index. */
-    if (lookup_props & LookupFlag::UseMarkFilteringSet)
-      return !_get_gdef (face).mark_set_covers (lookup_props >> 16, ginfo->codepoint);
-
-    /* The second byte of lookup_props has the meaning "ignore marks of attachment type
-     * different than the attachment type specified." */
-    if (lookup_props & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType)
-      return (lookup_props & LookupFlag::MarkAttachmentType) != (property & LookupFlag::MarkAttachmentType);
-  }
+    return !_hb_ot_layout_check_glyph_property (face, ginfo, lookup_props, NULL);
 
+  /* If not a mark, don't skip. */
   return false;
 }
 
commit 8c69e65abed961002d90024c92e18538c6516262
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 22:07:49 2010 -0400

    Rename lookup_flags to lookup_props since it's more than just flags

diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 2ba0ef4..2855425 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -290,7 +290,11 @@ struct Lookup
   inline unsigned int get_subtable_count (void) const { return subTable.len; }
 
   inline unsigned int get_type (void) const { return lookupType; }
-  inline unsigned int get_flag (void) const
+
+  /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
+   * higher 16-bit is mark-filtering-set if the lookup uses one.
+   * Not to be confused with glyph_props which is very similar. */
+  inline uint32_t get_props (void) const
   {
     unsigned int flag = lookupFlag;
     if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index cb97cfb..2cfabf9 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -625,7 +625,7 @@ struct PairPosFormat1
       return false;
 
     unsigned int j = c->buffer->i + 1;
-    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL))
     {
       if (unlikely (j == end))
 	return false;
@@ -687,7 +687,7 @@ struct PairPosFormat2
       return false;
 
     unsigned int j = c->buffer->i + 1;
-    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL))
     {
       if (unlikely (j == end))
 	return false;
@@ -840,7 +840,7 @@ struct CursivePosFormat1
       return false;
 
     unsigned int j = c->buffer->i + 1;
-    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL))
     {
       if (unlikely (j == end))
 	return false;
@@ -876,7 +876,7 @@ struct CursivePosFormat1
 	c->buffer->pos[i].y_advance = c->buffer->pos[i].y_offset + exit_y - entry_y;
     }
 
-    if  (c->lookup_flag & LookupFlag::RightToLeft)
+    if  (c->lookup_props & LookupFlag::RightToLeft)
     {
       c->buffer->pos[i].cursive_chain() = j - i;
       if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
@@ -1192,7 +1192,7 @@ struct MarkMarkPosFormat1
       if (unlikely (!j))
 	return false;
       j--;
-    } while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_flag, &property));
+    } while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, &property));
 
     if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
       return false;
@@ -1411,9 +1411,9 @@ struct PosLookup : Lookup
     c->lookup_mask = lookup_mask;
     c->context_length = context_length;
     c->nesting_level_left = nesting_level_left;
-    c->lookup_flag = get_flag ();
+    c->lookup_props = get_props ();
 
-    if (!_hb_ot_layout_check_glyph_property (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_flag, &c->property))
+    if (!_hb_ot_layout_check_glyph_property (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_props, &c->property))
       return false;
 
     for (unsigned int i = 0; i < get_subtable_count (); i++)
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index a69f41f..f63386b 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -354,7 +354,7 @@ struct Ligature
     for (i = 1, j = c->buffer->i + 1; i < count; i++, j++)
     {
       unsigned int property;
-      while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_flag, &property))
+      while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, &property))
       {
 	if (unlikely (j + count - i == end))
 	  return false;
@@ -392,7 +392,7 @@ struct Ligature
 
       for (i = 1; i < count; i++)
       {
-	while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_flag, NULL))
+	while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_props, NULL))
 	{
 	  c->buffer->info[c->buffer->i].component() = i;
 	  c->buffer->info[c->buffer->i].lig_id() = lig_id;
@@ -776,9 +776,9 @@ struct SubstLookup : Lookup
     c->lookup_mask = lookup_mask;
     c->context_length = context_length;
     c->nesting_level_left = nesting_level_left;
-    c->lookup_flag = get_flag ();
+    c->lookup_props = get_props ();
 
-    if (!_hb_ot_layout_check_glyph_property (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_flag, &c->property))
+    if (!_hb_ot_layout_check_glyph_property (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_props, &c->property))
       return false;
 
     if (unlikely (lookup_type == SubstLookupSubTable::Extension))
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 5dc6f3a..5dd6b31 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -53,7 +53,7 @@ struct hb_apply_context_t
   hb_mask_t lookup_mask;
   unsigned int context_length;
   unsigned int nesting_level_left;
-  unsigned int lookup_flag;
+  unsigned int lookup_props;
   unsigned int property; /* propety of first glyph */
 
 
@@ -126,7 +126,7 @@ static inline bool match_input (hb_apply_context_t *c,
 
   for (i = 1, j = c->buffer->i + 1; i < count; i++, j++)
   {
-    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL))
     {
       if (unlikely (j + count - i == end))
 	return false;
@@ -153,7 +153,7 @@ static inline bool match_backtrack (hb_apply_context_t *c,
 
   for (unsigned int i = 0, j = c->buffer->out_len - 1; i < count; i++, j--)
   {
-    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->out_info[j], c->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->out_info[j], c->lookup_props, NULL))
     {
       if (unlikely (j + 1 == count - i))
 	return false;
@@ -181,7 +181,7 @@ static inline bool match_lookahead (hb_apply_context_t *c,
 
   for (i = 0, j = c->buffer->i + offset; i < count; i++, j++)
   {
-    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_props, NULL))
     {
       if (unlikely (j + count - i == end))
 	return false;
@@ -235,7 +235,7 @@ static inline bool apply_lookup (hb_apply_context_t *c,
    */
   for (unsigned int i = 0; i < count; /* NOP */)
   {
-    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_flag, NULL))
+    while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_props, NULL))
     {
       if (unlikely (c->buffer->i == end))
 	return true;
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index a088687..d9d65a5 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -97,13 +97,13 @@ _hb_ot_layout_free (hb_ot_layout_t *layout);
 HB_INTERNAL hb_bool_t
 _hb_ot_layout_check_glyph_property (hb_face_t    *face,
 				    hb_glyph_info_t *ginfo,
-				    unsigned int  lookup_flags,
+				    unsigned int  lookup_props,
 				    unsigned int *property);
 
 HB_INTERNAL hb_bool_t
 _hb_ot_layout_skip_mark (hb_face_t    *face,
 			 hb_glyph_info_t *ginfo,
-			 unsigned int  lookup_flags,
+			 unsigned int  lookup_props,
 			 unsigned int *property);
 
 
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index d128fdb..e4f5e2d 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -138,7 +138,7 @@ _hb_ot_layout_get_glyph_property (hb_face_t       *face,
 hb_bool_t
 _hb_ot_layout_check_glyph_property (hb_face_t    *face,
 				    hb_glyph_info_t *ginfo,
-				    unsigned int  lookup_flags,
+				    unsigned int  lookup_props,
 				    unsigned int *property_out)
 {
   unsigned int property;
@@ -148,25 +148,25 @@ _hb_ot_layout_check_glyph_property (hb_face_t    *face,
     *property_out = property;
 
   /* Not covered, if, for example, glyph class is ligature and
-   * lookup_flags includes LookupFlags::IgnoreLigatures
+   * lookup_props includes LookupFlags::IgnoreLigatures
    */
-  if (property & lookup_flags & LookupFlag::IgnoreFlags)
+  if (property & lookup_props & LookupFlag::IgnoreFlags)
     return false;
 
   if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
   {
     /* If using mark filtering sets, the high short of
-     * lookup_flags has the set index.
+     * lookup_props has the set index.
      */
-    if (lookup_flags & LookupFlag::UseMarkFilteringSet)
-      return _get_gdef (face).mark_set_covers (lookup_flags >> 16, ginfo->codepoint);
+    if (lookup_props & LookupFlag::UseMarkFilteringSet)
+      return _get_gdef (face).mark_set_covers (lookup_props >> 16, ginfo->codepoint);
 
-    /* The second byte of lookup_flags has the meaning
+    /* The second byte of lookup_props has the meaning
      * "ignore marks of attachment type different than
      * the attachment type specified."
      */
-    if (lookup_flags & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType)
-      return (lookup_flags & LookupFlag::MarkAttachmentType) == (property & LookupFlag::MarkAttachmentType);
+    if (lookup_props & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType)
+      return (lookup_props & LookupFlag::MarkAttachmentType) == (property & LookupFlag::MarkAttachmentType);
   }
 
   return true;
@@ -175,7 +175,7 @@ _hb_ot_layout_check_glyph_property (hb_face_t    *face,
 hb_bool_t
 _hb_ot_layout_skip_mark (hb_face_t    *face,
 			 hb_glyph_info_t *ginfo,
-			 unsigned int  lookup_flags,
+			 unsigned int  lookup_props,
 			 unsigned int *property_out)
 {
   unsigned int property;
@@ -186,18 +186,18 @@ _hb_ot_layout_skip_mark (hb_face_t    *face,
 
   if (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
   {
-    /* Skip mark if lookup_flags includes LookupFlags::IgnoreMarks */
-    if (lookup_flags & LookupFlag::IgnoreMarks)
+    /* Skip mark if lookup_props includes LookupFlags::IgnoreMarks */
+    if (lookup_props & LookupFlag::IgnoreMarks)
       return true;
 
-    /* If using mark filtering sets, the high short of lookup_flags has the set index. */
-    if (lookup_flags & LookupFlag::UseMarkFilteringSet)
-      return !_get_gdef (face).mark_set_covers (lookup_flags >> 16, ginfo->codepoint);
+    /* If using mark filtering sets, the high short of lookup_props has the set index. */
+    if (lookup_props & LookupFlag::UseMarkFilteringSet)
+      return !_get_gdef (face).mark_set_covers (lookup_props >> 16, ginfo->codepoint);
 
-    /* The second byte of lookup_flags has the meaning "ignore marks of attachment type
+    /* The second byte of lookup_props has the meaning "ignore marks of attachment type
      * different than the attachment type specified." */
-    if (lookup_flags & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType)
-      return (lookup_flags & LookupFlag::MarkAttachmentType) != (property & LookupFlag::MarkAttachmentType);
+    if (lookup_props & LookupFlag::MarkAttachmentType && property & LookupFlag::MarkAttachmentType)
+      return (lookup_props & LookupFlag::MarkAttachmentType) != (property & LookupFlag::MarkAttachmentType);
   }
 
   return false;
diff --git a/src/main.cc b/src/main.cc
index 083908e..8126dae 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -161,8 +161,8 @@ main (int argc, char **argv)
 	printf ("    %d lookup(s) found in table\n", num_lookups);
 	for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
 	  const Lookup &lookup = g.get_lookup (n_lookup);
-	  printf ("    Lookup %2d of %2d: type %d, flags 0x%04X\n", n_lookup, num_lookups,
-	          lookup.get_type(), lookup.get_flag());
+	  printf ("    Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup, num_lookups,
+	          lookup.get_type(), lookup.get_props());
 	}
 
 	}
commit 98370e89d1bff248737b482d129c2a4deb8bfd95
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 17:39:01 2010 -0400

    WIP removing external synthesized GDEF support and implementing it internally

diff --git a/TODO b/TODO
index d206da1..fb6a86f 100644
--- a/TODO
+++ b/TODO
@@ -3,8 +3,6 @@ General fixes:
 
 - Fix tt kern on/off
 
-- Remove synthesized GDEF
-
 - Remove fixed-size feature/lookup arrays in hb-ot-map
 
 - Use size_t in sanitize
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index de698ed..a129165 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -35,10 +35,6 @@
 HB_BEGIN_DECLS
 
 
-/* XXX */
-#define HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
-#define gproperty() var2.u32
-
 ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20);
 ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
 
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index daf9d53..03e8e1a 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -253,7 +253,6 @@ hb_buffer_add_glyph (hb_buffer_t    *buffer,
   glyph->codepoint = codepoint;
   glyph->mask = mask;
   glyph->cluster = cluster;
-  glyph->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
 
   buffer->len++;
 }
@@ -330,7 +329,6 @@ _hb_buffer_replace_glyphs_be16 (hb_buffer_t *buffer,
     hb_glyph_info_t *info = &buffer->out_info[buffer->out_len + i];
     *info = orig_info;
     info->codepoint = hb_be_uint16 (glyph_data_be[i]);
-    info->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
   }
 
   buffer->i  += num_in;
@@ -353,7 +351,6 @@ _hb_buffer_replace_glyph (hb_buffer_t *buffer,
 
   info = &buffer->out_info[buffer->out_len];
   info->codepoint = glyph_index;
-  info->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
 
   buffer->i++;
   buffer->out_len++;
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index ccbd939..2ba0ef4 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -431,7 +431,7 @@ struct ClassDefFormat1
   friend struct ClassDef;
 
   private:
-  inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const
+  inline unsigned int get_class (hb_codepoint_t glyph_id) const
   {
     if ((unsigned int) (glyph_id - startGlyph) < classValue.len)
       return classValue[glyph_id - startGlyph];
@@ -457,7 +457,7 @@ struct ClassDefFormat2
   friend struct ClassDef;
 
   private:
-  inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const
+  inline unsigned int get_class (hb_codepoint_t glyph_id) const
   {
     int i = rangeRecord.search (glyph_id);
     if (i != -1)
@@ -480,9 +480,9 @@ struct ClassDefFormat2
 
 struct ClassDef
 {
-  inline hb_ot_layout_class_t operator () (hb_codepoint_t glyph_id) const { return get_class (glyph_id); }
+  inline unsigned int operator () (hb_codepoint_t glyph_id) const { return get_class (glyph_id); }
 
-  inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const
+  inline unsigned int get_class (hb_codepoint_t glyph_id) const
   {
     switch (u.format) {
     case 1: return u.format1.get_class(glyph_id);
diff --git a/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh
index c7bd738..209f00a 100644
--- a/src/hb-ot-layout-gdef-private.hh
+++ b/src/hb-ot-layout-gdef-private.hh
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007,2008,2009  Red Hat, Inc.
+ * Copyright (C) 2010  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -22,6 +23,7 @@
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
  */
 
 #ifndef HB_OT_LAYOUT_GDEF_PRIVATE_HH
@@ -335,11 +337,11 @@ struct GDEF
   };
 
   inline bool has_glyph_classes (void) const { return glyphClassDef != 0; }
-  inline hb_ot_layout_class_t get_glyph_class (hb_codepoint_t glyph) const
+  inline unsigned int get_glyph_class (hb_codepoint_t glyph) const
   { return (this+glyphClassDef).get_class (glyph); }
 
   inline bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; }
-  inline hb_ot_layout_class_t get_mark_attachment_type (hb_codepoint_t glyph) const
+  inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
   { return (this+markAttachClassDef).get_class (glyph); }
 
   inline bool has_attach_points (void) const { return attachList != 0; }
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 5cf9379..cb97cfb 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright (C) 2010  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -22,6 +23,7 @@
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
  */
 
 #ifndef HB_OT_LAYOUT_GPOS_PRIVATE_HH
@@ -826,7 +828,7 @@ struct CursivePosFormat1
     TRACE_APPLY ();
 
     /* We don't handle mark glyphs here. */
-    if (c->property == HB_OT_LAYOUT_GLYPH_CLASS_MARK)
+    if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
       return false;
 
     unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length);
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 577b34b..a69f41f 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright (C) 2010  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -22,6 +23,7 @@
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
  */
 
 #ifndef HB_OT_LAYOUT_GSUB_PRIVATE_HH
@@ -47,11 +49,7 @@ struct SingleSubstFormat1
       return false;
 
     glyph_id += deltaGlyphID;
-    c->buffer->replace_glyph (glyph_id);
-
-    /* We inherit the old glyph class to the substituted glyph */
-    if (_hb_ot_layout_has_new_glyph_classes (c->layout->face))
-      _hb_ot_layout_set_glyph_property (c->layout->face, glyph_id, c->property);
+    c->replace_glyph (glyph_id);
 
     return true;
   }
@@ -91,11 +89,7 @@ struct SingleSubstFormat2
       return false;
 
     glyph_id = substitute[index];
-    c->buffer->replace_glyph (glyph_id);
-
-    /* We inherit the old glyph class to the substituted glyph */
-    if (_hb_ot_layout_has_new_glyph_classes (c->layout->face))
-      _hb_ot_layout_set_glyph_property (c->layout->face, glyph_id, c->property);
+    c->replace_glyph (glyph_id);
 
     return true;
   }
@@ -164,19 +158,9 @@ struct Sequence
     if (unlikely (!substitute.len))
       return false;
 
-    c->buffer->replace_glyphs_be16 (1, substitute.len, (const uint16_t *) substitute.array);
-
-    /* This is a guess only ... */
-    if (_hb_ot_layout_has_new_glyph_classes (c->layout->face))
-    {
-      unsigned int property = c->property;
-      if (property == HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)
-        property = HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
-
-      unsigned int count = substitute.len;
-      for (unsigned int n = 0; n < count; n++)
-	_hb_ot_layout_set_glyph_property (c->layout->face, substitute[n], property);
-    }
+    if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)
+      c->guess_glyph_class (HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH);
+    c->replace_glyphs_be16 (1, substitute.len, (const uint16_t *) substitute.array);
 
     return true;
   }
@@ -295,11 +279,7 @@ struct AlternateSubstFormat1
 
     glyph_id = alt_set[alt_index - 1];
 
-    c->buffer->replace_glyph (glyph_id);
-
-    /* We inherit the old glyph class to the substituted glyph */
-    if (_hb_ot_layout_has_new_glyph_classes (c->layout->face))
-      _hb_ot_layout_set_glyph_property (c->layout->face, glyph_id, c->property);
+    c->replace_glyph (glyph_id);
 
     return true;
   }
@@ -359,7 +339,7 @@ struct Ligature
   friend struct LigatureSet;
 
   private:
-  inline bool apply (hb_apply_context_t *c, bool is_mark) const
+  inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY ();
     unsigned int i, j;
@@ -368,6 +348,9 @@ struct Ligature
     if (unlikely (c->buffer->i + count > end))
       return false;
 
+    bool first_was_mark = (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
+    bool found_non_mark = false;
+
     for (i = 1, j = c->buffer->i + 1; i < count; i++, j++)
     {
       unsigned int property;
@@ -378,17 +361,14 @@ struct Ligature
 	j++;
       }
 
-      if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
-	is_mark = false;
+      found_non_mark |= !(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
 
       if (likely (c->buffer->info[j].codepoint != component[i]))
         return false;
     }
-    /* This is just a guess ... */
-    if (_hb_ot_layout_has_new_glyph_classes (c->layout->face))
-      _hb_ot_layout_set_glyph_class (c->layout->face, ligGlyph,
-				     is_mark ? HB_OT_LAYOUT_GLYPH_CLASS_MARK
-					     : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE);
+
+    if (first_was_mark && found_non_mark)
+      c->guess_glyph_class (HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE);
 
     /* Allocate new ligature id */
     unsigned int lig_id = allocate_lig_id (c->buffer);
@@ -397,11 +377,11 @@ struct Ligature
 
     if (j == c->buffer->i + i) /* No input glyphs skipped */
     {
-      c->buffer->replace_glyphs_be16 (i, 1, (const uint16_t *) &ligGlyph);
+      c->replace_glyphs_be16 (i, 1, (const uint16_t *) &ligGlyph);
     }
     else
     {
-      c->buffer->replace_glyph (ligGlyph);
+      c->replace_glyph (ligGlyph);
 
       /* Now we must do a second loop to copy the skipped glyphs to
 	 `out' and assign component values to it.  We start with the
@@ -416,7 +396,7 @@ struct Ligature
 	{
 	  c->buffer->info[c->buffer->i].component() = i;
 	  c->buffer->info[c->buffer->i].lig_id() = lig_id;
-	  c->buffer->replace_glyph (c->buffer->info[c->buffer->i].codepoint);
+	  c->replace_glyph (c->buffer->info[c->buffer->i].codepoint);
 	}
 
 	/* Skip the base glyph */
@@ -455,14 +435,14 @@ struct LigatureSet
   friend struct LigatureSubstFormat1;
 
   private:
-  inline bool apply (hb_apply_context_t *c, bool is_mark) const
+  inline bool apply (hb_apply_context_t *c) 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 (c, is_mark))
+      if (lig.apply (c))
         return true;
     }
 
@@ -493,14 +473,12 @@ struct LigatureSubstFormat1
     TRACE_APPLY ();
     hb_codepoint_t glyph_id = c->buffer->info[c->buffer->i].codepoint;
 
-    bool first_is_mark = !!(c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
-
     unsigned int index = (this+coverage) (glyph_id);
     if (likely (index == NOT_COVERED))
       return false;
 
     const LigatureSet &lig_set = this+ligatureSet[index];
-    return lig_set.apply (c, first_is_mark);
+    return lig_set.apply (c);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) {
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 8268d0f..5dc6f3a 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright (C) 2010  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -22,6 +23,7 @@
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
  */
 
 #ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH
@@ -52,7 +54,32 @@ struct hb_apply_context_t
   unsigned int context_length;
   unsigned int nesting_level_left;
   unsigned int lookup_flag;
-  unsigned int property; /* propety of first glyph (TODO remove) */
+  unsigned int property; /* propety of first glyph */
+
+
+  inline void replace_glyph (hb_codepoint_t glyph_index) const
+  {
+    clear_property ();
+    buffer->replace_glyph (glyph_index);
+  }
+  inline void replace_glyphs_be16 (unsigned int num_in,
+				   unsigned int num_out,
+				   const uint16_t *glyph_data_be) const
+  {
+    clear_property ();
+    buffer->replace_glyphs_be16 (num_in, num_out, glyph_data_be);
+  }
+
+  inline void guess_glyph_class (unsigned int klass)
+  {
+//    buffer->info[buffer->i].gproperty() = klass;
+  }
+
+  private:
+  inline void clear_property (void) const
+  {
+    buffer->info[buffer->i].gproperty() = 0;
+  }
 };
 
 
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index f28e99d..a088687 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -41,10 +41,18 @@ HB_BEGIN_DECLS
 /* XXX */
 #define component() var1.u16[0]
 #define lig_id() var1.u16[1]
+#define gproperty() var2.u32
 #define back() var.u16[0] /* number of glyphs to go back for drawing current glyph */
 #define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */
 
-typedef unsigned int hb_ot_layout_class_t;
+typedef enum {
+  HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH	= 0x0002,
+  HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE	= 0x0004,
+  HB_OT_LAYOUT_GLYPH_CLASS_MARK		= 0x0008,
+  HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT	= 0x0010,
+  HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED	= 0x0020
+} hb_ot_layout_glyph_class_t;
+
 
 /*
  * hb_ot_layout_t
@@ -59,12 +67,6 @@ struct hb_ot_layout_t
   const struct GDEF *gdef;
   const struct GSUB *gsub;
   const struct GPOS *gpos;
-
-  struct
-  {
-    unsigned char *klasses;
-    unsigned int len;
-  } new_gdef;
 };
 
 struct hb_ot_layout_context_t
@@ -93,19 +95,6 @@ _hb_ot_layout_free (hb_ot_layout_t *layout);
  */
 
 HB_INTERNAL hb_bool_t
-_hb_ot_layout_has_new_glyph_classes (hb_face_t *face);
-
-HB_INTERNAL void
-_hb_ot_layout_set_glyph_property (hb_face_t      *face,
-				  hb_codepoint_t  glyph,
-				  unsigned int    property);
-
-HB_INTERNAL void
-_hb_ot_layout_set_glyph_class (hb_face_t                  *face,
-			       hb_codepoint_t              glyph,
-			       hb_ot_layout_glyph_class_t  klass);
-
-HB_INTERNAL hb_bool_t
 _hb_ot_layout_check_glyph_property (hb_face_t    *face,
 				    hb_glyph_info_t *ginfo,
 				    unsigned int  lookup_flags,
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index a705b66..d128fdb 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -70,8 +70,6 @@ _hb_ot_layout_free (hb_ot_layout_t *layout)
   hb_blob_destroy (layout->gsub_blob);
   hb_blob_destroy (layout->gpos_blob);
 
-  free (layout->new_gdef.klasses);
-
   free (layout);
 }
 
@@ -98,32 +96,23 @@ _get_gpos (hb_face_t *face)
  * GDEF
  */
 
-/* TODO the public class_t is a mess */
-
 hb_bool_t
 hb_ot_layout_has_glyph_classes (hb_face_t *face)
 {
   return _get_gdef (face).has_glyph_classes ();
 }
 
-hb_bool_t
-_hb_ot_layout_has_new_glyph_classes (hb_face_t *face)
-{
-  return face->ot_layout->new_gdef.len > 0;
-}
-
 static unsigned int
-_hb_ot_layout_get_glyph_property (hb_face_t      *face,
-				  hb_codepoint_t  glyph)
+_hb_ot_layout_get_glyph_property_from_gdef (hb_face_t       *face,
+					    hb_glyph_info_t *info)
 {
-  hb_ot_layout_class_t klass;
+  hb_codepoint_t glyph = info->codepoint;
+
+  unsigned int klass;
   const GDEF &gdef = _get_gdef (face);
 
   klass = gdef.get_glyph_class (glyph);
 
-  if (!klass && glyph < face->ot_layout->new_gdef.len)
-    klass = face->ot_layout->new_gdef.klasses[glyph];
-
   switch (klass) {
   default:
   case GDEF::UnclassifiedGlyph:	return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
@@ -132,10 +121,20 @@ _hb_ot_layout_get_glyph_property (hb_face_t      *face,
   case GDEF::ComponentGlyph:	return HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT;
   case GDEF::MarkGlyph:
 	klass = gdef.get_mark_attachment_type (glyph);
-	return HB_OT_LAYOUT_GLYPH_CLASS_MARK + (klass << 8);
+	return HB_OT_LAYOUT_GLYPH_CLASS_MARK | (klass << 8);
   }
 }
 
+static inline unsigned int
+_hb_ot_layout_get_glyph_property (hb_face_t       *face,
+				  hb_glyph_info_t *info)
+{
+  if (!info->gproperty())
+    info->gproperty() = _hb_ot_layout_get_glyph_property_from_gdef (face, info);
+
+  return info->gproperty();
+}
+
 hb_bool_t
 _hb_ot_layout_check_glyph_property (hb_face_t    *face,
 				    hb_glyph_info_t *ginfo,
@@ -144,9 +143,7 @@ _hb_ot_layout_check_glyph_property (hb_face_t    *face,
 {
   unsigned int property;
 
-  if (ginfo->gproperty() == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
-    ginfo->gproperty() = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint);
-  property = ginfo->gproperty();
+  property = _hb_ot_layout_get_glyph_property (face, ginfo);
   if (property_out)
     *property_out = property;
 
@@ -183,9 +180,7 @@ _hb_ot_layout_skip_mark (hb_face_t    *face,
 {
   unsigned int property;
 
-  if (ginfo->gproperty() == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
-    ginfo->gproperty() = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint);
-  property = ginfo->gproperty();
+  property = _hb_ot_layout_get_glyph_property (face, ginfo);
   if (property_out)
     *property_out = property;
 
@@ -208,103 +203,6 @@ _hb_ot_layout_skip_mark (hb_face_t    *face,
   return false;
 }
 
-void
-_hb_ot_layout_set_glyph_class (hb_face_t                  *face,
-			       hb_codepoint_t              glyph,
-			       hb_ot_layout_glyph_class_t  klass)
-{
-  if (HB_OBJECT_IS_INERT (face))
-    return;
-
-  /* TODO optimize this? similar to old harfbuzz code for example */
-
-  hb_ot_layout_t *layout = face->ot_layout;
-  hb_ot_layout_class_t gdef_klass;
-  unsigned int len = layout->new_gdef.len;
-
-  if (unlikely (glyph > 65535))
-    return;
-
-  /* XXX this is not threadsafe */
-  if (glyph >= len) {
-    unsigned int new_len;
-    unsigned char *new_klasses;
-
-    new_len = len == 0 ? 120 : 2 * len;
-    while (new_len <= glyph)
-      new_len *= 2;
-
-    if (new_len > 65536)
-      new_len = 65536;
-    new_klasses = (unsigned char *) realloc (layout->new_gdef.klasses, new_len * sizeof (unsigned char));
-
-    if (unlikely (!new_klasses))
-      return;
-
-    memset (new_klasses + len, 0, new_len - len);
-
-    layout->new_gdef.klasses = new_klasses;
-    layout->new_gdef.len = new_len;
-  }
-
-  switch (klass) {
-  default:
-  case HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED:	gdef_klass = GDEF::UnclassifiedGlyph;	break;
-  case HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH:	gdef_klass = GDEF::BaseGlyph;		break;
-  case HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE:	gdef_klass = GDEF::LigatureGlyph;	break;
-  case HB_OT_LAYOUT_GLYPH_CLASS_MARK:		gdef_klass = GDEF::MarkGlyph;		break;
-  case HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT:	gdef_klass = GDEF::ComponentGlyph;	break;
-  }
-
-  layout->new_gdef.klasses[glyph] = gdef_klass;
-  return;
-}
-
-void
-_hb_ot_layout_set_glyph_property (hb_face_t      *face,
-				  hb_codepoint_t  glyph,
-				  unsigned int    property)
-{ _hb_ot_layout_set_glyph_class (face, glyph, (hb_ot_layout_glyph_class_t) (property & 0xff)); }
-
-
-hb_ot_layout_glyph_class_t
-hb_ot_layout_get_glyph_class (hb_face_t      *face,
-			      hb_codepoint_t  glyph)
-{
-  return (hb_ot_layout_glyph_class_t) (_hb_ot_layout_get_glyph_property (face, glyph) & 0xff);
-}
-
-void
-hb_ot_layout_set_glyph_class (hb_face_t                 *face,
-			      hb_codepoint_t             glyph,
-			      hb_ot_layout_glyph_class_t klass)
-{
-  _hb_ot_layout_set_glyph_class (face, glyph, klass);
-}
-
-void
-hb_ot_layout_build_glyph_classes (hb_face_t      *face,
-				  hb_codepoint_t *glyphs,
-				  unsigned char  *klasses,
-				  uint16_t        count)
-{
-  if (HB_OBJECT_IS_INERT (face))
-    return;
-
-  hb_ot_layout_t *layout = face->ot_layout;
-
-  if (unlikely (!count || !glyphs || !klasses))
-    return;
-
-  if (layout->new_gdef.len == 0) {
-    layout->new_gdef.klasses = (unsigned char *) calloc (count, sizeof (unsigned char));
-    layout->new_gdef.len = count;
-  }
-
-  for (unsigned int i = 0; i < count; i++)
-    _hb_ot_layout_set_glyph_class (face, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]);
-}
-
 unsigned int
 hb_ot_layout_get_attach_points (hb_face_t      *face,
 				hb_codepoint_t  glyph,
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 541b191..58c0fbe 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -44,35 +44,9 @@ HB_BEGIN_DECLS
  * GDEF
  */
 
-typedef enum {
-  HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED	= 0x0000,
-  HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH	= 0x0002,
-  HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE	= 0x0004,
-  HB_OT_LAYOUT_GLYPH_CLASS_MARK		= 0x0008,
-  HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT	= 0x0010
-} hb_ot_layout_glyph_class_t;
-
-/* XXX These should eventually be removed as we move synthesized glyph
- * classes in harfbuzz. */
-
 hb_bool_t
 hb_ot_layout_has_glyph_classes (hb_face_t *face);
 
-hb_ot_layout_glyph_class_t
-hb_ot_layout_get_glyph_class (hb_face_t      *face,
-			      hb_codepoint_t  glyph);
-
-void
-hb_ot_layout_set_glyph_class (hb_face_t                 *face,
-			      hb_codepoint_t             glyph,
-			      hb_ot_layout_glyph_class_t klass);
-
-void
-hb_ot_layout_build_glyph_classes (hb_face_t      *face,
-				  hb_codepoint_t *glyphs,
-				  unsigned char  *klasses,
-				  uint16_t        count);
-
 /* Not that useful.  Provides list of attach points for a glyph that a
  * client may want to cache */
 unsigned int
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 64a1a3d..06316bc 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -163,6 +163,14 @@ hb_ensure_native_direction (hb_ot_shape_context_t *c)
   }
 }
 
+static void
+hb_reset_glyph_infos (hb_ot_shape_context_t *c)
+{
+  unsigned int count = c->buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    c->buffer->info[i].var1.u32 = c->buffer->info[i].var2.u32 = 0;
+}
+
 
 /* Substitute */
 
@@ -278,6 +286,8 @@ hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
 
   hb_ot_shape_setup_masks (c);
 
+  hb_reset_glyph_infos (c);
+
   /* SUBSTITUTE */
   {
     /* Mirroring needs to see the original direction */
commit 870e2d6eac01d004c72a925ea93e6823251d5fa2
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 17:37:20 2010 -0400

    Remove unused function

diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index de72220..de698ed 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -56,12 +56,6 @@ HB_INTERNAL void
 _hb_buffer_clear_output (hb_buffer_t *buffer);
 
 HB_INTERNAL void
-_hb_buffer_replace_glyphs (hb_buffer_t *buffer,
-			   unsigned int num_in,
-			   unsigned int num_out,
-			   const hb_codepoint_t *glyph_data);
-
-HB_INTERNAL void
 _hb_buffer_replace_glyphs_be16 (hb_buffer_t *buffer,
 				unsigned int num_in,
 				unsigned int num_out,
@@ -125,10 +119,6 @@ struct _hb_buffer_t {
   inline void swap (void) { _hb_buffer_swap (this); }
   inline void clear_output (void) { _hb_buffer_clear_output (this); }
   inline void next_glyph (void) { _hb_buffer_next_glyph (this); }
-  inline void replace_glyphs (unsigned int num_in,
-			      unsigned int num_out,
-			      const hb_codepoint_t *glyph_data)
-  { _hb_buffer_replace_glyphs (this, num_in, num_out, glyph_data); }
   inline void replace_glyphs_be16 (unsigned int num_in,
 				   unsigned int num_out,
 				   const uint16_t *glyph_data_be)
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 2461046..daf9d53 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -311,33 +311,6 @@ _hb_buffer_swap (hb_buffer_t *buffer)
 }
 
 void
-_hb_buffer_replace_glyphs (hb_buffer_t *buffer,
-			   unsigned int num_in,
-			   unsigned int num_out,
-			   const hb_codepoint_t *glyph_data)
-{
-  if (buffer->out_info != buffer->info ||
-      buffer->out_len + num_out > buffer->i + num_in)
-  {
-    if (unlikely (!_hb_buffer_ensure_separate (buffer, buffer->out_len + num_out)))
-      return;
-  }
-
-  hb_glyph_info_t orig_info = buffer->info[buffer->i];
-
-  for (unsigned int i = 0; i < num_out; i++)
-  {
-    hb_glyph_info_t *info = &buffer->out_info[buffer->out_len + i];
-    *info = orig_info;
-    info->codepoint = glyph_data[i];
-    info->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
-  }
-
-  buffer->i  += num_in;
-  buffer->out_len += num_out;
-}
-
-void
 _hb_buffer_replace_glyphs_be16 (hb_buffer_t *buffer,
 				unsigned int num_in,
 				unsigned int num_out,
commit 1115890b90709fa5329a55d22f543020f3df9f6f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 17:07:04 2010 -0400

    More cleanup

diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index ce95679..de72220 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -35,12 +35,9 @@
 HB_BEGIN_DECLS
 
 
+/* XXX */
 #define HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
-#define component() var1.u16[0]
-#define lig_id() var1.u16[1]
 #define gproperty() var2.u32
-#define back() var.u16[0] /* number of glyphs to go back for drawing current glyph */
-#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */
 
 ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20);
 ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index a26958d..f28e99d 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -38,6 +38,12 @@
 HB_BEGIN_DECLS
 
 
+/* XXX */
+#define component() var1.u16[0]
+#define lig_id() var1.u16[1]
+#define back() var.u16[0] /* number of glyphs to go back for drawing current glyph */
+#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */
+
 typedef unsigned int hb_ot_layout_class_t;
 
 /*
commit dbf56b1d94910f04823e53e39ace1e5145bddc04
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 17:06:12 2010 -0400

    More lig-id cleanup

diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index 2ad8212..ce95679 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -120,11 +120,11 @@ struct _hb_buffer_t {
 
   /* Other stuff */
 
-  unsigned int max_lig_id;
+  unsigned int serial;
 
 
   /* Methods */
-  inline unsigned int allocate_lig_id (void) { return max_lig_id++; }
+  inline unsigned int next_serial (void) { return serial++; }
   inline void swap (void) { _hb_buffer_swap (this); }
   inline void clear_output (void) { _hb_buffer_clear_output (this); }
   inline void next_glyph (void) { _hb_buffer_next_glyph (this); }
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index a75b8e9..2461046 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -228,7 +228,7 @@ hb_buffer_clear (hb_buffer_t *buffer)
   buffer->out_len = 0;
   buffer->i = 0;
   buffer->out_info = buffer->info;
-  buffer->max_lig_id = 0;
+  buffer->serial = 0;
 }
 
 hb_bool_t
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 7e37d51..577b34b 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -391,7 +391,7 @@ struct Ligature
 					     : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE);
 
     /* Allocate new ligature id */
-    unsigned int lig_id = c->buffer->allocate_lig_id ();
+    unsigned int lig_id = allocate_lig_id (c->buffer);
     c->buffer->info[c->buffer->i].component() = 0;
     c->buffer->info[c->buffer->i].lig_id() = lig_id;
 
@@ -427,6 +427,12 @@ 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 overflows */
+    return lig_id;
+  }
+
   public:
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
commit f6a23a0b9171958f76c1d0473b09fc08d2b3a0d0
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 17:01:03 2010 -0400

    More removal of lig-id code from buffer

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 7bdee9f..a75b8e9 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -248,11 +248,11 @@ hb_buffer_add_glyph (hb_buffer_t    *buffer,
   if (unlikely (!_hb_buffer_ensure (buffer, buffer->len + 1))) return;
 
   glyph = &buffer->info[buffer->len];
+
+  memset (glyph, 0, sizeof (*glyph));
   glyph->codepoint = codepoint;
   glyph->mask = mask;
   glyph->cluster = cluster;
-  glyph->component() = 0;
-  glyph->lig_id() = 0;
   glyph->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
 
   buffer->len++;
commit dd2ffd282c059194fd87fb1664e2e0cdb56a87a0
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 16:57:01 2010 -0400

    Minor renaming

diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index 97da610..2ad8212 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -59,20 +59,20 @@ HB_INTERNAL void
 _hb_buffer_clear_output (hb_buffer_t *buffer);
 
 HB_INTERNAL void
-_hb_buffer_add_output_glyphs (hb_buffer_t *buffer,
-			      unsigned int num_in,
-			      unsigned int num_out,
-			      const hb_codepoint_t *glyph_data);
+_hb_buffer_replace_glyphs (hb_buffer_t *buffer,
+			   unsigned int num_in,
+			   unsigned int num_out,
+			   const hb_codepoint_t *glyph_data);
 
 HB_INTERNAL void
-_hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer,
-				   unsigned int num_in,
-				   unsigned int num_out,
-				   const uint16_t *glyph_data_be);
+_hb_buffer_replace_glyphs_be16 (hb_buffer_t *buffer,
+				unsigned int num_in,
+				unsigned int num_out,
+				const uint16_t *glyph_data_be);
 
 HB_INTERNAL void
-_hb_buffer_add_output_glyph (hb_buffer_t *buffer,
-			     hb_codepoint_t glyph_index);
+_hb_buffer_replace_glyph (hb_buffer_t *buffer,
+			  hb_codepoint_t glyph_index);
 
 HB_INTERNAL void
 _hb_buffer_next_glyph (hb_buffer_t *buffer);
@@ -128,17 +128,16 @@ struct _hb_buffer_t {
   inline void swap (void) { _hb_buffer_swap (this); }
   inline void clear_output (void) { _hb_buffer_clear_output (this); }
   inline void next_glyph (void) { _hb_buffer_next_glyph (this); }
-  inline void add_output_glyphs (unsigned int num_in,
-				 unsigned int num_out,
-				 const hb_codepoint_t *glyph_data)
-  { _hb_buffer_add_output_glyphs (this, num_in, num_out, glyph_data); }
-  inline void add_output_glyphs_be16 (unsigned int num_in,
-				      unsigned int num_out,
-				      const uint16_t *glyph_data_be)
-  { _hb_buffer_add_output_glyphs_be16 (this, num_in, num_out, glyph_data_be); }
-  inline void add_output_glyph (hb_codepoint_t glyph_index)
-  { _hb_buffer_add_output_glyph (this, glyph_index); }
-  inline void replace_glyph (hb_codepoint_t glyph_index) { add_output_glyph (glyph_index); }
+  inline void replace_glyphs (unsigned int num_in,
+			      unsigned int num_out,
+			      const hb_codepoint_t *glyph_data)
+  { _hb_buffer_replace_glyphs (this, num_in, num_out, glyph_data); }
+  inline void replace_glyphs_be16 (unsigned int num_in,
+				   unsigned int num_out,
+				   const uint16_t *glyph_data_be)
+  { _hb_buffer_replace_glyphs_be16 (this, num_in, num_out, glyph_data_be); }
+  inline void replace_glyph (hb_codepoint_t glyph_index)
+  { _hb_buffer_replace_glyph (this, glyph_index); }
 
   inline void reset_masks (hb_mask_t mask)
   {
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 7eb0370..7bdee9f 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -311,10 +311,10 @@ _hb_buffer_swap (hb_buffer_t *buffer)
 }
 
 void
-_hb_buffer_add_output_glyphs (hb_buffer_t *buffer,
-			      unsigned int num_in,
-			      unsigned int num_out,
-			      const hb_codepoint_t *glyph_data)
+_hb_buffer_replace_glyphs (hb_buffer_t *buffer,
+			   unsigned int num_in,
+			   unsigned int num_out,
+			   const hb_codepoint_t *glyph_data)
 {
   if (buffer->out_info != buffer->info ||
       buffer->out_len + num_out > buffer->i + num_in)
@@ -338,10 +338,10 @@ _hb_buffer_add_output_glyphs (hb_buffer_t *buffer,
 }
 
 void
-_hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer,
-				   unsigned int num_in,
-				   unsigned int num_out,
-				   const uint16_t *glyph_data_be)
+_hb_buffer_replace_glyphs_be16 (hb_buffer_t *buffer,
+				unsigned int num_in,
+				unsigned int num_out,
+				const uint16_t *glyph_data_be)
 {
   if (buffer->out_info != buffer->info ||
       buffer->out_len + num_out > buffer->i + num_in)
@@ -365,8 +365,8 @@ _hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer,
 }
 
 void
-_hb_buffer_add_output_glyph (hb_buffer_t *buffer,
-			     hb_codepoint_t glyph_index)
+_hb_buffer_replace_glyph (hb_buffer_t *buffer,
+			  hb_codepoint_t glyph_index)
 {
   hb_glyph_info_t *info;
 
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 829217c..7e37d51 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -164,7 +164,7 @@ struct Sequence
     if (unlikely (!substitute.len))
       return false;
 
-    c->buffer->add_output_glyphs_be16 (1, substitute.len, (const uint16_t *) substitute.array);
+    c->buffer->replace_glyphs_be16 (1, substitute.len, (const uint16_t *) substitute.array);
 
     /* This is a guess only ... */
     if (_hb_ot_layout_has_new_glyph_classes (c->layout->face))
@@ -397,11 +397,11 @@ struct Ligature
 
     if (j == c->buffer->i + i) /* No input glyphs skipped */
     {
-      c->buffer->add_output_glyphs_be16 (i, 1, (const uint16_t *) &ligGlyph);
+      c->buffer->replace_glyphs_be16 (i, 1, (const uint16_t *) &ligGlyph);
     }
     else
     {
-      c->buffer->add_output_glyph (ligGlyph);
+      c->buffer->replace_glyph (ligGlyph);
 
       /* Now we must do a second loop to copy the skipped glyphs to
 	 `out' and assign component values to it.  We start with the
@@ -416,7 +416,7 @@ struct Ligature
 	{
 	  c->buffer->info[c->buffer->i].component() = i;
 	  c->buffer->info[c->buffer->i].lig_id() = lig_id;
-	  c->buffer->add_output_glyph (c->buffer->info[c->buffer->i].codepoint);
+	  c->buffer->replace_glyph (c->buffer->info[c->buffer->i].codepoint);
 	}
 
 	/* Skip the base glyph */
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 5770cbf..64a1a3d 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -198,14 +198,14 @@ hb_map_glyphs (hb_font_t    *font,
   unsigned int count = buffer->len - 1;
   for (buffer->i = 0; buffer->i < count;) {
     if (unlikely (is_variation_selector (buffer->info[buffer->i + 1].codepoint))) {
-      buffer->add_output_glyph (hb_font_get_glyph (font, face, buffer->info[buffer->i].codepoint, buffer->info[buffer->i + 1].codepoint));
+      buffer->replace_glyph (hb_font_get_glyph (font, face, buffer->info[buffer->i].codepoint, buffer->info[buffer->i + 1].codepoint));
       buffer->i++;
     } else {
-      buffer->add_output_glyph (hb_font_get_glyph (font, face, buffer->info[buffer->i].codepoint, 0));
+      buffer->replace_glyph (hb_font_get_glyph (font, face, buffer->info[buffer->i].codepoint, 0));
     }
   }
   if (likely (buffer->i < buffer->len))
-    buffer->add_output_glyph (hb_font_get_glyph (font, face, buffer->info[buffer->i].codepoint, 0));
+    buffer->replace_glyph (hb_font_get_glyph (font, face, buffer->info[buffer->i].codepoint, 0));
   buffer->swap ();
 }
 
commit fe263272a2b26204bc39829a94d90ab537517f3f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 16:51:02 2010 -0400

    Move setting lig_id/component out of buffer and to the gsub code

diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index b5ba57d..97da610 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -62,23 +62,17 @@ HB_INTERNAL void
 _hb_buffer_add_output_glyphs (hb_buffer_t *buffer,
 			      unsigned int num_in,
 			      unsigned int num_out,
-			      const hb_codepoint_t *glyph_data,
-			      unsigned short component,
-			      unsigned short ligID);
+			      const hb_codepoint_t *glyph_data);
 
 HB_INTERNAL void
 _hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer,
 				   unsigned int num_in,
 				   unsigned int num_out,
-				   const uint16_t *glyph_data_be,
-				   unsigned short component,
-				   unsigned short ligID);
+				   const uint16_t *glyph_data_be);
 
 HB_INTERNAL void
 _hb_buffer_add_output_glyph (hb_buffer_t *buffer,
-			     hb_codepoint_t glyph_index,
-			     unsigned short component,
-			     unsigned short ligID);
+			     hb_codepoint_t glyph_index);
 
 HB_INTERNAL void
 _hb_buffer_next_glyph (hb_buffer_t *buffer);
@@ -136,20 +130,14 @@ struct _hb_buffer_t {
   inline void next_glyph (void) { _hb_buffer_next_glyph (this); }
   inline void add_output_glyphs (unsigned int num_in,
 				 unsigned int num_out,
-				 const hb_codepoint_t *glyph_data,
-				 unsigned short component,
-				 unsigned short ligID)
-  { _hb_buffer_add_output_glyphs (this, num_in, num_out, glyph_data, component, ligID); }
+				 const hb_codepoint_t *glyph_data)
+  { _hb_buffer_add_output_glyphs (this, num_in, num_out, glyph_data); }
   inline void add_output_glyphs_be16 (unsigned int num_in,
 				      unsigned int num_out,
-				      const uint16_t *glyph_data_be,
-				      unsigned short component,
-				      unsigned short ligID)
-  { _hb_buffer_add_output_glyphs_be16 (this, num_in, num_out, glyph_data_be, component, ligID); }
-  inline void add_output_glyph (hb_codepoint_t glyph_index,
-				unsigned short component = 0xFFFF,
-				unsigned short ligID = 0xFFFF)
-  { _hb_buffer_add_output_glyph (this, glyph_index, component, ligID); }
+				      const uint16_t *glyph_data_be)
+  { _hb_buffer_add_output_glyphs_be16 (this, num_in, num_out, glyph_data_be); }
+  inline void add_output_glyph (hb_codepoint_t glyph_index)
+  { _hb_buffer_add_output_glyph (this, glyph_index); }
   inline void replace_glyph (hb_codepoint_t glyph_index) { add_output_glyph (glyph_index); }
 
   inline void reset_masks (hb_mask_t mask)
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 7b15de4..7eb0370 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -314,14 +314,8 @@ void
 _hb_buffer_add_output_glyphs (hb_buffer_t *buffer,
 			      unsigned int num_in,
 			      unsigned int num_out,
-			      const hb_codepoint_t *glyph_data,
-			      unsigned short component,
-			      unsigned short lig_id)
+			      const hb_codepoint_t *glyph_data)
 {
-  unsigned int i;
-  unsigned int mask;
-  unsigned int cluster;
-
   if (buffer->out_info != buffer->info ||
       buffer->out_len + num_out > buffer->i + num_in)
   {
@@ -329,21 +323,13 @@ _hb_buffer_add_output_glyphs (hb_buffer_t *buffer,
       return;
   }
 
-  mask = buffer->info[buffer->i].mask;
-  cluster = buffer->info[buffer->i].cluster;
-  if (component == 0xFFFF)
-    component = buffer->info[buffer->i].component();
-  if (lig_id == 0xFFFF)
-    lig_id = buffer->info[buffer->i].lig_id();
+  hb_glyph_info_t orig_info = buffer->info[buffer->i];
 
-  for (i = 0; i < num_out; i++)
+  for (unsigned int i = 0; i < num_out; i++)
   {
     hb_glyph_info_t *info = &buffer->out_info[buffer->out_len + i];
+    *info = orig_info;
     info->codepoint = glyph_data[i];
-    info->mask = mask;
-    info->cluster = cluster;
-    info->component() = component;
-    info->lig_id() = lig_id;
     info->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
   }
 
@@ -355,14 +341,8 @@ void
 _hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer,
 				   unsigned int num_in,
 				   unsigned int num_out,
-				   const uint16_t *glyph_data_be,
-				   unsigned short component,
-				   unsigned short lig_id)
+				   const uint16_t *glyph_data_be)
 {
-  unsigned int i;
-  unsigned int mask;
-  unsigned int cluster;
-
   if (buffer->out_info != buffer->info ||
       buffer->out_len + num_out > buffer->i + num_in)
   {
@@ -370,21 +350,13 @@ _hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer,
       return;
   }
 
-  mask = buffer->info[buffer->i].mask;
-  cluster = buffer->info[buffer->i].cluster;
-  if (component == 0xFFFF)
-    component = buffer->info[buffer->i].component();
-  if (lig_id == 0xFFFF)
-    lig_id = buffer->info[buffer->i].lig_id();
+  hb_glyph_info_t orig_info = buffer->info[buffer->i];
 
-  for (i = 0; i < num_out; i++)
+  for (unsigned int i = 0; i < num_out; i++)
   {
     hb_glyph_info_t *info = &buffer->out_info[buffer->out_len + i];
+    *info = orig_info;
     info->codepoint = hb_be_uint16 (glyph_data_be[i]);
-    info->mask = mask;
-    info->cluster = cluster;
-    info->component() = component;
-    info->lig_id() = lig_id;
     info->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
   }
 
@@ -394,9 +366,7 @@ _hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer,
 
 void
 _hb_buffer_add_output_glyph (hb_buffer_t *buffer,
-			     hb_codepoint_t glyph_index,
-			     unsigned short component,
-			     unsigned short lig_id)
+			     hb_codepoint_t glyph_index)
 {
   hb_glyph_info_t *info;
 
@@ -410,10 +380,6 @@ _hb_buffer_add_output_glyph (hb_buffer_t *buffer,
 
   info = &buffer->out_info[buffer->out_len];
   info->codepoint = glyph_index;
-  if (component != 0xFFFF)
-    info->component() = component;
-  if (lig_id != 0xFFFF)
-    info->lig_id() = lig_id;
   info->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
 
   buffer->i++;
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 89d2fb4..829217c 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -164,9 +164,7 @@ struct Sequence
     if (unlikely (!substitute.len))
       return false;
 
-    c->buffer->add_output_glyphs_be16 (1,
-				       substitute.len, (const uint16_t *) substitute.array,
-				       0xFFFF, 0xFFFF);
+    c->buffer->add_output_glyphs_be16 (1, substitute.len, (const uint16_t *) substitute.array);
 
     /* This is a guess only ... */
     if (_hb_ot_layout_has_new_glyph_classes (c->layout->face))
@@ -392,15 +390,18 @@ struct Ligature
 				     is_mark ? HB_OT_LAYOUT_GLYPH_CLASS_MARK
 					     : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE);
 
+    /* Allocate new ligature id */
+    unsigned int lig_id = c->buffer->allocate_lig_id ();
+    c->buffer->info[c->buffer->i].component() = 0;
+    c->buffer->info[c->buffer->i].lig_id() = lig_id;
+
     if (j == c->buffer->i + i) /* No input glyphs skipped */
-      c->buffer->add_output_glyphs_be16 (i,
-					 1, (const uint16_t *) &ligGlyph,
-					 0,
-					 c->buffer->allocate_lig_id ());
+    {
+      c->buffer->add_output_glyphs_be16 (i, 1, (const uint16_t *) &ligGlyph);
+    }
     else
     {
-      unsigned int lig_id = c->buffer->allocate_lig_id ();
-      c->buffer->add_output_glyph (ligGlyph, 0, lig_id);
+      c->buffer->add_output_glyph (ligGlyph);
 
       /* Now we must do a second loop to copy the skipped glyphs to
 	 `out' and assign component values to it.  We start with the
@@ -409,10 +410,14 @@ struct Ligature
 	 value it is later possible to check whether a specific
 	 component value really belongs to a given ligature. */
 
-      for ( i = 1; i < count; i++ )
+      for (i = 1; i < count; i++)
       {
 	while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_flag, NULL))
-	  c->buffer->add_output_glyph (c->buffer->info[c->buffer->i].codepoint, i, lig_id);
+	{
+	  c->buffer->info[c->buffer->i].component() = i;
+	  c->buffer->info[c->buffer->i].lig_id() = lig_id;
+	  c->buffer->add_output_glyph (c->buffer->info[c->buffer->i].codepoint);
+	}
 
 	/* Skip the base glyph */
 	c->buffer->i++;
commit 2e2b2480c01c788ea702d78ca830c2bb659654a8
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 16:25:28 2010 -0400

    Always allocate new ligature id
    
    No practical point in reusing ligature ids.

diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 66d42a9..89d2fb4 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -393,13 +393,10 @@ struct Ligature
 					     : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE);
 
     if (j == c->buffer->i + 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. */
       c->buffer->add_output_glyphs_be16 (i,
 					 1, (const uint16_t *) &ligGlyph,
 					 0,
-					 c->buffer->info[c->buffer->i].lig_id() && !c->buffer->info[c->buffer->i].component() ?
-					 0xFFFF : c->buffer->allocate_lig_id ());
+					 c->buffer->allocate_lig_id ());
     else
     {
       unsigned int lig_id = c->buffer->allocate_lig_id ();
commit bf07d5a29c61baf6fd683289c7764f487ad7e413
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 16:19:13 2010 -0400

    Set component=0 for ligature glyph

diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index c51dd8f..66d42a9 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -403,7 +403,7 @@ struct Ligature
     else
     {
       unsigned int lig_id = c->buffer->allocate_lig_id ();
-      c->buffer->add_output_glyph (ligGlyph, 0xFFFF, lig_id);
+      c->buffer->add_output_glyph (ligGlyph, 0, 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
@@ -417,7 +417,8 @@ struct Ligature
 	while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_flag, NULL))
 	  c->buffer->add_output_glyph (c->buffer->info[c->buffer->i].codepoint, i, lig_id);
 
-	(c->buffer->i)++;
+	/* Skip the base glyph */
+	c->buffer->i++;
       }
     }
 
commit 37ab877149582c7ce7416425bb402340e3f948a2
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 15:38:06 2010 -0400

    Remove comment

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 849ca2f..7b15de4 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -310,26 +310,6 @@ _hb_buffer_swap (hb_buffer_t *buffer)
   buffer->i = 0;
 }
 
-/* The following function copies `num_out' elements from `glyph_data'
-   to `buffer->out_info', advancing the in array pointer in the structure
-   by `num_in' elements, and the out array pointer by `num_out' elements.
-   Finally, it sets the `length' field of `out' equal to
-   `pos' of the `out' structure.
-
-   If `component' is 0xFFFF, the component value from buffer->i
-   will copied `num_out' times, otherwise `component' itself will
-   be used to fill the `component' fields.
-
-   If `lig_id' is 0xFFFF, the lig_id value from buffer->i
-   will copied `num_out' times, otherwise `lig_id' itself will
-   be used to fill the `lig_id' fields.
-
-   The mask for all replacement glyphs are taken
-   from the glyph at position `buffer->i'.
-
-   The cluster value for the glyph at position buffer->i is used
-   for all replacement glyphs */
-
 void
 _hb_buffer_add_output_glyphs (hb_buffer_t *buffer,
 			      unsigned int num_in,
commit 88474c6fdaf35c56368694a5b164f4988a004d49
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 14:42:15 2010 -0400

    Get rid of the OpenType-specific internal buffer representation
    
    Add variant integers to buffer item types.  More cleanup coming.

diff --git a/TODO b/TODO
index 08376e3..d206da1 100644
--- a/TODO
+++ b/TODO
@@ -3,8 +3,6 @@ General fixes:
 
 - Fix tt kern on/off
 
-- Remove hb_internal_glyph_info_t, etc
-
 - Remove synthesized GDEF
 
 - Remove fixed-size feature/lookup arrays in hb-ot-map
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index 585a82a..b5ba57d 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -36,30 +36,13 @@ HB_BEGIN_DECLS
 
 
 #define HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
+#define component() var1.u16[0]
+#define lig_id() var1.u16[1]
+#define gproperty() var2.u32
+#define back() var.u16[0] /* number of glyphs to go back for drawing current glyph */
+#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */
 
-
-typedef struct _hb_internal_glyph_info_t {
-  hb_codepoint_t codepoint;
-  hb_mask_t      mask;
-  uint32_t       cluster;
-  uint16_t       component;
-  uint16_t       lig_id;
-  uint32_t       gproperty;
-} hb_internal_glyph_info_t;
-
-typedef struct _hb_internal_glyph_position_t {
-  hb_position_t  x_advance;
-  hb_position_t  y_advance;
-  hb_position_t  x_offset;
-  hb_position_t  y_offset;
-  uint32_t       back : 16;		/* number of glyphs to go back
-					   for drawing current glyph */
-  int32_t        cursive_chain : 16;	/* character to which this connects,
-					   may be positive or negative */
-} hb_internal_glyph_position_t;
-
-ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_internal_glyph_info_t));
-ASSERT_STATIC (sizeof (hb_glyph_position_t) == sizeof (hb_internal_glyph_position_t));
+ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20);
 ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
 
 typedef struct _hb_segment_properties_t {
@@ -137,9 +120,9 @@ struct _hb_buffer_t {
   unsigned int len; /* Length of ->info and ->pos arrays */
   unsigned int out_len; /* Length of ->out array */
 
-  hb_internal_glyph_info_t     *info;
-  hb_internal_glyph_info_t     *out_info;
-  hb_internal_glyph_position_t *pos;
+  hb_glyph_info_t     *info;
+  hb_glyph_info_t     *out_info;
+  hb_glyph_position_t *pos;
 
   /* Other stuff */
 
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 930f380..849ca2f 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -64,8 +64,8 @@ _hb_buffer_enlarge (hb_buffer_t *buffer, unsigned int size)
     return FALSE;
 
   unsigned int new_allocated = buffer->allocated;
-  hb_internal_glyph_position_t *new_pos;
-  hb_internal_glyph_info_t *new_info;
+  hb_glyph_position_t *new_pos;
+  hb_glyph_info_t *new_info;
   bool separate_out;
 
   separate_out = buffer->out_info != buffer->info;
@@ -73,8 +73,8 @@ _hb_buffer_enlarge (hb_buffer_t *buffer, unsigned int size)
   while (size > new_allocated)
     new_allocated += (new_allocated >> 1) + 8;
 
-  new_pos = (hb_internal_glyph_position_t *) realloc (buffer->pos, new_allocated * sizeof (buffer->pos[0]));
-  new_info = (hb_internal_glyph_info_t *) realloc (buffer->info, new_allocated * sizeof (buffer->info[0]));
+  new_pos = (hb_glyph_position_t *) realloc (buffer->pos, new_allocated * sizeof (buffer->pos[0]));
+  new_info = (hb_glyph_info_t *) realloc (buffer->info, new_allocated * sizeof (buffer->info[0]));
 
   if (unlikely (!new_pos || !new_info))
     buffer->in_error = TRUE;
@@ -85,7 +85,7 @@ _hb_buffer_enlarge (hb_buffer_t *buffer, unsigned int size)
   if (likely (new_info))
     buffer->info = new_info;
 
-  buffer->out_info = separate_out ? (hb_internal_glyph_info_t *) buffer->pos : buffer->info;
+  buffer->out_info = separate_out ? (hb_glyph_info_t *) buffer->pos : buffer->info;
   if (likely (!buffer->in_error))
     buffer->allocated = new_allocated;
 
@@ -107,7 +107,7 @@ _hb_buffer_ensure_separate (hb_buffer_t *buffer, unsigned int size)
   {
     assert (buffer->have_output);
 
-    buffer->out_info = (hb_internal_glyph_info_t *) buffer->pos;
+    buffer->out_info = (hb_glyph_info_t *) buffer->pos;
     memcpy (buffer->out_info, buffer->info, buffer->out_len * sizeof (buffer->out_info[0]));
   }
 
@@ -243,7 +243,7 @@ hb_buffer_add_glyph (hb_buffer_t    *buffer,
 		     hb_mask_t       mask,
 		     unsigned int    cluster)
 {
-  hb_internal_glyph_info_t *glyph;
+  hb_glyph_info_t *glyph;
 
   if (unlikely (!_hb_buffer_ensure (buffer, buffer->len + 1))) return;
 
@@ -251,9 +251,9 @@ hb_buffer_add_glyph (hb_buffer_t    *buffer,
   glyph->codepoint = codepoint;
   glyph->mask = mask;
   glyph->cluster = cluster;
-  glyph->component = 0;
-  glyph->lig_id = 0;
-  glyph->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
+  glyph->component() = 0;
+  glyph->lig_id() = 0;
+  glyph->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
 
   buffer->len++;
 }
@@ -267,7 +267,7 @@ hb_buffer_clear_positions (hb_buffer_t *buffer)
 
   if (unlikely (!buffer->pos))
   {
-    buffer->pos = (hb_internal_glyph_position_t *) calloc (buffer->allocated, sizeof (buffer->pos[0]));
+    buffer->pos = (hb_glyph_position_t *) calloc (buffer->allocated, sizeof (buffer->pos[0]));
     return;
   }
 
@@ -296,11 +296,11 @@ _hb_buffer_swap (hb_buffer_t *buffer)
 
   if (buffer->out_info != buffer->info)
   {
-    hb_internal_glyph_info_t *tmp_string;
+    hb_glyph_info_t *tmp_string;
     tmp_string = buffer->info;
     buffer->info = buffer->out_info;
     buffer->out_info = tmp_string;
-    buffer->pos = (hb_internal_glyph_position_t *) buffer->out_info;
+    buffer->pos = (hb_glyph_position_t *) buffer->out_info;
   }
 
   tmp = buffer->len;
@@ -352,19 +352,19 @@ _hb_buffer_add_output_glyphs (hb_buffer_t *buffer,
   mask = buffer->info[buffer->i].mask;
   cluster = buffer->info[buffer->i].cluster;
   if (component == 0xFFFF)
-    component = buffer->info[buffer->i].component;
+    component = buffer->info[buffer->i].component();
   if (lig_id == 0xFFFF)
-    lig_id = buffer->info[buffer->i].lig_id;
+    lig_id = buffer->info[buffer->i].lig_id();
 
   for (i = 0; i < num_out; i++)
   {
-    hb_internal_glyph_info_t *info = &buffer->out_info[buffer->out_len + i];
+    hb_glyph_info_t *info = &buffer->out_info[buffer->out_len + i];
     info->codepoint = glyph_data[i];
     info->mask = mask;
     info->cluster = cluster;
-    info->component = component;
-    info->lig_id = lig_id;
-    info->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
+    info->component() = component;
+    info->lig_id() = lig_id;
+    info->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
   }
 
   buffer->i  += num_in;
@@ -393,19 +393,19 @@ _hb_buffer_add_output_glyphs_be16 (hb_buffer_t *buffer,
   mask = buffer->info[buffer->i].mask;
   cluster = buffer->info[buffer->i].cluster;
   if (component == 0xFFFF)
-    component = buffer->info[buffer->i].component;
+    component = buffer->info[buffer->i].component();
   if (lig_id == 0xFFFF)
-    lig_id = buffer->info[buffer->i].lig_id;
+    lig_id = buffer->info[buffer->i].lig_id();
 
   for (i = 0; i < num_out; i++)
   {
-    hb_internal_glyph_info_t *info = &buffer->out_info[buffer->out_len + i];
+    hb_glyph_info_t *info = &buffer->out_info[buffer->out_len + i];
     info->codepoint = hb_be_uint16 (glyph_data_be[i]);
     info->mask = mask;
     info->cluster = cluster;
-    info->component = component;
-    info->lig_id = lig_id;
-    info->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
+    info->component() = component;
+    info->lig_id() = lig_id;
+    info->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
   }
 
   buffer->i  += num_in;
@@ -418,7 +418,7 @@ _hb_buffer_add_output_glyph (hb_buffer_t *buffer,
 			     unsigned short component,
 			     unsigned short lig_id)
 {
-  hb_internal_glyph_info_t *info;
+  hb_glyph_info_t *info;
 
   if (buffer->out_info != buffer->info)
   {
@@ -431,10 +431,10 @@ _hb_buffer_add_output_glyph (hb_buffer_t *buffer,
   info = &buffer->out_info[buffer->out_len];
   info->codepoint = glyph_index;
   if (component != 0xFFFF)
-    info->component = component;
+    info->component() = component;
   if (lig_id != 0xFFFF)
-    info->lig_id = lig_id;
-  info->gproperty = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
+    info->lig_id() = lig_id;
+  info->gproperty() = HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN;
 
   buffer->i++;
   buffer->out_len++;
@@ -548,7 +548,7 @@ reverse_range (hb_buffer_t *buffer,
   unsigned int i, j;
 
   for (i = start, j = end - 1; i < j; i++, j--) {
-    hb_internal_glyph_info_t t;
+    hb_glyph_info_t t;
 
     t = buffer->info[i];
     buffer->info[i] = buffer->info[j];
@@ -557,7 +557,7 @@ reverse_range (hb_buffer_t *buffer,
 
   if (buffer->pos) {
     for (i = 0, j = end - 1; i < j; i++, j--) {
-      hb_internal_glyph_position_t t;
+      hb_glyph_position_t t;
 
       t = buffer->pos[i];
       buffer->pos[i] = buffer->pos[j];
diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index c2dc29f..0185415 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -50,7 +50,7 @@ typedef struct _hb_glyph_position_t {
   hb_position_t  y_advance;
   hb_position_t  x_offset;
   hb_position_t  y_offset;
-  hb_var_int_t   var1;
+  hb_var_int_t   var;
 } hb_glyph_position_t;
 
 
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 187dc98..5cf9379 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -87,10 +87,10 @@ struct ValueFormat : USHORT
   inline unsigned int get_size (void) const
   { return get_len () * Value::static_size; }
 
-  void apply_value (hb_ot_layout_context_t       *layout,
-		    const void                   *base,
-		    const Value                  *values,
-		    hb_internal_glyph_position_t &glyph_pos) const
+  void apply_value (hb_ot_layout_context_t *layout,
+		    const void             *base,
+		    const Value            *values,
+		    hb_glyph_position_t    &glyph_pos) const
   {
     unsigned int x_ppem, y_ppem;
     unsigned int format = *this;
@@ -399,10 +399,10 @@ struct MarkArray : ArrayOf<MarkRecord>	/* Array of MarkRecords--in Coverage orde
     mark_anchor.get_anchor (c->layout, c->buffer->info[c->buffer->i].codepoint, &mark_x, &mark_y);
     glyph_anchor.get_anchor (c->layout, c->buffer->info[glyph_pos].codepoint, &base_x, &base_y);
 
-    hb_internal_glyph_position_t &o = c->buffer->pos[c->buffer->i];
+    hb_glyph_position_t &o = c->buffer->pos[c->buffer->i];
     o.x_offset  = base_x - mark_x;
     o.y_offset  = base_y - mark_y;
-    o.back      = c->buffer->i - glyph_pos;
+    o.back()    = c->buffer->i - glyph_pos;
 
     c->buffer->i++;
     return true;
@@ -876,7 +876,7 @@ struct CursivePosFormat1
 
     if  (c->lookup_flag & LookupFlag::RightToLeft)
     {
-      c->buffer->pos[i].cursive_chain = j - i;
+      c->buffer->pos[i].cursive_chain() = j - i;
       if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
 	c->buffer->pos[i].y_offset = entry_y - exit_y;
       else
@@ -884,7 +884,7 @@ struct CursivePosFormat1
     }
     else
     {
-      c->buffer->pos[j].cursive_chain = i - j;
+      c->buffer->pos[j].cursive_chain() = i - j;
       if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
 	c->buffer->pos[j].y_offset = exit_y - entry_y;
       else
@@ -1093,9 +1093,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 (c->buffer->info[j].lig_id && c->buffer->info[j].lig_id == c->buffer->info[c->buffer->i].lig_id && c->buffer->info[c->buffer->i].component)
+    if (c->buffer->info[j].lig_id() && c->buffer->info[j].lig_id() == c->buffer->info[c->buffer->i].lig_id() && c->buffer->info[c->buffer->i].component())
     {
-      comp_index = c->buffer->info[c->buffer->i].component - 1;
+      comp_index = c->buffer->info[c->buffer->i].component() - 1;
       if (comp_index >= comp_count)
 	comp_index = comp_count - 1;
     }
@@ -1198,8 +1198,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 ((c->buffer->info[j].component != c->buffer->info[c->buffer->i].component) ||
-	(c->buffer->info[j].component && c->buffer->info[j].lig_id != c->buffer->info[c->buffer->i].lig_id))
+    if ((c->buffer->info[j].component() != c->buffer->info[c->buffer->i].component()) ||
+	(c->buffer->info[j].component() && c->buffer->info[j].lig_id() != c->buffer->info[c->buffer->i].lig_id()))
       return false;
 
     unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoint);
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index f09b4d2..c51dd8f 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -398,7 +398,7 @@ struct Ligature
       c->buffer->add_output_glyphs_be16 (i,
 					 1, (const uint16_t *) &ligGlyph,
 					 0,
-					 c->buffer->info[c->buffer->i].lig_id && !c->buffer->info[c->buffer->i].component ?
+					 c->buffer->info[c->buffer->i].lig_id() && !c->buffer->info[c->buffer->i].component() ?
 					 0xFFFF : c->buffer->allocate_lig_id ());
     else
     {
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 4cde089..a26958d 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -101,13 +101,13 @@ _hb_ot_layout_set_glyph_class (hb_face_t                  *face,
 
 HB_INTERNAL hb_bool_t
 _hb_ot_layout_check_glyph_property (hb_face_t    *face,
-				    hb_internal_glyph_info_t *ginfo,
+				    hb_glyph_info_t *ginfo,
 				    unsigned int  lookup_flags,
 				    unsigned int *property);
 
 HB_INTERNAL hb_bool_t
 _hb_ot_layout_skip_mark (hb_face_t    *face,
-			 hb_internal_glyph_info_t *ginfo,
+			 hb_glyph_info_t *ginfo,
 			 unsigned int  lookup_flags,
 			 unsigned int *property);
 
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index f85bf86..a705b66 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -138,15 +138,15 @@ _hb_ot_layout_get_glyph_property (hb_face_t      *face,
 
 hb_bool_t
 _hb_ot_layout_check_glyph_property (hb_face_t    *face,
-				    hb_internal_glyph_info_t *ginfo,
+				    hb_glyph_info_t *ginfo,
 				    unsigned int  lookup_flags,
 				    unsigned int *property_out)
 {
   unsigned int property;
 
-  if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
-    ginfo->gproperty = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint);
-  property = ginfo->gproperty;
+  if (ginfo->gproperty() == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
+    ginfo->gproperty() = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint);
+  property = ginfo->gproperty();
   if (property_out)
     *property_out = property;
 
@@ -177,15 +177,15 @@ _hb_ot_layout_check_glyph_property (hb_face_t    *face,
 
 hb_bool_t
 _hb_ot_layout_skip_mark (hb_face_t    *face,
-			 hb_internal_glyph_info_t *ginfo,
+			 hb_glyph_info_t *ginfo,
 			 unsigned int  lookup_flags,
 			 unsigned int *property_out)
 {
   unsigned int property;
 
-  if (ginfo->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
-    ginfo->gproperty = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint);
-  property = ginfo->gproperty;
+  if (ginfo->gproperty() == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
+    ginfo->gproperty() = _hb_ot_layout_get_glyph_property (face, ginfo->codepoint);
+  property = ginfo->gproperty();
   if (property_out)
     *property_out = property;
 
@@ -606,7 +606,7 @@ hb_ot_layout_position_finish (hb_font_t    *font HB_UNUSED,
 {
   unsigned int i, j;
   unsigned int len = hb_buffer_get_length (buffer);
-  hb_internal_glyph_position_t *pos = (hb_internal_glyph_position_t *) hb_buffer_get_glyph_positions (buffer);
+  hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer);
   hb_direction_t direction = buffer->props.direction;
 
   /* TODO: Vertical */
@@ -616,35 +616,34 @@ hb_ot_layout_position_finish (hb_font_t    *font HB_UNUSED,
   if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
   {
     for (j = 0; j < len; j++) {
-      if (pos[j].cursive_chain < 0)
-	pos[j].y_offset += pos[j + pos[j].cursive_chain].y_offset;
+      if (pos[j].cursive_chain() < 0)
+	pos[j].y_offset += pos[j + pos[j].cursive_chain()].y_offset;
     }
     for (i = len; i > 0; i--) {
       j = i - 1;
-      if (pos[j].cursive_chain > 0)
-	pos[j].y_offset += pos[j + pos[j].cursive_chain].y_offset;
+      if (pos[j].cursive_chain() > 0)
+	pos[j].y_offset += pos[j + pos[j].cursive_chain()].y_offset;
     }
   }
   else
   {
     for (j = 0; j < len; j++) {
-      if (pos[j].cursive_chain < 0)
-	pos[j].x_offset += pos[j + pos[j].cursive_chain].x_offset;
+      if (pos[j].cursive_chain() < 0)
+	pos[j].x_offset += pos[j + pos[j].cursive_chain()].x_offset;
     }
     for (i = len; i > 0; i--) {
       j = i - 1;
-      if (pos[j].cursive_chain > 0)
-	pos[j].x_offset += pos[j + pos[j].cursive_chain].x_offset;
+      if (pos[j].cursive_chain() > 0)
+	pos[j].x_offset += pos[j + pos[j].cursive_chain()].x_offset;
     }
   }
 
 
   /* Handle attachments */
   for (i = 0; i < len; i++)
-    if (pos[i].back)
+    if (pos[i].back())
     {
-      unsigned int back = i - pos[i].back;
-      pos[i].back = 0;
+      unsigned int back = i - pos[i].back();
       pos[i].x_offset += pos[back].x_offset;
       pos[i].y_offset += pos[back].y_offset;
 
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 0c485bd..2401c36 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -690,16 +690,16 @@ _hb_ot_shape_complex_setup_masks_arabic	(hb_ot_shape_context_t *c)
     unsigned int this_type = get_joining_type (c->buffer->info[i].codepoint, c->buffer->unicode->v.get_general_category (c->buffer->info[i].codepoint));
 
     if (unlikely (this_type == JOINING_TYPE_T)) {
-      c->buffer->info[i].gproperty = NONE;
+      c->buffer->info[i].var2.u32 = NONE;
       continue;
     }
 
     const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
 
     if (entry->prev_action != NONE)
-      c->buffer->info[prev].gproperty = entry->prev_action;
+      c->buffer->info[prev].var2.u32 = entry->prev_action;
 
-    c->buffer->info[i].gproperty = entry->curr_action;
+    c->buffer->info[i].var2.u32 = entry->curr_action;
 
     prev = i;
     state = entry->next_state;
@@ -711,7 +711,7 @@ _hb_ot_shape_complex_setup_masks_arabic	(hb_ot_shape_context_t *c)
     mask_array[i] = c->plan->map.get_1_mask (arabic_syriac_features[i]);
 
   for (unsigned int i = 0; i < count; i++)
-    c->buffer->info[i].mask |= mask_array[c->buffer->info[i].gproperty];
+    c->buffer->info[i].mask |= mask_array[c->buffer->info[i].var2.u32];
 }
 
 
commit 6cb8c3493019e1497921666fc268cb81943f9f1f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 27 14:27:03 2010 -0400

    Add hb_var_int_t

diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index e6d477d..c2dc29f 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -41,8 +41,8 @@ typedef struct _hb_glyph_info_t {
   hb_codepoint_t codepoint;
   hb_mask_t      mask;
   uint32_t       cluster;
-  uint32_t       internal1;
-  uint32_t       internal2;
+  hb_var_int_t   var1;
+  hb_var_int_t   var2;
 } hb_glyph_info_t;
 
 typedef struct _hb_glyph_position_t {
@@ -50,7 +50,7 @@ typedef struct _hb_glyph_position_t {
   hb_position_t  y_advance;
   hb_position_t  x_offset;
   hb_position_t  y_offset;
-  uint32_t       internal;
+  hb_var_int_t   var1;
 } hb_glyph_position_t;
 
 
diff --git a/src/hb-common.h b/src/hb-common.h
index 85906c5..1dd02cb 100644
--- a/src/hb-common.h
+++ b/src/hb-common.h
@@ -91,6 +91,16 @@ typedef enum _hb_direction_t {
 #define HB_DIRECTION_REVERSE(dir)	((hb_direction_t) (((unsigned int) (dir)) ^ 1))
 
 
+typedef union _hb_var_int_t {
+  uint32_t u32;
+  int32_t i32;
+  uint16_t u16[2];
+  int16_t i16[2];
+  uint8_t u8[4];
+  int8_t i8[4];
+} hb_var_int_t;
+
+
 HB_END_DECLS
 
 #endif /* HB_COMMON_H */



More information about the HarfBuzz mailing list