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

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri May 20 13:01:11 PDT 2011


 TODO                                 |    2 
 configure.ac                         |    2 
 src/hb-font-private.hh               |   40 +--
 src/hb-font.cc                       |  457 ++++++++++++++++++++++++++---------
 src/hb-font.h                        |  192 ++++++++++----
 src/hb-ft.cc                         |  229 +++++++++++------
 src/hb-ot-layout-gdef-private.hh     |   18 -
 src/hb-ot-layout-gpos-private.hh     |   50 ++-
 src/hb-ot-layout-gsub-private.hh     |    1 
 src/hb-ot-layout-gsubgpos-private.hh |    1 
 src/hb-ot-layout.h                   |    2 
 src/hb-ot-shape.cc                   |   33 ++
 src/hb-ot-tag.cc                     |    2 
 src/hb-view.cc                       |   33 +-
 test/test-blob.c                     |    6 
 test/test-buffer.c                   |   38 ++
 test/test-font.c                     |   61 ++--
 test/test-shape.c                    |   29 +-
 18 files changed, 868 insertions(+), 328 deletions(-)

New commits:
commit 3b0bb855e011099f1a4c77ffc5214c658e280b2d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri May 20 15:59:59 2011 -0400

    [Vertical] GPOS x/y advance adjustments only apply in hori/vert respectively

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 9ddc0f7..87e25ff 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -95,20 +95,26 @@ struct ValueFormat : USHORT
   { return get_len () * Value::static_size; }
 
   void apply_value (hb_font_t            *font,
+		    hb_direction_t        direction,
 		    const void           *base,
 		    const Value          *values,
 		    hb_glyph_position_t  &glyph_pos) const
   {
     unsigned int x_ppem, y_ppem;
     unsigned int format = *this;
+    hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (direction);
 
     if (!format) return;
 
     if (format & xPlacement) glyph_pos.x_offset  += font->em_scale_x (get_short (values++));
     if (format & yPlacement) glyph_pos.y_offset  += font->em_scale_y (get_short (values++));
-    if (format & xAdvance)   glyph_pos.x_advance += font->em_scale_x (get_short (values++));
+    if (format & xAdvance) {
+      if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values++)); else values++;
+    }
     /* y_advance values grow downward but font-space grows upward, hence negation */
-    if (format & yAdvance)   glyph_pos.y_advance -= font->em_scale_y (get_short (values++));
+    if (format & yAdvance) {
+      if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values++)); else values++;
+    }
 
     if (!has_device ()) return;
 
@@ -125,11 +131,11 @@ struct ValueFormat : USHORT
       if (y_ppem) glyph_pos.y_offset  += (base + get_device (values++)).get_y_delta (font); else values++;
     }
     if (format & xAdvDevice) {
-      if (x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_delta (font); else values++;
+      if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_delta (font); else values++;
     }
     if (format & yAdvDevice) {
       /* y_advance values grow downward but font-space grows upward, hence negation */
-      if (y_ppem) glyph_pos.y_advance -= (base + get_device (values++)).get_y_delta (font); else values++;
+      if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values++)).get_y_delta (font); else values++;
     }
   }
 
@@ -436,7 +442,8 @@ struct SinglePosFormat1
     if (likely (index == NOT_COVERED))
       return false;
 
-    valueFormat.apply_value (c->font, this, values, c->buffer->pos[c->buffer->i]);
+    valueFormat.apply_value (c->font, c->direction, this,
+			     values, c->buffer->pos[c->buffer->i]);
 
     c->buffer->i++;
     return true;
@@ -478,7 +485,7 @@ struct SinglePosFormat2
     if (likely (index >= valueCount))
       return false;
 
-    valueFormat.apply_value (c->font, this,
+    valueFormat.apply_value (c->font, c->direction, this,
 			     &values[index * valueFormat.get_len ()],
 			     c->buffer->pos[c->buffer->i]);
 
@@ -574,8 +581,10 @@ struct PairSet
     {
       if (c->buffer->info[pos].codepoint == record->secondGlyph)
       {
-	valueFormats[0].apply_value (c->font, this, &record->values[0], c->buffer->pos[c->buffer->i]);
-	valueFormats[1].apply_value (c->font, this, &record->values[len1], c->buffer->pos[pos]);
+	valueFormats[0].apply_value (c->font, c->direction, this,
+				     &record->values[0], c->buffer->pos[c->buffer->i]);
+	valueFormats[1].apply_value (c->font, c->direction, this,
+				     &record->values[len1], c->buffer->pos[pos]);
 	if (len2)
 	  pos++;
 	c->buffer->i = pos;
@@ -709,8 +718,10 @@ struct PairPosFormat2
       return false;
 
     const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
-    valueFormat1.apply_value (c->font, this, v, c->buffer->pos[c->buffer->i]);
-    valueFormat2.apply_value (c->font, this, v + len1, c->buffer->pos[j]);
+    valueFormat1.apply_value (c->font, c->direction, this,
+			      v, c->buffer->pos[c->buffer->i]);
+    valueFormat2.apply_value (c->font, c->direction, this,
+			      v + len1, c->buffer->pos[j]);
 
     if (len2)
       j++;
commit cc2086d67ce559878a5ce2b41d89a37eabac90b8
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu May 19 19:19:50 2011 -0400

    [Vertical] Fix GPOS y-advance direction

diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 27d2603..9ddc0f7 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -104,11 +104,11 @@ struct ValueFormat : USHORT
 
     if (!format) return;
 
-    /* design units -> fractional pixel */
     if (format & xPlacement) glyph_pos.x_offset  += font->em_scale_x (get_short (values++));
     if (format & yPlacement) glyph_pos.y_offset  += font->em_scale_y (get_short (values++));
     if (format & xAdvance)   glyph_pos.x_advance += font->em_scale_x (get_short (values++));
-    if (format & yAdvance)   glyph_pos.y_advance += font->em_scale_y (get_short (values++));
+    /* y_advance values grow downward but font-space grows upward, hence negation */
+    if (format & yAdvance)   glyph_pos.y_advance -= font->em_scale_y (get_short (values++));
 
     if (!has_device ()) return;
 
@@ -128,7 +128,8 @@ struct ValueFormat : USHORT
       if (x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_delta (font); else values++;
     }
     if (format & yAdvDevice) {
-      if (y_ppem) glyph_pos.y_advance += (base + get_device (values++)).get_y_delta (font); else values++;
+      /* y_advance values grow downward but font-space grows upward, hence negation */
+      if (y_ppem) glyph_pos.y_advance -= (base + get_device (values++)).get_y_delta (font); else values++;
     }
   }
 
commit 67d51ff96154c8909734046601e439dd8f6a86df
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu May 19 19:08:57 2011 -0400

    [Vertical] Do fallback origin calculation

diff --git a/src/hb-font.cc b/src/hb-font.cc
index e358ae7..ae2910c 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -71,7 +71,7 @@ hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
     return;
   }
 
-  *advance = 0;
+  *advance = font->x_scale;
 }
 
 static void
@@ -89,7 +89,7 @@ hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
     return;
   }
 
-  *advance = 0;
+  *advance = font->y_scale;
 }
 
 static hb_bool_t
@@ -450,6 +450,21 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
   }
 }
 
+static void
+guess_v_origin_minus_h_origin (hb_font_t *font,
+			       hb_codepoint_t glyph,
+			       hb_position_t *x, hb_position_t *y)
+{
+  *x = *y = 0;
+
+  hb_font_get_glyph_h_advance (font, glyph, x);
+  *x /= 2;
+
+  /* TODO use font_metics.ascent */
+  *y = font->y_scale;
+}
+
+
 void
 hb_font_get_glyph_origin_for_direction (hb_font_t *font,
 					hb_codepoint_t glyph,
@@ -457,11 +472,18 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font,
 					hb_position_t *x, hb_position_t *y)
 {
   if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
-    hb_font_get_glyph_h_origin (font, glyph, x, y);
+    hb_bool_t ret = hb_font_get_glyph_h_origin (font, glyph, x, y);
+    if (!ret && (ret = hb_font_get_glyph_v_origin (font, glyph, x, y))) {
+      hb_position_t dx, dy;
+      guess_v_origin_minus_h_origin (font, glyph, &dx, &dy);
+      *x -= dx; *y -= dy;
+    }
   } else {
     hb_bool_t ret = hb_font_get_glyph_v_origin (font, glyph, x, y);
-    if (!ret) {
-      /* TODO return h_origin/2. and font_extents.ascent */
+    if (!ret && (ret = hb_font_get_glyph_h_origin (font, glyph, x, y))) {
+      hb_position_t dx, dy;
+      guess_v_origin_minus_h_origin (font, glyph, &dx, &dy);
+      *x += dx; *y += dy;
     }
   }
 }
commit 60fbb36096e344e9af79409ce8cfe3f1f7b0d321
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu May 19 18:46:15 2011 -0400

    [Vertical] GPOS is always done with horizontal origin

diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index fcd96da..b170c9d 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -138,10 +138,10 @@ struct _hb_font_t {
     return v;
   }
   inline hb_position_t parent_scale_x_position (hb_position_t v) {
-    return parent_scale_x_distance (v); /* We don't have translation right now */
+    return parent_scale_x_distance (v);
   }
   inline hb_position_t parent_scale_y_position (hb_position_t v) {
-    return parent_scale_y_distance (v); /* We don't have translation right now */
+    return parent_scale_y_distance (v);
   }
 
   inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
diff --git a/src/hb-font.cc b/src/hb-font.cc
index e223a68..e358ae7 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -56,44 +56,40 @@ hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
   return FALSE;
 }
 
-static hb_bool_t
+static void
 hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
 				 void *font_data HB_UNUSED,
 				 hb_codepoint_t glyph,
-				 hb_position_t *x,
-				 hb_position_t *y,
+				 hb_position_t *advance,
 				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_bool_t ret = hb_font_get_glyph_h_advance (font->parent,
-						 glyph,
-						 x, y);
-    font->parent_scale_distance (x, y);
-    return ret;
+    hb_font_get_glyph_h_advance (font->parent,
+				 glyph,
+				 advance);
+    *advance = font->parent_scale_x_distance (*advance);
+    return;
   }
 
-  *x = *y = 0;
-  return FALSE;
+  *advance = 0;
 }
 
-static hb_bool_t
+static void
 hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
 				 void *font_data HB_UNUSED,
 				 hb_codepoint_t glyph,
-				 hb_position_t *x,
-				 hb_position_t *y,
+				 hb_position_t *advance,
 				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_bool_t ret = hb_font_get_glyph_v_advance (font->parent,
-						 glyph,
-						 x, y);
-    font->parent_scale_distance (x, y);
-    return ret;
+    hb_font_get_glyph_v_advance (font->parent,
+				 glyph,
+				 advance);
+    *advance = font->parent_scale_y_distance (*advance);
+    return;
   }
 
-  *x = *y = 0;
-  return FALSE;
+  *advance = 0;
 }
 
 static hb_bool_t
@@ -108,7 +104,8 @@ hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
     hb_bool_t ret = hb_font_get_glyph_h_origin (font->parent,
 						glyph,
 						x, y);
-    font->parent_scale_distance (x, y);
+    if (ret)
+      font->parent_scale_position (x, y);
     return ret;
   }
 
@@ -128,7 +125,8 @@ hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
     hb_bool_t ret = hb_font_get_glyph_v_origin (font->parent,
 						glyph,
 						x, y);
-    font->parent_scale_distance (x, y);
+    if (ret)
+      font->parent_scale_position (x, y);
     return ret;
   }
 
@@ -136,46 +134,42 @@ hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
   return FALSE;
 }
 
-static hb_bool_t
+static void
 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
 				 void *font_data HB_UNUSED,
 				 hb_codepoint_t left_glyph,
 				 hb_codepoint_t right_glyph,
-				 hb_position_t *x,
-				 hb_position_t *y,
+				 hb_position_t *kerning,
 				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_bool_t ret = hb_font_get_glyph_h_kerning (font->parent,
-						 left_glyph, right_glyph,
-						 x, y);
-    font->parent_scale_distance (x, y);
-    return ret;
+    hb_font_get_glyph_h_kerning (font->parent,
+				 left_glyph, right_glyph,
+				 kerning);
+    *kerning = font->parent_scale_x_distance (*kerning);
+    return;
   }
 
-  *x = *y = 0;
-  return FALSE;
+  *kerning = 0;
 }
 
-static hb_bool_t
+static void
 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
 				 void *font_data HB_UNUSED,
 				 hb_codepoint_t top_glyph,
 				 hb_codepoint_t bottom_glyph,
-				 hb_position_t *x,
-				 hb_position_t *y,
+				 hb_position_t *kerning,
 				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_bool_t ret = hb_font_get_glyph_v_kerning (font->parent,
-						 top_glyph, bottom_glyph,
-						 x, y);
-    font->parent_scale_distance (x, y);
-    return ret;
+    hb_font_get_glyph_v_kerning (font->parent,
+				 top_glyph, bottom_glyph,
+				 kerning);
+    *kerning = font->parent_scale_y_distance (*kerning);
+    return;
   }
 
-  *x = *y = 0;
-  return FALSE;
+  *kerning = 0;
 }
 
 static hb_bool_t
@@ -189,13 +183,14 @@ hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
     hb_bool_t ret = hb_font_get_glyph_extents (font->parent,
 					       glyph,
 					       extents);
-    font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
-    font->parent_scale_distance (&extents->width, &extents->height);
+    if (ret) {
+      font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
+      font->parent_scale_distance (&extents->width, &extents->height);
+    }
     return ret;
   }
 
-  extents->x_bearing = extents->y_bearing = 0;
-  extents->width = extents->height = 0;
+  memset (extents, 0, sizeof (*extents));
   return FALSE;
 }
 
@@ -212,7 +207,8 @@ hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
     hb_bool_t ret = hb_font_get_glyph_contour_point (font->parent,
 						     glyph, point_index,
 						     x, y);
-    font->parent_scale_position (x, y);
+    if (ret)
+      font->parent_scale_position (x, y);
     return ret;
   }
 
@@ -344,26 +340,26 @@ hb_font_get_glyph (hb_font_t *font,
 				 font->klass->user_data.glyph);
 }
 
-hb_bool_t
+void
 hb_font_get_glyph_h_advance (hb_font_t *font,
 			     hb_codepoint_t glyph,
-			     hb_position_t *x, hb_position_t *y)
+			     hb_position_t *advance)
 {
-  *x = *y = 0;
-  return font->klass->get.glyph_h_advance (font, font->user_data,
-					   glyph, x, y,
-					   font->klass->user_data.glyph_h_advance);
+  *advance = 0;
+  font->klass->get.glyph_h_advance (font, font->user_data,
+				    glyph, advance,
+				    font->klass->user_data.glyph_h_advance);
 }
 
-hb_bool_t
+void
 hb_font_get_glyph_v_advance (hb_font_t *font,
 			     hb_codepoint_t glyph,
-			     hb_position_t *x, hb_position_t *y)
+			     hb_position_t *advance)
 {
-  *x = *y = 0;
-  return font->klass->get.glyph_v_advance (font, font->user_data,
-					   glyph, x, y,
-					   font->klass->user_data.glyph_v_advance);
+  *advance = 0;
+  font->klass->get.glyph_v_advance (font, font->user_data,
+				    glyph, advance,
+				    font->klass->user_data.glyph_v_advance);
 }
 
 hb_bool_t
@@ -388,27 +384,27 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
 					   font->klass->user_data.glyph_v_origin);
 }
 
-hb_bool_t
+void
 hb_font_get_glyph_h_kerning (hb_font_t *font,
 			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-			     hb_position_t *x, hb_position_t *y)
+			     hb_position_t *kerning)
 {
-  *x = *y = 0;
+  *kerning = 0;
   return font->klass->get.glyph_h_kerning (font, font->user_data,
 					   left_glyph, right_glyph,
-					   x, y,
+					   kerning,
 					   font->klass->user_data.glyph_h_kerning);
 }
 
-hb_bool_t
+void
 hb_font_get_glyph_v_kerning (hb_font_t *font,
 			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-			     hb_position_t *x, hb_position_t *y)
+			     hb_position_t *kerning)
 {
-  *x = *y = 0;
+  *kerning = 0;
   return font->klass->get.glyph_v_kerning (font, font->user_data,
 				     left_glyph, right_glyph,
-				     x, y,
+				     kerning,
 				     font->klass->user_data.glyph_v_kerning);
 }
 
@@ -445,13 +441,12 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
 					 hb_direction_t direction,
 					 hb_position_t *x, hb_position_t *y)
 {
-  if (HB_DIRECTION_IS_VERTICAL (direction)) {
-    hb_bool_t ret = hb_font_get_glyph_v_advance (font, glyph, x, y);
-    if (!ret) {
-      /* TODO return font_extents.ascent + font_extents.descent? */
-    }
+  if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
+    *y = 0;
+    hb_font_get_glyph_h_advance (font, glyph, x);
   } else {
-    hb_font_get_glyph_h_advance (font, glyph, x, y);
+    *x = 0;
+    hb_font_get_glyph_v_advance (font, glyph, y);
   }
 }
 
@@ -461,13 +456,13 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font,
 					hb_direction_t direction,
 					hb_position_t *x, hb_position_t *y)
 {
-  if (HB_DIRECTION_IS_VERTICAL (direction)) {
+  if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
+    hb_font_get_glyph_h_origin (font, glyph, x, y);
+  } else {
     hb_bool_t ret = hb_font_get_glyph_v_origin (font, glyph, x, y);
     if (!ret) {
       /* TODO return h_origin/2. and font_extents.ascent */
     }
-  } else {
-    hb_font_get_glyph_h_origin (font, glyph, x, y);
   }
 }
 
@@ -505,40 +500,34 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
 					 hb_direction_t direction,
 					 hb_position_t *x, hb_position_t *y)
 {
-  switch (direction) {
-    case HB_DIRECTION_LTR:
-    case HB_DIRECTION_RTL:
-      hb_font_get_glyph_h_kerning (font, first_glyph, second_glyph, x, y);
-      break;
-
-    case HB_DIRECTION_TTB:
-    case HB_DIRECTION_BTT:
-      hb_font_get_glyph_v_kerning (font, first_glyph, second_glyph, x, y);
-      break;
-
-    case HB_DIRECTION_INVALID:
-    default:
-      break;
+  if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
+    *y = 0;
+     hb_font_get_glyph_h_kerning (font, first_glyph, second_glyph, x);
+  } else {
+    *x = 0;
+     hb_font_get_glyph_v_kerning (font, first_glyph, second_glyph, y);
   }
 }
 
-void
-hb_font_get_glyph_extents_for_direction (hb_font_t *font,
-					 hb_codepoint_t glyph,
-					 hb_direction_t direction,
-					 hb_glyph_extents_t *extents)
+hb_bool_t
+hb_font_get_glyph_extents_for_origin (hb_font_t *font,
+				      hb_codepoint_t glyph,
+				      hb_direction_t direction,
+				      hb_glyph_extents_t *extents)
 {
   hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, extents);
 
   if (ret)
     hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, &extents->x_bearing, &extents->y_bearing);
+
+  return ret;
 }
 
 hb_bool_t
-hb_font_get_glyph_contour_point_for_direction (hb_font_t *font,
-					       hb_codepoint_t glyph, unsigned int point_index,
-					       hb_direction_t direction,
-					       hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
+					    hb_codepoint_t glyph, unsigned int point_index,
+					    hb_direction_t direction,
+					    hb_position_t *x, hb_position_t *y)
 {
   hb_bool_t ret = hb_font_get_glyph_contour_point (font, glyph, point_index, x, y);
 
diff --git a/src/hb-font.h b/src/hb-font.h
index 3c181f0..22384ac 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -142,10 +142,10 @@ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
 					       void *user_data);
 
 
-typedef hb_bool_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
-						       hb_codepoint_t glyph,
-						       hb_position_t *x, hb_position_t *y,
-						       void *user_data);
+typedef void (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
+						  hb_codepoint_t glyph,
+						  hb_position_t *advance,
+						  void *user_data);
 typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
 typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
 
@@ -156,10 +156,10 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon
 typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
 typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
 
-typedef hb_bool_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
-						       hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
-						       hb_position_t *x, hb_position_t *y,
-						       void *user_data);
+typedef void (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
+						  hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+						  hb_position_t *kerning,
+						  void *user_data);
 typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
 typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
 
@@ -225,14 +225,14 @@ hb_font_get_glyph (hb_font_t *font,
 		   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
 		   hb_codepoint_t *glyph);
 
-hb_bool_t
+void
 hb_font_get_glyph_h_advance (hb_font_t *font,
 			     hb_codepoint_t glyph,
-			     hb_position_t *x, hb_position_t *y);
-hb_bool_t
+			     hb_position_t *advance);
+void
 hb_font_get_glyph_v_advance (hb_font_t *font,
 			     hb_codepoint_t glyph,
-			     hb_position_t *x, hb_position_t *y);
+			     hb_position_t *advance);
 
 hb_bool_t
 hb_font_get_glyph_h_origin (hb_font_t *font,
@@ -243,14 +243,14 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
 			    hb_codepoint_t glyph,
 			    hb_position_t *x, hb_position_t *y);
 
-hb_bool_t
+void
 hb_font_get_glyph_h_kerning (hb_font_t *font,
 			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-			     hb_position_t *x, hb_position_t *y);
-hb_bool_t
+			     hb_position_t *kerning);
+void
 hb_font_get_glyph_v_kerning (hb_font_t *font,
 			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph,
-			     hb_position_t *x, hb_position_t *y);
+			     hb_position_t *kerning);
 
 hb_bool_t
 hb_font_get_glyph_extents (hb_font_t *font,
@@ -292,17 +292,17 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
 					 hb_direction_t direction,
 					 hb_position_t *x, hb_position_t *y);
 
-void
-hb_font_get_glyph_extents_for_direction (hb_font_t *font,
-					 hb_codepoint_t glyph,
-					 hb_direction_t direction,
-					 hb_glyph_extents_t *extents);
+hb_bool_t
+hb_font_get_glyph_extents_for_origin (hb_font_t *font,
+				      hb_codepoint_t glyph,
+				      hb_direction_t direction,
+				      hb_glyph_extents_t *extents);
 
 hb_bool_t
-hb_font_get_glyph_contour_point_for_direction (hb_font_t *font,
-					       hb_codepoint_t glyph, unsigned int point_index,
-					       hb_direction_t direction,
-					       hb_position_t *x, hb_position_t *y);
+hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
+					    hb_codepoint_t glyph, unsigned int point_index,
+					    hb_direction_t direction,
+					    hb_position_t *x, hb_position_t *y);
 
 
 /*
@@ -357,9 +357,6 @@ hb_font_set_funcs (hb_font_t         *font,
 		   hb_destroy_func_t  destroy);
 
 
-/*
- * We should add support for full matrices.
- */
 void
 hb_font_set_scale (hb_font_t *font,
 		   int x_scale,
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index f6a62cf..feaf9aa 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -78,42 +78,38 @@ hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
   return *glyph != 0;
 }
 
-static hb_bool_t
+static void
 hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
 			   void *font_data,
 			   hb_codepoint_t glyph,
-			   hb_position_t *x,
-			   hb_position_t *y,
+			   hb_position_t *advance,
 			   void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
   int load_flags = FT_LOAD_DEFAULT;
 
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
-    return FALSE;
+    return;
 
-  *x = ft_face->glyph->metrics.horiAdvance;
-  return TRUE;
+  *advance = ft_face->glyph->metrics.horiAdvance;
 }
 
-static hb_bool_t
+static void
 hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
 			   void *font_data,
 			   hb_codepoint_t glyph,
-			   hb_position_t *x,
-			   hb_position_t *y,
+			   hb_position_t *advance,
 			   void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
   int load_flags = FT_LOAD_DEFAULT;
 
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
-    return FALSE;
+    return;
 
   /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
    * have a Y growing upward.  Hence the extra negation. */
-  *y = -ft_face->glyph->metrics.vertAdvance;
-  return TRUE;
+  *advance = -ft_face->glyph->metrics.vertAdvance;
 }
 
 static hb_bool_t
@@ -147,45 +143,36 @@ hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
   *x = ft_face->glyph->metrics.horiBearingX -   ft_face->glyph->metrics.vertBearingX;
   *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY);
 
-  /* TODO ??
-  if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
-    FT_Vector_Transform (&vector, &scaled_font->unscaled->Current_Shape);
-   */
-
   return TRUE;
 }
 
-static hb_bool_t
+static void
 hb_ft_get_glyph_h_kerning (hb_font_t *font HB_UNUSED,
 			   void *font_data,
 			   hb_codepoint_t left_glyph,
 			   hb_codepoint_t right_glyph,
-			   hb_position_t *x,
-			   hb_position_t *y,
+			   hb_position_t *kerning,
 			   void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
-  FT_Vector kerning;
+  FT_Vector kerningv;
 
-  if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning))
-    return FALSE;
+  if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerningv))
+    return;
 
-  *x = kerning.x;
-  *y = kerning.y;
-  return TRUE;
+  *kerning = kerningv.x;
 }
 
-static hb_bool_t
+static void
 hb_ft_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
 			   void *font_data HB_UNUSED,
 			   hb_codepoint_t top_glyph HB_UNUSED,
 			   hb_codepoint_t bottom_glyph HB_UNUSED,
-			   hb_position_t *x HB_UNUSED,
-			   hb_position_t *y HB_UNUSED,
+			   hb_position_t *kerning HB_UNUSED,
 			   void *user_data HB_UNUSED)
 {
   /* FreeType API doesn't support vertical kerning */
-  return FALSE;
+  return;
 }
 
 static hb_bool_t
diff --git a/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh
index 01ac4ba..77549fa 100644
--- a/src/hb-ot-layout-gdef-private.hh
+++ b/src/hb-ot-layout-gdef-private.hh
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2007,2008,2009  Red Hat, Inc.
- * Copyright © 2010  Google, Inc.
+ * Copyright © 2010,2011  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -96,7 +96,7 @@ struct CaretValueFormat1
   friend struct CaretValue;
 
   private:
-  inline int get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const
+  inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const
   {
     return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
   }
@@ -118,10 +118,10 @@ struct CaretValueFormat2
   friend struct CaretValue;
 
   private:
-  inline int get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
+  inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
   {
     hb_position_t x, y;
-    if (hb_font_get_glyph_contour_point_for_direction (font, glyph_id, caretValuePoint, direction, &x, &y))
+    if (hb_font_get_glyph_contour_point_for_origin (font, glyph_id, caretValuePoint, direction, &x, &y))
       return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
     else
       return 0;
@@ -143,7 +143,7 @@ struct CaretValueFormat3
 {
   friend struct CaretValue;
 
-  inline int get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
+  inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
   {
     return HB_DIRECTION_IS_HORIZONTAL (direction) ?
            font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font) :
@@ -169,7 +169,7 @@ struct CaretValueFormat3
 
 struct CaretValue
 {
-  inline int get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
+  inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
   {
     switch (u.format) {
     case 1: return u.format1.get_caret_value (font, direction, glyph_id);
@@ -208,7 +208,7 @@ struct LigGlyph
 				      hb_codepoint_t glyph_id,
 				      unsigned int start_offset,
 				      unsigned int *caret_count /* IN/OUT */,
-				      int *caret_array /* OUT */) const
+				      hb_position_t *caret_array /* OUT */) const
   {
     if (caret_count) {
       const OffsetTo<CaretValue> *array = carets.sub_array (start_offset, caret_count);
@@ -241,7 +241,7 @@ struct LigCaretList
 				      hb_codepoint_t glyph_id,
 				      unsigned int start_offset,
 				      unsigned int *caret_count /* IN/OUT */,
-				      int *caret_array /* OUT */) const
+				      hb_position_t *caret_array /* OUT */) const
   {
     unsigned int index = (this+coverage) (glyph_id);
     if (index == NOT_COVERED)
@@ -357,7 +357,7 @@ struct GDEF
 				      hb_codepoint_t glyph_id,
 				      unsigned int start_offset,
 				      unsigned int *caret_count /* IN/OUT */,
-				      int *caret_array /* OUT */) const
+				      hb_position_t *caret_array /* OUT */) const
   { return (this+ligCaretList).get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); }
 
   inline bool has_mark_sets (void) const { return version >= 0x00010002 && markGlyphSetsDef[0] != 0; }
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index cfb5e82..27d2603 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -210,7 +210,6 @@ struct AnchorFormat1
 
   private:
   inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
-			  hb_direction_t direction HB_UNUSED,
 			  hb_position_t *x, hb_position_t *y) const
   {
       *x = font->em_scale_x (xCoordinate);
@@ -236,7 +235,6 @@ struct AnchorFormat2
 
   private:
   inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
-			  hb_direction_t direction,
 			  hb_position_t *x, hb_position_t *y) const
   {
       unsigned int x_ppem = font->x_ppem;
@@ -245,7 +243,7 @@ struct AnchorFormat2
       hb_bool_t ret = false;
 
       if (x_ppem || y_ppem)
-	ret = hb_font_get_glyph_contour_point_for_direction (font, glyph_id, anchorPoint, direction, &cx, &cy);
+	ret = hb_font_get_glyph_contour_point_for_origin (font, glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
       *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate);
       *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate);
   }
@@ -270,13 +268,11 @@ struct AnchorFormat3
 
   private:
   inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
-			  hb_direction_t direction HB_UNUSED,
 			  hb_position_t *x, hb_position_t *y) const
   {
       *x = font->em_scale_x (xCoordinate);
       *y = font->em_scale_y (yCoordinate);
 
-      /* pixel -> fractional pixel */
       if (font->x_ppem)
 	*x += (this+xDeviceTable).get_x_delta (font);
       if (font->y_ppem)
@@ -309,15 +305,14 @@ struct AnchorFormat3
 struct Anchor
 {
   inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
-			  hb_direction_t direction,
 			  hb_position_t *x, hb_position_t *y) const
   {
     *x = *y = 0;
     switch (u.format) {
-    case 1: u.format1.get_anchor (font, glyph_id, direction, x, y); return;
-    case 2: u.format2.get_anchor (font, glyph_id, direction, x, y); return;
-    case 3: u.format3.get_anchor (font, glyph_id, direction, x, y); return;
-    default:							    return;
+    case 1: u.format1.get_anchor (font, glyph_id, x, y); return;
+    case 2: u.format2.get_anchor (font, glyph_id, x, y); return;
+    case 3: u.format3.get_anchor (font, glyph_id, x, y); return;
+    default:						 return;
     }
   }
 
@@ -407,8 +402,8 @@ struct MarkArray : ArrayOf<MarkRecord>	/* Array of MarkRecords--in Coverage orde
 
     hb_position_t mark_x, mark_y, base_x, base_y;
 
-    mark_anchor.get_anchor (c->font, c->buffer->info[c->buffer->i].codepoint, c->direction, &mark_x, &mark_y);
-    glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, c->direction, &base_x, &base_y);
+    mark_anchor.get_anchor (c->font, c->buffer->info[c->buffer->i].codepoint, &mark_x, &mark_y);
+    glyph_anchor.get_anchor (c->font, 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;
@@ -863,8 +858,8 @@ struct CursivePosFormat1
     unsigned int i = c->buffer->i;
 
     hb_position_t entry_x, entry_y, exit_x, exit_y;
-    (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, c->direction, &exit_x, &exit_y);
-    (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, c->direction, &entry_x, &entry_y);
+    (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, &exit_x, &exit_y);
+    (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, &entry_x, &entry_y);
 
     /* Align the exit anchor of the left/top glyph with the entry anchor of the right/bottom glyph
      * by adjusting advance of the left/top glyph. */
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 5257244..6320437 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -63,7 +63,7 @@ hb_ot_layout_get_ligature_carets (hb_font_t      *font,
 				  hb_codepoint_t  glyph,
 				  unsigned int    start_offset,
 				  unsigned int   *caret_count /* IN/OUT */,
-				  int            *caret_array /* OUT */);
+				  hb_position_t  *caret_array /* OUT */);
 
 
 /*
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index f9c05ec..d8970a1 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -121,8 +121,23 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
   if (!hb_ot_layout_has_positioning (c->face))
     return;
 
+  unsigned int count = c->buffer->len;
+  for (unsigned int i = 0; i < count; i++) {
+    hb_font_add_glyph_origin_for_direction (c->font, c->buffer->info[i].codepoint,
+					    HB_DIRECTION_LTR,
+					    &c->buffer->pos[i].x_offset,
+					    &c->buffer->pos[i].y_offset);
+  }
+
   c->plan->map.position (c->font, c->face, c->buffer);
 
+  for (unsigned int i = 0; i < count; i++) {
+    hb_font_subtract_glyph_origin_for_direction (c->font, c->buffer->info[i].codepoint,
+						 HB_DIRECTION_LTR,
+						 &c->buffer->pos[i].x_offset,
+						 &c->buffer->pos[i].y_offset);
+  }
+
   hb_ot_layout_position_finish (c->buffer);
 
   c->applied_position_complex = TRUE;
commit 8b38faeede41e64eb0f6ac2e12ce51dd7138d50a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu May 19 13:08:00 2011 -0400

    More vertical
    
    Starting to get there, but not without yet another round of changes.
    
    I think I know wheere to go now.

diff --git a/src/hb-font.cc b/src/hb-font.cc
index c2fbb94..e223a68 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -472,6 +472,34 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font,
 }
 
 void
+hb_font_add_glyph_origin_for_direction (hb_font_t *font,
+					hb_codepoint_t glyph,
+					hb_direction_t direction,
+					hb_position_t *x, hb_position_t *y)
+{
+  hb_position_t origin_x, origin_y;
+
+  hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &origin_y);
+
+  *x += origin_x;
+  *y += origin_y;
+}
+
+void
+hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
+					     hb_codepoint_t glyph,
+					     hb_direction_t direction,
+					     hb_position_t *x, hb_position_t *y)
+{
+  hb_position_t origin_x, origin_y;
+
+  hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &origin_y);
+
+  *x -= origin_x;
+  *y -= origin_y;
+}
+
+void
 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
 					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
 					 hb_direction_t direction,
@@ -502,12 +530,8 @@ hb_font_get_glyph_extents_for_direction (hb_font_t *font,
 {
   hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, extents);
 
-  if (ret) {
-    hb_position_t origin_x, origin_y;
-    hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &origin_y);
-    extents->x_bearing += origin_x;
-    extents->y_bearing += origin_y;
-  }
+  if (ret)
+    hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, &extents->x_bearing, &extents->y_bearing);
 }
 
 hb_bool_t
@@ -518,12 +542,8 @@ hb_font_get_glyph_contour_point_for_direction (hb_font_t *font,
 {
   hb_bool_t ret = hb_font_get_glyph_contour_point (font, glyph, point_index, x, y);
 
-  if (ret) {
-    hb_position_t origin_x, origin_y;
-    hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &origin_y);
-    *x += origin_x;
-    *y += origin_y;
-  }
+  if (ret)
+    hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, x, y);
 
   return ret;
 }
diff --git a/src/hb-font.h b/src/hb-font.h
index a73b8d1..3c181f0 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -275,6 +275,16 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font,
 					hb_codepoint_t glyph,
 					hb_direction_t direction,
 					hb_position_t *x, hb_position_t *y);
+void
+hb_font_add_glyph_origin_for_direction (hb_font_t *font,
+					hb_codepoint_t glyph,
+					hb_direction_t direction,
+					hb_position_t *x, hb_position_t *y);
+void
+hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
+					     hb_codepoint_t glyph,
+					     hb_direction_t direction,
+					     hb_position_t *x, hb_position_t *y);
 
 void
 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index c545d24..f6a62cf 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -110,6 +110,8 @@ hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
     return FALSE;
 
+  /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
+   * have a Y growing upward.  Hence the extra negation. */
   *y = -ft_face->glyph->metrics.vertAdvance;
   return TRUE;
 }
@@ -140,7 +142,16 @@ hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
     return FALSE;
 
-  /* XXX */*y = ft_face->glyph->metrics.vertAdvance;
+  /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
+   * have a Y growing upward.  Hence the extra negation. */
+  *x = ft_face->glyph->metrics.horiBearingX -   ft_face->glyph->metrics.vertBearingX;
+  *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY);
+
+  /* TODO ??
+  if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
+    FT_Vector_Transform (&vector, &scaled_font->unscaled->Current_Shape);
+   */
+
   return TRUE;
 }
 
@@ -190,7 +201,6 @@ hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
     return FALSE;
 
-  /* XXX: A few negations should be in order here, not sure. */
   extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
   extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
   extents->width = ft_face->glyph->metrics.width;
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 8823f5a..f9c05ec 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -262,6 +262,10 @@ hb_position_default (hb_ot_shape_context_t *c)
 					     c->buffer->props.direction,
 					     &c->buffer->pos[i].x_advance,
 					     &c->buffer->pos[i].y_advance);
+    hb_font_subtract_glyph_origin_for_direction (c->font, c->buffer->info[i].codepoint,
+						 c->buffer->props.direction,
+						 &c->buffer->pos[i].x_offset,
+						 &c->buffer->pos[i].y_offset);
   }
 }
 
commit e609aeb1e24da6b7c812396cddb93ee3c95ef87a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed May 18 10:17:02 2011 -0400

    [hb-view] Add --annotate
    
    Currently it only marks glyph origins.

diff --git a/src/hb-view.cc b/src/hb-view.cc
index 35d8a5f..5dceaf9 100644
--- a/src/hb-view.cc
+++ b/src/hb-view.cc
@@ -62,6 +62,7 @@ static const char *script = NULL;
 static const char *language = NULL;
 static hb_feature_t *features = NULL;
 static unsigned int num_features;
+static hb_bool_t annotate = FALSE;
 static hb_bool_t debug = FALSE;
 
 /* Ugh, global vars.  Ugly, but does the job */
@@ -99,6 +100,7 @@ parse_opts (int argc, char **argv)
     {
       int option_index = 0, c;
       static struct option long_options[] = {
+	{"annotate", 0, &annotate, TRUE},
 	{"background", 1, 0, 'B'},
 	{"debug", 0, &debug, TRUE},
 	{"direction", 1, 0, 'd'},
@@ -411,7 +413,7 @@ create_context (void)
   fr = fg = fb = 0; fa = 255;
   sscanf (fore + (*fore=='#'), "%2x%2x%2x%2x", &fr, &fg, &fb, &fa);
 
-  if (ba == 255 && fa == 255 && br == bg && bg == bb && fr == fg && fg == fb) {
+  if (!annotate && ba == 255 && fa == 255 && br == bg && bg == bb && fr == fg && fg == fb) {
     /* grayscale.  use A8 surface */
     surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
     cr = cairo_create (surface);
@@ -482,6 +484,22 @@ draw (void)
       width = MAX (width, extents.x_advance);
       cairo_save (cr);
       cairo_translate (cr, x, y);
+      if (annotate) {
+        unsigned int i;
+        cairo_save (cr);
+
+	/* Draw actual glyph origins */
+	cairo_set_source_rgba (cr, 1., 0., 0., .5);
+	cairo_set_line_width (cr, 5);
+	cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+	for (i = 0; i < num_glyphs; i++) {
+	  cairo_move_to (cr, glyphs[i].x, glyphs[i].y);
+	  cairo_rel_line_to (cr, 0, 0);
+	}
+	cairo_stroke (cr);
+
+        cairo_restore (cr);
+      }
       cairo_show_glyphs (cr, glyphs, num_glyphs);
       cairo_restore (cr);
       y += ceil (font_extents.height - ceil (font_extents.ascent));
commit b8d76dd74e50d295918cc015e9d2a55e2bf6a461
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue May 17 23:31:00 2011 -0400

    Vertical: Adjust origin in glyph_extents() and glyph_contour_point()
    
    The base for vertical is almost ready now.

diff --git a/src/hb-font.cc b/src/hb-font.cc
index 55b80ee..c2fbb94 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -503,9 +503,10 @@ hb_font_get_glyph_extents_for_direction (hb_font_t *font,
   hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, extents);
 
   if (ret) {
-    /* XXX Adjust origin */
-  } else {
-    /* TODO Simulate using get_h_advance and font_extents? */
+    hb_position_t origin_x, origin_y;
+    hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &origin_y);
+    extents->x_bearing += origin_x;
+    extents->y_bearing += origin_y;
   }
 }
 
@@ -518,7 +519,10 @@ hb_font_get_glyph_contour_point_for_direction (hb_font_t *font,
   hb_bool_t ret = hb_font_get_glyph_contour_point (font, glyph, point_index, x, y);
 
   if (ret) {
-    /* XXX Adjust origin */
+    hb_position_t origin_x, origin_y;
+    hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &origin_y);
+    *x += origin_x;
+    *y += origin_y;
   }
 
   return ret;
commit 190981851fe2bb6479b5c72451279f66fe4f6e23
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue May 17 23:27:22 2011 -0400

    Cosmetic

diff --git a/src/hb-font.cc b/src/hb-font.cc
index 9687252..55b80ee 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -60,19 +60,19 @@ static hb_bool_t
 hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
 				 void *font_data HB_UNUSED,
 				 hb_codepoint_t glyph,
-				 hb_position_t *x_advance,
-				 hb_position_t *y_advance,
+				 hb_position_t *x,
+				 hb_position_t *y,
 				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
     hb_bool_t ret = hb_font_get_glyph_h_advance (font->parent,
 						 glyph,
-						 x_advance, y_advance);
-    font->parent_scale_distance (x_advance, y_advance);
+						 x, y);
+    font->parent_scale_distance (x, y);
     return ret;
   }
 
-  *x_advance = *y_advance = 0;
+  *x = *y = 0;
   return FALSE;
 }
 
@@ -80,19 +80,19 @@ static hb_bool_t
 hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
 				 void *font_data HB_UNUSED,
 				 hb_codepoint_t glyph,
-				 hb_position_t *x_advance,
-				 hb_position_t *y_advance,
+				 hb_position_t *x,
+				 hb_position_t *y,
 				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
     hb_bool_t ret = hb_font_get_glyph_v_advance (font->parent,
 						 glyph,
-						 x_advance, y_advance);
-    font->parent_scale_distance (x_advance, y_advance);
+						 x, y);
+    font->parent_scale_distance (x, y);
     return ret;
   }
 
-  *x_advance = *y_advance = 0;
+  *x = *y = 0;
   return FALSE;
 }
 
@@ -100,19 +100,19 @@ static hb_bool_t
 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
 				void *font_data HB_UNUSED,
 				hb_codepoint_t glyph,
-				hb_position_t *x_origin,
-				hb_position_t *y_origin,
+				hb_position_t *x,
+				hb_position_t *y,
 				void *user_data HB_UNUSED)
 {
   if (font->parent) {
     hb_bool_t ret = hb_font_get_glyph_h_origin (font->parent,
 						glyph,
-						x_origin, y_origin);
-    font->parent_scale_distance (x_origin, y_origin);
+						x, y);
+    font->parent_scale_distance (x, y);
     return ret;
   }
 
-  *x_origin = *y_origin = 0;
+  *x = *y = 0;
   return FALSE;
 }
 
@@ -120,19 +120,19 @@ static hb_bool_t
 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
 				void *font_data HB_UNUSED,
 				hb_codepoint_t glyph,
-				hb_position_t *x_origin,
-				hb_position_t *y_origin,
+				hb_position_t *x,
+				hb_position_t *y,
 				void *user_data HB_UNUSED)
 {
   if (font->parent) {
     hb_bool_t ret = hb_font_get_glyph_v_origin (font->parent,
 						glyph,
-						x_origin, y_origin);
-    font->parent_scale_distance (x_origin, y_origin);
+						x, y);
+    font->parent_scale_distance (x, y);
     return ret;
   }
 
-  *x_origin = *y_origin = 0;
+  *x = *y = 0;
   return FALSE;
 }
 
@@ -141,19 +141,19 @@ hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
 				 void *font_data HB_UNUSED,
 				 hb_codepoint_t left_glyph,
 				 hb_codepoint_t right_glyph,
-				 hb_position_t *x_kern,
-				 hb_position_t *y_kern,
+				 hb_position_t *x,
+				 hb_position_t *y,
 				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
     hb_bool_t ret = hb_font_get_glyph_h_kerning (font->parent,
 						 left_glyph, right_glyph,
-						 x_kern, y_kern);
-    font->parent_scale_distance (x_kern, y_kern);
+						 x, y);
+    font->parent_scale_distance (x, y);
     return ret;
   }
 
-  *x_kern = *y_kern = 0;
+  *x = *y = 0;
   return FALSE;
 }
 
@@ -162,19 +162,19 @@ hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
 				 void *font_data HB_UNUSED,
 				 hb_codepoint_t top_glyph,
 				 hb_codepoint_t bottom_glyph,
-				 hb_position_t *x_kern,
-				 hb_position_t *y_kern,
+				 hb_position_t *x,
+				 hb_position_t *y,
 				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
     hb_bool_t ret = hb_font_get_glyph_v_kerning (font->parent,
 						 top_glyph, bottom_glyph,
-						 x_kern, y_kern);
-    font->parent_scale_distance (x_kern, y_kern);
+						 x, y);
+    font->parent_scale_distance (x, y);
     return ret;
   }
 
-  *x_kern = *y_kern = 0;
+  *x = *y = 0;
   return FALSE;
 }
 
@@ -347,68 +347,68 @@ hb_font_get_glyph (hb_font_t *font,
 hb_bool_t
 hb_font_get_glyph_h_advance (hb_font_t *font,
 			     hb_codepoint_t glyph,
-			     hb_position_t *x_advance, hb_position_t *y_advance)
+			     hb_position_t *x, hb_position_t *y)
 {
-  *x_advance = *y_advance = 0;
+  *x = *y = 0;
   return font->klass->get.glyph_h_advance (font, font->user_data,
-					   glyph, x_advance, y_advance,
+					   glyph, x, y,
 					   font->klass->user_data.glyph_h_advance);
 }
 
 hb_bool_t
 hb_font_get_glyph_v_advance (hb_font_t *font,
 			     hb_codepoint_t glyph,
-			     hb_position_t *x_advance, hb_position_t *y_advance)
+			     hb_position_t *x, hb_position_t *y)
 {
-  *x_advance = *y_advance = 0;
+  *x = *y = 0;
   return font->klass->get.glyph_v_advance (font, font->user_data,
-					   glyph, x_advance, y_advance,
+					   glyph, x, y,
 					   font->klass->user_data.glyph_v_advance);
 }
 
 hb_bool_t
 hb_font_get_glyph_h_origin (hb_font_t *font,
 			    hb_codepoint_t glyph,
-			    hb_position_t *x_origin, hb_position_t *y_origin)
+			    hb_position_t *x, hb_position_t *y)
 {
-  *x_origin = *y_origin = 0;
+  *x = *y = 0;
   return font->klass->get.glyph_h_origin (font, font->user_data,
-					   glyph, x_origin, y_origin,
+					   glyph, x, y,
 					   font->klass->user_data.glyph_h_origin);
 }
 
 hb_bool_t
 hb_font_get_glyph_v_origin (hb_font_t *font,
 			    hb_codepoint_t glyph,
-			    hb_position_t *x_origin, hb_position_t *y_origin)
+			    hb_position_t *x, hb_position_t *y)
 {
-  *x_origin = *y_origin = 0;
+  *x = *y = 0;
   return font->klass->get.glyph_v_origin (font, font->user_data,
-					   glyph, x_origin, y_origin,
+					   glyph, x, y,
 					   font->klass->user_data.glyph_v_origin);
 }
 
 hb_bool_t
 hb_font_get_glyph_h_kerning (hb_font_t *font,
 			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-			     hb_position_t *x_kern, hb_position_t *y_kern)
+			     hb_position_t *x, hb_position_t *y)
 {
-  *x_kern = *y_kern = 0;
+  *x = *y = 0;
   return font->klass->get.glyph_h_kerning (font, font->user_data,
 					   left_glyph, right_glyph,
-					   x_kern, y_kern,
+					   x, y,
 					   font->klass->user_data.glyph_h_kerning);
 }
 
 hb_bool_t
 hb_font_get_glyph_v_kerning (hb_font_t *font,
 			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-			     hb_position_t *x_kern, hb_position_t *y_kern)
+			     hb_position_t *x, hb_position_t *y)
 {
-  *x_kern = *y_kern = 0;
+  *x = *y = 0;
   return font->klass->get.glyph_v_kerning (font, font->user_data,
 				     left_glyph, right_glyph,
-				     x_kern, y_kern,
+				     x, y,
 				     font->klass->user_data.glyph_v_kerning);
 }
 
@@ -443,15 +443,15 @@ void
 hb_font_get_glyph_advance_for_direction (hb_font_t *font,
 					 hb_codepoint_t glyph,
 					 hb_direction_t direction,
-					 hb_position_t *x_advance, hb_position_t *y_advance)
+					 hb_position_t *x, hb_position_t *y)
 {
   if (HB_DIRECTION_IS_VERTICAL (direction)) {
-    hb_bool_t ret = hb_font_get_glyph_v_advance (font, glyph, x_advance, y_advance);
+    hb_bool_t ret = hb_font_get_glyph_v_advance (font, glyph, x, y);
     if (!ret) {
       /* TODO return font_extents.ascent + font_extents.descent? */
     }
   } else {
-    hb_font_get_glyph_h_advance (font, glyph, x_advance, y_advance);
+    hb_font_get_glyph_h_advance (font, glyph, x, y);
   }
 }
 
@@ -459,15 +459,15 @@ void
 hb_font_get_glyph_origin_for_direction (hb_font_t *font,
 					hb_codepoint_t glyph,
 					hb_direction_t direction,
-					hb_position_t *x_origin, hb_position_t *y_origin)
+					hb_position_t *x, hb_position_t *y)
 {
   if (HB_DIRECTION_IS_VERTICAL (direction)) {
-    hb_bool_t ret = hb_font_get_glyph_v_origin (font, glyph, x_origin, y_origin);
+    hb_bool_t ret = hb_font_get_glyph_v_origin (font, glyph, x, y);
     if (!ret) {
       /* TODO return h_origin/2. and font_extents.ascent */
     }
   } else {
-    hb_font_get_glyph_h_origin (font, glyph, x_origin, y_origin);
+    hb_font_get_glyph_h_origin (font, glyph, x, y);
   }
 }
 
@@ -475,17 +475,17 @@ void
 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
 					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
 					 hb_direction_t direction,
-					 hb_position_t *x_kern, hb_position_t *y_kern)
+					 hb_position_t *x, hb_position_t *y)
 {
   switch (direction) {
     case HB_DIRECTION_LTR:
     case HB_DIRECTION_RTL:
-      hb_font_get_glyph_h_kerning (font, first_glyph, second_glyph, x_kern, y_kern);
+      hb_font_get_glyph_h_kerning (font, first_glyph, second_glyph, x, y);
       break;
 
     case HB_DIRECTION_TTB:
     case HB_DIRECTION_BTT:
-      hb_font_get_glyph_v_kerning (font, first_glyph, second_glyph, x_kern, y_kern);
+      hb_font_get_glyph_v_kerning (font, first_glyph, second_glyph, x, y);
       break;
 
     case HB_DIRECTION_INVALID:
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index 3b00068..c545d24 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -82,8 +82,8 @@ static hb_bool_t
 hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
 			   void *font_data,
 			   hb_codepoint_t glyph,
-			   hb_position_t *x_advance,
-			   hb_position_t *y_advance,
+			   hb_position_t *x,
+			   hb_position_t *y,
 			   void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
@@ -92,7 +92,7 @@ hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
     return FALSE;
 
-  *x_advance = ft_face->glyph->metrics.horiAdvance;
+  *x = ft_face->glyph->metrics.horiAdvance;
   return TRUE;
 }
 
@@ -100,8 +100,8 @@ static hb_bool_t
 hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
 			   void *font_data,
 			   hb_codepoint_t glyph,
-			   hb_position_t *x_advance,
-			   hb_position_t *y_advance,
+			   hb_position_t *x,
+			   hb_position_t *y,
 			   void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
@@ -110,7 +110,7 @@ hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
     return FALSE;
 
-  *y_advance = -ft_face->glyph->metrics.vertAdvance;
+  *y = -ft_face->glyph->metrics.vertAdvance;
   return TRUE;
 }
 
@@ -118,8 +118,8 @@ static hb_bool_t
 hb_ft_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
 			  void *font_data HB_UNUSED,
 			  hb_codepoint_t glyph HB_UNUSED,
-			  hb_position_t *x_origin HB_UNUSED,
-			  hb_position_t *y_origin HB_UNUSED,
+			  hb_position_t *x HB_UNUSED,
+			  hb_position_t *y HB_UNUSED,
 			  void *user_data HB_UNUSED)
 {
   /* We always work in the horizontal coordinates. */
@@ -130,8 +130,8 @@ static hb_bool_t
 hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
 			  void *font_data,
 			  hb_codepoint_t glyph,
-			  hb_position_t *x_origin,
-			  hb_position_t *y_origin,
+			  hb_position_t *x,
+			  hb_position_t *y,
 			  void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
@@ -140,7 +140,7 @@ hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
     return FALSE;
 
-  /* XXX */*y_origin = ft_face->glyph->metrics.vertAdvance;
+  /* XXX */*y = ft_face->glyph->metrics.vertAdvance;
   return TRUE;
 }
 
@@ -149,8 +149,8 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font HB_UNUSED,
 			   void *font_data,
 			   hb_codepoint_t left_glyph,
 			   hb_codepoint_t right_glyph,
-			   hb_position_t *x_kern,
-			   hb_position_t *y_kern,
+			   hb_position_t *x,
+			   hb_position_t *y,
 			   void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
@@ -159,8 +159,8 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font HB_UNUSED,
   if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning))
     return FALSE;
 
-  *x_kern = kerning.x;
-  *y_kern = kerning.y;
+  *x = kerning.x;
+  *y = kerning.y;
   return TRUE;
 }
 
@@ -169,8 +169,8 @@ hb_ft_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
 			   void *font_data HB_UNUSED,
 			   hb_codepoint_t top_glyph HB_UNUSED,
 			   hb_codepoint_t bottom_glyph HB_UNUSED,
-			   hb_position_t *x_kern HB_UNUSED,
-			   hb_position_t *y_kern HB_UNUSED,
+			   hb_position_t *x HB_UNUSED,
+			   hb_position_t *y HB_UNUSED,
 			   void *user_data HB_UNUSED)
 {
   /* FreeType API doesn't support vertical kerning */
@@ -187,8 +187,6 @@ hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
   FT_Face ft_face = (FT_Face) font_data;
   int load_flags = FT_LOAD_DEFAULT;
 
-  /* TODO: load_flags, embolden, etc, shape/transform */
-
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
     return FALSE;
 
commit 2c3f51a11c176aa3fc12a9522325efaef2c79d35
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue May 17 23:23:27 2011 -0400

    Minor

diff --git a/src/hb-font.cc b/src/hb-font.cc
index df1dfb1..9687252 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -448,7 +448,7 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
   if (HB_DIRECTION_IS_VERTICAL (direction)) {
     hb_bool_t ret = hb_font_get_glyph_v_advance (font, glyph, x_advance, y_advance);
     if (!ret) {
-      /* TODO Simulate using h_advance and font_extents */
+      /* TODO return font_extents.ascent + font_extents.descent? */
     }
   } else {
     hb_font_get_glyph_h_advance (font, glyph, x_advance, y_advance);
@@ -464,7 +464,7 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font,
   if (HB_DIRECTION_IS_VERTICAL (direction)) {
     hb_bool_t ret = hb_font_get_glyph_v_origin (font, glyph, x_origin, y_origin);
     if (!ret) {
-      /* TODO Simulate using XXX h_origin and font_extents */
+      /* TODO return h_origin/2. and font_extents.ascent */
     }
   } else {
     hb_font_get_glyph_h_origin (font, glyph, x_origin, y_origin);
commit 7e2c85de305be59e1a6afa7d2061e4b7dd00acf7
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue May 17 17:55:03 2011 -0400

    [API] Vertical support, take 2
    
    I like this API *much* better.  Implementation still incomplete, but
    horizontal works.

diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index 875a884..fcd96da 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -52,11 +52,12 @@ struct _hb_font_funcs_t {
   HB_FONT_FUNC_IMPLEMENT (glyph) \
   HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
   HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
   HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
-  HB_FONT_FUNC_IMPLEMENT (h_kerning) \
-  HB_FONT_FUNC_IMPLEMENT (v_kerning) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
   HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
-  HB_FONT_FUNC_IMPLEMENT (contour_point)
+  HB_FONT_FUNC_IMPLEMENT (glyph_contour_point)
 
 
   struct {
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 9cdb302..df1dfb1 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -97,6 +97,26 @@ hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
 }
 
 static hb_bool_t
+hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
+				void *font_data HB_UNUSED,
+				hb_codepoint_t glyph,
+				hb_position_t *x_origin,
+				hb_position_t *y_origin,
+				void *user_data HB_UNUSED)
+{
+  if (font->parent) {
+    hb_bool_t ret = hb_font_get_glyph_h_origin (font->parent,
+						glyph,
+						x_origin, y_origin);
+    font->parent_scale_distance (x_origin, y_origin);
+    return ret;
+  }
+
+  *x_origin = *y_origin = 0;
+  return FALSE;
+}
+
+static hb_bool_t
 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
 				void *font_data HB_UNUSED,
 				hb_codepoint_t glyph,
@@ -117,18 +137,18 @@ hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
 }
 
 static hb_bool_t
-hb_font_get_h_kerning_nil (hb_font_t *font HB_UNUSED,
-			   void *font_data HB_UNUSED,
-			   hb_codepoint_t left_glyph,
-			   hb_codepoint_t right_glyph,
-			   hb_position_t *x_kern,
-			   hb_position_t *y_kern,
-			   void *user_data HB_UNUSED)
+hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
+				 void *font_data HB_UNUSED,
+				 hb_codepoint_t left_glyph,
+				 hb_codepoint_t right_glyph,
+				 hb_position_t *x_kern,
+				 hb_position_t *y_kern,
+				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_bool_t ret = hb_font_get_h_kerning (font->parent,
-					   left_glyph, right_glyph,
-					   x_kern, y_kern);
+    hb_bool_t ret = hb_font_get_glyph_h_kerning (font->parent,
+						 left_glyph, right_glyph,
+						 x_kern, y_kern);
     font->parent_scale_distance (x_kern, y_kern);
     return ret;
   }
@@ -138,18 +158,18 @@ hb_font_get_h_kerning_nil (hb_font_t *font HB_UNUSED,
 }
 
 static hb_bool_t
-hb_font_get_v_kerning_nil (hb_font_t *font HB_UNUSED,
-			   void *font_data HB_UNUSED,
-			   hb_codepoint_t top_glyph,
-			   hb_codepoint_t bottom_glyph,
-			   hb_position_t *x_kern,
-			   hb_position_t *y_kern,
-			   void *user_data HB_UNUSED)
+hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
+				 void *font_data HB_UNUSED,
+				 hb_codepoint_t top_glyph,
+				 hb_codepoint_t bottom_glyph,
+				 hb_position_t *x_kern,
+				 hb_position_t *y_kern,
+				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_bool_t ret = hb_font_get_v_kerning (font->parent,
-					   top_glyph, bottom_glyph,
-					   x_kern, y_kern);
+    hb_bool_t ret = hb_font_get_glyph_v_kerning (font->parent,
+						 top_glyph, bottom_glyph,
+						 x_kern, y_kern);
     font->parent_scale_distance (x_kern, y_kern);
     return ret;
   }
@@ -162,14 +182,12 @@ static hb_bool_t
 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
 			       void *font_data HB_UNUSED,
 			       hb_codepoint_t glyph,
-			       hb_bool_t *vertical,
 			       hb_glyph_extents_t *extents,
 			       void *user_data HB_UNUSED)
 {
   if (font->parent) {
     hb_bool_t ret = hb_font_get_glyph_extents (font->parent,
 					       glyph,
-					       vertical,
 					       extents);
     font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
     font->parent_scale_distance (&extents->width, &extents->height);
@@ -182,20 +200,18 @@ hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
 }
 
 static hb_bool_t
-hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED,
-			       void *font_data HB_UNUSED,
-			       hb_codepoint_t glyph,
-			       unsigned int point_index,
-			       hb_bool_t *vertical,
-			       hb_position_t *x,
-			       hb_position_t *y,
-			       void *user_data HB_UNUSED)
+hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
+				     void *font_data HB_UNUSED,
+				     hb_codepoint_t glyph,
+				     unsigned int point_index,
+				     hb_position_t *x,
+				     hb_position_t *y,
+				     void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_bool_t ret = hb_font_get_contour_point (font->parent,
-					       glyph, point_index,
-					       vertical,
-					       x, y);
+    hb_bool_t ret = hb_font_get_glyph_contour_point (font->parent,
+						     glyph, point_index,
+						     x, y);
     font->parent_scale_position (x, y);
     return ret;
   }
@@ -351,6 +367,17 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
 }
 
 hb_bool_t
+hb_font_get_glyph_h_origin (hb_font_t *font,
+			    hb_codepoint_t glyph,
+			    hb_position_t *x_origin, hb_position_t *y_origin)
+{
+  *x_origin = *y_origin = 0;
+  return font->klass->get.glyph_h_origin (font, font->user_data,
+					   glyph, x_origin, y_origin,
+					   font->klass->user_data.glyph_h_origin);
+}
+
+hb_bool_t
 hb_font_get_glyph_v_origin (hb_font_t *font,
 			    hb_codepoint_t glyph,
 			    hb_position_t *x_origin, hb_position_t *y_origin)
@@ -362,55 +389,51 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
 }
 
 hb_bool_t
-hb_font_get_h_kerning (hb_font_t *font,
-		       hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-		       hb_position_t *x_kern, hb_position_t *y_kern)
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
+			     hb_position_t *x_kern, hb_position_t *y_kern)
 {
   *x_kern = *y_kern = 0;
-  return font->klass->get.h_kerning (font, font->user_data,
-				     left_glyph, right_glyph,
-				     x_kern, y_kern,
-				     font->klass->user_data.h_kerning);
+  return font->klass->get.glyph_h_kerning (font, font->user_data,
+					   left_glyph, right_glyph,
+					   x_kern, y_kern,
+					   font->klass->user_data.glyph_h_kerning);
 }
 
 hb_bool_t
-hb_font_get_v_kerning (hb_font_t *font,
-		       hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-		       hb_position_t *x_kern, hb_position_t *y_kern)
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
+			     hb_position_t *x_kern, hb_position_t *y_kern)
 {
   *x_kern = *y_kern = 0;
-  return font->klass->get.v_kerning (font, font->user_data,
+  return font->klass->get.glyph_v_kerning (font, font->user_data,
 				     left_glyph, right_glyph,
 				     x_kern, y_kern,
-				     font->klass->user_data.v_kerning);
+				     font->klass->user_data.glyph_v_kerning);
 }
 
 hb_bool_t
 hb_font_get_glyph_extents (hb_font_t *font,
 			   hb_codepoint_t glyph,
-			   hb_bool_t *vertical,
 			   hb_glyph_extents_t *extents)
 {
   memset (extents, 0, sizeof (*extents));
   return font->klass->get.glyph_extents (font, font->user_data,
 					 glyph,
-					 vertical,
 					 extents,
 					 font->klass->user_data.glyph_extents);
 }
 
 hb_bool_t
-hb_font_get_contour_point (hb_font_t *font,
-			   hb_codepoint_t glyph, unsigned int point_index,
-			   hb_bool_t *vertical,
-			   hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_contour_point (hb_font_t *font,
+				 hb_codepoint_t glyph, unsigned int point_index,
+				 hb_position_t *x, hb_position_t *y)
 {
   *x = *y = 0;
-  return font->klass->get.contour_point (font, font->user_data,
-					 glyph, point_index,
-					 vertical,
-					 x, y,
-					 font->klass->user_data.contour_point);
+  return font->klass->get.glyph_contour_point (font, font->user_data,
+					       glyph, point_index,
+					       x, y,
+					       font->klass->user_data.glyph_contour_point);
 }
 
 
@@ -433,20 +456,36 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
 }
 
 void
-hb_font_get_kerning_for_direction (hb_font_t *font,
-				   hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
-				   hb_direction_t direction,
-				   hb_position_t *x_kern, hb_position_t *y_kern)
+hb_font_get_glyph_origin_for_direction (hb_font_t *font,
+					hb_codepoint_t glyph,
+					hb_direction_t direction,
+					hb_position_t *x_origin, hb_position_t *y_origin)
+{
+  if (HB_DIRECTION_IS_VERTICAL (direction)) {
+    hb_bool_t ret = hb_font_get_glyph_v_origin (font, glyph, x_origin, y_origin);
+    if (!ret) {
+      /* TODO Simulate using XXX h_origin and font_extents */
+    }
+  } else {
+    hb_font_get_glyph_h_origin (font, glyph, x_origin, y_origin);
+  }
+}
+
+void
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+					 hb_direction_t direction,
+					 hb_position_t *x_kern, hb_position_t *y_kern)
 {
   switch (direction) {
     case HB_DIRECTION_LTR:
     case HB_DIRECTION_RTL:
-      hb_font_get_h_kerning (font, first_glyph, second_glyph, x_kern, y_kern);
+      hb_font_get_glyph_h_kerning (font, first_glyph, second_glyph, x_kern, y_kern);
       break;
 
     case HB_DIRECTION_TTB:
     case HB_DIRECTION_BTT:
-      hb_font_get_v_kerning (font, first_glyph, second_glyph, x_kern, y_kern);
+      hb_font_get_glyph_v_kerning (font, first_glyph, second_glyph, x_kern, y_kern);
       break;
 
     case HB_DIRECTION_INVALID:
@@ -461,28 +500,24 @@ hb_font_get_glyph_extents_for_direction (hb_font_t *font,
 					 hb_direction_t direction,
 					 hb_glyph_extents_t *extents)
 {
-  hb_bool_t vertical = HB_DIRECTION_IS_VERTICAL (direction);
-  hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, &vertical, extents);
+  hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, extents);
 
   if (ret) {
-    if (vertical != HB_DIRECTION_IS_VERTICAL (direction)) {
-      /* XXX Adjust origin */
-    }
+    /* XXX Adjust origin */
   } else {
     /* TODO Simulate using get_h_advance and font_extents? */
   }
 }
 
 hb_bool_t
-hb_font_get_contour_point_for_direction (hb_font_t *font,
-					 hb_codepoint_t glyph, unsigned int point_index,
-					 hb_direction_t direction,
-					 hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_contour_point_for_direction (hb_font_t *font,
+					       hb_codepoint_t glyph, unsigned int point_index,
+					       hb_direction_t direction,
+					       hb_position_t *x, hb_position_t *y)
 {
-  hb_bool_t vertical = HB_DIRECTION_IS_VERTICAL (direction);
-  hb_bool_t ret = hb_font_get_contour_point (font, glyph, point_index, &vertical, x, y);
+  hb_bool_t ret = hb_font_get_glyph_contour_point (font, glyph, point_index, x, y);
 
-  if (ret && vertical != HB_DIRECTION_IS_VERTICAL (direction)) {
+  if (ret) {
     /* XXX Adjust origin */
   }
 
diff --git a/src/hb-font.h b/src/hb-font.h
index 625ff4a..a73b8d1 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -144,34 +144,34 @@ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
 
 typedef hb_bool_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
 						       hb_codepoint_t glyph,
-						       hb_position_t *x_advance, hb_position_t *y_advance,
+						       hb_position_t *x, hb_position_t *y,
 						       void *user_data);
 typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
 typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
 
-typedef hb_bool_t (*hb_font_get_glyph_v_origin_func_t) (hb_font_t *font, void *font_data,
-							hb_codepoint_t glyph,
-							hb_position_t *x_origin, hb_position_t *y_origin,
-							void *user_data);
+typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data,
+						      hb_codepoint_t glyph,
+						      hb_position_t *x, hb_position_t *y,
+						      void *user_data);
+typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
+typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
 
-typedef hb_bool_t (*hb_font_get_kerning_func_t) (hb_font_t *font, void *font_data,
-						 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
-						 hb_position_t *x_kern, hb_position_t *y_kern,
-						 void *user_data);
-typedef hb_font_get_kerning_func_t hb_font_get_h_kerning_func_t;
-typedef hb_font_get_kerning_func_t hb_font_get_v_kerning_func_t;
+typedef hb_bool_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
+						       hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+						       hb_position_t *x, hb_position_t *y,
+						       void *user_data);
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
 
 
 typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
 						       hb_codepoint_t glyph,
-						       hb_bool_t *vertical,
 						       hb_glyph_extents_t *extents,
 						       void *user_data);
-typedef hb_bool_t (*hb_font_get_contour_point_func_t) (hb_font_t *font, void *font_data,
-						       hb_codepoint_t glyph, unsigned int point_index,
-						       hb_bool_t *vertical,
-						       hb_position_t *x, hb_position_t *y,
-						       void *user_data);
+typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data,
+							     hb_codepoint_t glyph, unsigned int point_index,
+							     hb_position_t *x, hb_position_t *y,
+							     void *user_data);
 
 
 /* func setters */
@@ -191,27 +191,31 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
 					void *user_data, hb_destroy_func_t destroy);
 
 void
+hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
+				       hb_font_get_glyph_h_origin_func_t glyph_advance_func,
+				       void *user_data, hb_destroy_func_t destroy);
+void
 hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
 				       hb_font_get_glyph_v_origin_func_t glyph_advance_func,
 				       void *user_data, hb_destroy_func_t destroy);
 
 void
-hb_font_funcs_set_h_kerning_func (hb_font_funcs_t *ffuncs,
-				  hb_font_get_h_kerning_func_t kerning_func,
-				  void *user_data, hb_destroy_func_t destroy);
+hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
+					hb_font_get_glyph_h_kerning_func_t kerning_func,
+					void *user_data, hb_destroy_func_t destroy);
 void
-hb_font_funcs_set_v_kerning_func (hb_font_funcs_t *ffuncs,
-				  hb_font_get_v_kerning_func_t kerning_func,
-				  void *user_data, hb_destroy_func_t destroy);
+hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
+					hb_font_get_glyph_v_kerning_func_t kerning_func,
+					void *user_data, hb_destroy_func_t destroy);
 
 void
 hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
 				      hb_font_get_glyph_extents_func_t glyph_extents_func,
 				      void *user_data, hb_destroy_func_t destroy);
 void
-hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs,
-				      hb_font_get_contour_point_func_t contour_point_func,
-				      void *user_data, hb_destroy_func_t destroy);
+hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
+					    hb_font_get_glyph_contour_point_func_t glyph_contour_point_func,
+					    void *user_data, hb_destroy_func_t destroy);
 
 
 /* func dispatch */
@@ -224,37 +228,39 @@ hb_font_get_glyph (hb_font_t *font,
 hb_bool_t
 hb_font_get_glyph_h_advance (hb_font_t *font,
 			     hb_codepoint_t glyph,
-			     hb_position_t *x_advance, hb_position_t *y_advance);
+			     hb_position_t *x, hb_position_t *y);
 hb_bool_t
 hb_font_get_glyph_v_advance (hb_font_t *font,
 			     hb_codepoint_t glyph,
-			     hb_position_t *x_advance, hb_position_t *y_advance);
+			     hb_position_t *x, hb_position_t *y);
 
 hb_bool_t
+hb_font_get_glyph_h_origin (hb_font_t *font,
+			    hb_codepoint_t glyph,
+			    hb_position_t *x, hb_position_t *y);
+hb_bool_t
 hb_font_get_glyph_v_origin (hb_font_t *font,
 			    hb_codepoint_t glyph,
-			    hb_position_t *x_kern, hb_position_t *y_kern);
+			    hb_position_t *x, hb_position_t *y);
 
 hb_bool_t
-hb_font_get_h_kerning (hb_font_t *font,
-		       hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-		       hb_position_t *x_kern, hb_position_t *y_kern);
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
+			     hb_position_t *x, hb_position_t *y);
 hb_bool_t
-hb_font_get_v_kerning (hb_font_t *font,
-		       hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph,
-		       hb_position_t *x_kern, hb_position_t *y_kern);
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph,
+			     hb_position_t *x, hb_position_t *y);
 
 hb_bool_t
 hb_font_get_glyph_extents (hb_font_t *font,
 			   hb_codepoint_t glyph,
-			   hb_bool_t *vertical,
 			   hb_glyph_extents_t *extents);
 
 hb_bool_t
-hb_font_get_contour_point (hb_font_t *font,
-			   hb_codepoint_t glyph, unsigned int point_index,
-			   hb_bool_t *vertical,
-			   hb_position_t *x, hb_position_t *y);
+hb_font_get_glyph_contour_point (hb_font_t *font,
+				 hb_codepoint_t glyph, unsigned int point_index,
+				 hb_position_t *x, hb_position_t *y);
 
 
 /* high-level funcs, with fallback */
@@ -263,13 +269,18 @@ void
 hb_font_get_glyph_advance_for_direction (hb_font_t *font,
 					 hb_codepoint_t glyph,
 					 hb_direction_t direction,
-					 hb_position_t *x_advance, hb_position_t *y_advance);
+					 hb_position_t *x, hb_position_t *y);
+void
+hb_font_get_glyph_origin_for_direction (hb_font_t *font,
+					hb_codepoint_t glyph,
+					hb_direction_t direction,
+					hb_position_t *x, hb_position_t *y);
 
 void
-hb_font_get_kerning_for_direction (hb_font_t *font,
-				   hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
-				   hb_direction_t direction,
-				   hb_position_t *x_kern, hb_position_t *y_kern);
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+					 hb_direction_t direction,
+					 hb_position_t *x, hb_position_t *y);
 
 void
 hb_font_get_glyph_extents_for_direction (hb_font_t *font,
@@ -278,10 +289,10 @@ hb_font_get_glyph_extents_for_direction (hb_font_t *font,
 					 hb_glyph_extents_t *extents);
 
 hb_bool_t
-hb_font_get_contour_point_for_direction (hb_font_t *font,
-					 hb_codepoint_t glyph, unsigned int point_index,
-					 hb_direction_t direction,
-					 hb_position_t *x, hb_position_t *y);
+hb_font_get_glyph_contour_point_for_direction (hb_font_t *font,
+					       hb_codepoint_t glyph, unsigned int point_index,
+					       hb_direction_t direction,
+					       hb_position_t *x, hb_position_t *y);
 
 
 /*
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index 3e66adc..3b00068 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -115,6 +115,18 @@ hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
 }
 
 static hb_bool_t
+hb_ft_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
+			  void *font_data HB_UNUSED,
+			  hb_codepoint_t glyph HB_UNUSED,
+			  hb_position_t *x_origin HB_UNUSED,
+			  hb_position_t *y_origin HB_UNUSED,
+			  void *user_data HB_UNUSED)
+{
+  /* We always work in the horizontal coordinates. */
+  return TRUE;
+}
+
+static hb_bool_t
 hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
 			  void *font_data,
 			  hb_codepoint_t glyph,
@@ -128,18 +140,18 @@ hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
     return FALSE;
 
-  *y_origin = ft_face->glyph->metrics.vertAdvance;
+  /* XXX */*y_origin = ft_face->glyph->metrics.vertAdvance;
   return TRUE;
 }
 
 static hb_bool_t
-hb_ft_get_h_kerning (hb_font_t *font HB_UNUSED,
-		     void *font_data,
-		     hb_codepoint_t left_glyph,
-		     hb_codepoint_t right_glyph,
-		     hb_position_t *x_kern,
-		     hb_position_t *y_kern,
-		     void *user_data HB_UNUSED)
+hb_ft_get_glyph_h_kerning (hb_font_t *font HB_UNUSED,
+			   void *font_data,
+			   hb_codepoint_t left_glyph,
+			   hb_codepoint_t right_glyph,
+			   hb_position_t *x_kern,
+			   hb_position_t *y_kern,
+			   void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
   FT_Vector kerning;
@@ -153,13 +165,13 @@ hb_ft_get_h_kerning (hb_font_t *font HB_UNUSED,
 }
 
 static hb_bool_t
-hb_ft_get_v_kerning (hb_font_t *font HB_UNUSED,
-		     void *font_data,
-		     hb_codepoint_t top_glyph,
-		     hb_codepoint_t bottom_glyph,
-		     hb_position_t *x_kern,
-		     hb_position_t *y_kern,
-		     void *user_data HB_UNUSED)
+hb_ft_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
+			   void *font_data HB_UNUSED,
+			   hb_codepoint_t top_glyph HB_UNUSED,
+			   hb_codepoint_t bottom_glyph HB_UNUSED,
+			   hb_position_t *x_kern HB_UNUSED,
+			   hb_position_t *y_kern HB_UNUSED,
+			   void *user_data HB_UNUSED)
 {
   /* FreeType API doesn't support vertical kerning */
   return FALSE;
@@ -169,7 +181,6 @@ static hb_bool_t
 hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
 			 void *font_data,
 			 hb_codepoint_t glyph,
-			 hb_bool_t *vertical,
 			 hb_glyph_extents_t *extents,
 			 void *user_data HB_UNUSED)
 {
@@ -190,14 +201,13 @@ hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
 }
 
 static hb_bool_t
-hb_ft_get_contour_point (hb_font_t *font HB_UNUSED,
-			 void *font_data,
-			 hb_codepoint_t glyph,
-			 unsigned int point_index,
-			 hb_bool_t *vertical,
-			 hb_position_t *x,
-			 hb_position_t *y,
-			 void *user_data HB_UNUSED)
+hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
+			       void *font_data,
+			       hb_codepoint_t glyph,
+			       unsigned int point_index,
+			       hb_position_t *x,
+			       hb_position_t *y,
+			       void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
   int load_flags = FT_LOAD_DEFAULT;
@@ -213,7 +223,6 @@ hb_ft_get_contour_point (hb_font_t *font HB_UNUSED,
 
   *x = ft_face->glyph->outline.points[point_index].x;
   *y = ft_face->glyph->outline.points[point_index].y;
-  *vertical = FALSE; /* We always return position in horizontal coordinates */
 
   return TRUE;
 }
@@ -227,11 +236,12 @@ static hb_font_funcs_t ft_ffuncs = {
     hb_ft_get_glyph,
     hb_ft_get_glyph_h_advance,
     hb_ft_get_glyph_v_advance,
+    hb_ft_get_glyph_h_origin,
     hb_ft_get_glyph_v_origin,
-    hb_ft_get_h_kerning,
-    hb_ft_get_v_kerning,
+    hb_ft_get_glyph_h_kerning,
+    hb_ft_get_glyph_v_kerning,
     hb_ft_get_glyph_extents,
-    hb_ft_get_contour_point,
+    hb_ft_get_glyph_contour_point,
   }
 };
 
diff --git a/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh
index a14dada..01ac4ba 100644
--- a/src/hb-ot-layout-gdef-private.hh
+++ b/src/hb-ot-layout-gdef-private.hh
@@ -121,7 +121,7 @@ struct CaretValueFormat2
   inline int get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
   {
     hb_position_t x, y;
-    if (hb_font_get_contour_point_for_direction (font, glyph_id, caretValuePoint, direction, &x, &y))
+    if (hb_font_get_glyph_contour_point_for_direction (font, glyph_id, caretValuePoint, direction, &x, &y))
       return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
     else
       return 0;
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 6701a6a..cfb5e82 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -245,7 +245,7 @@ struct AnchorFormat2
       hb_bool_t ret = false;
 
       if (x_ppem || y_ppem)
-	ret = hb_font_get_contour_point_for_direction (font, glyph_id, anchorPoint, direction, &cx, &cy);
+	ret = hb_font_get_glyph_contour_point_for_direction (font, glyph_id, anchorPoint, direction, &cx, &cy);
       *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate);
       *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate);
   }
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 3b6aa5a..8823f5a 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -278,10 +278,10 @@ hb_truetype_kern (hb_ot_shape_context_t *c)
   unsigned int count = c->buffer->len;
   for (unsigned int i = 1; i < count; i++) {
     hb_position_t x_kern, y_kern, kern1, kern2;
-    hb_font_get_kerning_for_direction (c->font,
-				       c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint,
-				       c->buffer->props.direction,
-				       &x_kern, &y_kern);
+    hb_font_get_glyph_kerning_for_direction (c->font,
+					     c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint,
+					     c->buffer->props.direction,
+					     &x_kern, &y_kern);
 
     kern1 = x_kern >> 1;
     kern2 = x_kern - kern1;
commit 744970af4d884cc87ffa645804578fec8df674a9
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon May 16 18:15:37 2011 -0400

    [API] Add support for vertical text
    
    Design not final yet, and in fact I'm going to change it immediately,
    but this is an standalone change for itself.

diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index 8821ac1..875a884 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -48,28 +48,33 @@ struct _hb_font_funcs_t {
 
   /* Don't access these directly.  Call hb_font_get_*() instead. */
 
+#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
+  HB_FONT_FUNC_IMPLEMENT (glyph) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
+  HB_FONT_FUNC_IMPLEMENT (h_kerning) \
+  HB_FONT_FUNC_IMPLEMENT (v_kerning) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
+  HB_FONT_FUNC_IMPLEMENT (contour_point)
+
+
   struct {
-    hb_font_get_contour_point_func_t	contour_point;
-    hb_font_get_glyph_advance_func_t	glyph_advance;
-    hb_font_get_glyph_extents_func_t	glyph_extents;
-    hb_font_get_glyph_func_t		glyph;
-    hb_font_get_kerning_func_t		kerning;
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
+    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
   } get;
 
   struct {
-    void				*contour_point;
-    void				*glyph_advance;
-    void				*glyph_extents;
-    void				*glyph;
-    void				*kerning;
+#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
+    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
   } user_data;
 
   struct {
-    hb_destroy_func_t			contour_point;
-    hb_destroy_func_t			glyph_advance;
-    hb_destroy_func_t			glyph_extents;
-    hb_destroy_func_t			glyph;
-    hb_destroy_func_t			kerning;
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
+    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
   } destroy;
 };
 
diff --git a/src/hb-font.cc b/src/hb-font.cc
index cff8527..9cdb302 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -42,94 +42,166 @@ HB_BEGIN_DECLS
  */
 
 static hb_bool_t
-hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED,
-			       void *font_data HB_UNUSED,
-			       hb_codepoint_t glyph,
-			       unsigned int point_index,
-			       hb_position_t *x,
-			       hb_position_t *y,
-			       void *user_data HB_UNUSED)
+hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
+		       void *font_data HB_UNUSED,
+		       hb_codepoint_t unicode,
+		       hb_codepoint_t variation_selector,
+		       hb_codepoint_t *glyph,
+		       void *user_data HB_UNUSED)
+{
+  if (font->parent)
+    return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph);
+
+  *glyph = 0;
+  return FALSE;
+}
+
+static hb_bool_t
+hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
+				 void *font_data HB_UNUSED,
+				 hb_codepoint_t glyph,
+				 hb_position_t *x_advance,
+				 hb_position_t *y_advance,
+				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_bool_t ret;
-    ret = hb_font_get_contour_point (font->parent,
-				     glyph, point_index,
-				     x, y);
-    font->parent_scale_position (x, y);
+    hb_bool_t ret = hb_font_get_glyph_h_advance (font->parent,
+						 glyph,
+						 x_advance, y_advance);
+    font->parent_scale_distance (x_advance, y_advance);
     return ret;
   }
 
-  *x = *y = 0;
-
-  return false;
+  *x_advance = *y_advance = 0;
+  return FALSE;
 }
 
-static void
-hb_font_get_glyph_advance_nil (hb_font_t *font HB_UNUSED,
-			       void *font_data HB_UNUSED,
-			       hb_codepoint_t glyph,
-			       hb_position_t *x_advance,
-			       hb_position_t *y_advance,
-			       void *user_data HB_UNUSED)
+static hb_bool_t
+hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
+				 void *font_data HB_UNUSED,
+				 hb_codepoint_t glyph,
+				 hb_position_t *x_advance,
+				 hb_position_t *y_advance,
+				 void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_font_get_glyph_advance (font->parent, glyph, x_advance, y_advance);
+    hb_bool_t ret = hb_font_get_glyph_v_advance (font->parent,
+						 glyph,
+						 x_advance, y_advance);
     font->parent_scale_distance (x_advance, y_advance);
-    return;
+    return ret;
   }
 
   *x_advance = *y_advance = 0;
+  return FALSE;
 }
 
-static void
+static hb_bool_t
+hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
+				void *font_data HB_UNUSED,
+				hb_codepoint_t glyph,
+				hb_position_t *x_origin,
+				hb_position_t *y_origin,
+				void *user_data HB_UNUSED)
+{
+  if (font->parent) {
+    hb_bool_t ret = hb_font_get_glyph_v_origin (font->parent,
+						glyph,
+						x_origin, y_origin);
+    font->parent_scale_distance (x_origin, y_origin);
+    return ret;
+  }
+
+  *x_origin = *y_origin = 0;
+  return FALSE;
+}
+
+static hb_bool_t
+hb_font_get_h_kerning_nil (hb_font_t *font HB_UNUSED,
+			   void *font_data HB_UNUSED,
+			   hb_codepoint_t left_glyph,
+			   hb_codepoint_t right_glyph,
+			   hb_position_t *x_kern,
+			   hb_position_t *y_kern,
+			   void *user_data HB_UNUSED)
+{
+  if (font->parent) {
+    hb_bool_t ret = hb_font_get_h_kerning (font->parent,
+					   left_glyph, right_glyph,
+					   x_kern, y_kern);
+    font->parent_scale_distance (x_kern, y_kern);
+    return ret;
+  }
+
+  *x_kern = *y_kern = 0;
+  return FALSE;
+}
+
+static hb_bool_t
+hb_font_get_v_kerning_nil (hb_font_t *font HB_UNUSED,
+			   void *font_data HB_UNUSED,
+			   hb_codepoint_t top_glyph,
+			   hb_codepoint_t bottom_glyph,
+			   hb_position_t *x_kern,
+			   hb_position_t *y_kern,
+			   void *user_data HB_UNUSED)
+{
+  if (font->parent) {
+    hb_bool_t ret = hb_font_get_v_kerning (font->parent,
+					   top_glyph, bottom_glyph,
+					   x_kern, y_kern);
+    font->parent_scale_distance (x_kern, y_kern);
+    return ret;
+  }
+
+  *x_kern = *y_kern = 0;
+  return FALSE;
+}
+
+static hb_bool_t
 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
 			       void *font_data HB_UNUSED,
 			       hb_codepoint_t glyph,
+			       hb_bool_t *vertical,
 			       hb_glyph_extents_t *extents,
 			       void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_font_get_glyph_extents (font->parent, glyph, extents);
+    hb_bool_t ret = hb_font_get_glyph_extents (font->parent,
+					       glyph,
+					       vertical,
+					       extents);
     font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
     font->parent_scale_distance (&extents->width, &extents->height);
-    return;
+    return ret;
   }
 
   extents->x_bearing = extents->y_bearing = 0;
   extents->width = extents->height = 0;
-}
-
-static hb_bool_t
-hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
-		       void *font_data HB_UNUSED,
-		       hb_codepoint_t unicode,
-		       hb_codepoint_t variation_selector,
-		       hb_codepoint_t *glyph,
-		       void *user_data HB_UNUSED)
-{
-  if (font->parent)
-    return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph);
-
-  *glyph = 0;
   return FALSE;
 }
 
-static void
-hb_font_get_kerning_nil (hb_font_t *font HB_UNUSED,
-			 void *font_data HB_UNUSED,
-			 hb_codepoint_t left_glyph,
-			 hb_codepoint_t right_glyph,
-			 hb_position_t *x_kern,
-			 hb_position_t *y_kern,
-			 void *user_data HB_UNUSED)
+static hb_bool_t
+hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED,
+			       void *font_data HB_UNUSED,
+			       hb_codepoint_t glyph,
+			       unsigned int point_index,
+			       hb_bool_t *vertical,
+			       hb_position_t *x,
+			       hb_position_t *y,
+			       void *user_data HB_UNUSED)
 {
   if (font->parent) {
-    hb_font_get_kerning (font->parent, left_glyph, right_glyph, x_kern, y_kern);
-    font->parent_scale_distance (x_kern, y_kern);
-    return;
+    hb_bool_t ret = hb_font_get_contour_point (font->parent,
+					       glyph, point_index,
+					       vertical,
+					       x, y);
+    font->parent_scale_position (x, y);
+    return ret;
   }
 
-  *x_kern = *y_kern = 0;
+  *x = *y = 0;
+  return FALSE;
 }
 
 
@@ -139,11 +211,9 @@ static hb_font_funcs_t _hb_font_funcs_nil = {
   TRUE, /* immutable */
 
   {
-    hb_font_get_contour_point_nil,
-    hb_font_get_glyph_advance_nil,
-    hb_font_get_glyph_extents_nil,
-    hb_font_get_glyph_nil,
-    hb_font_get_kerning_nil
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
+    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
   }
 };
 
@@ -178,13 +248,9 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
 {
   if (!hb_object_destroy (ffuncs)) return;
 
-#define DESTROY(name) if (ffuncs->destroy.name) ffuncs->destroy.name (ffuncs->user_data.name)
-  DESTROY (contour_point);
-  DESTROY (glyph_advance);
-  DESTROY (glyph_extents);
-  DESTROY (glyph);
-  DESTROY (kerning);
-#undef DESTROY
+#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) ffuncs->destroy.name (ffuncs->user_data.name);
+  HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
 
   free (ffuncs);
 }
@@ -222,7 +288,7 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
 }
 
 
-#define IMPLEMENT(name)                                                  \
+#define HB_FONT_FUNC_IMPLEMENT(name) \
                                                                          \
 void                                                                     \
 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
@@ -247,69 +313,180 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
   }                                                                      \
 }
 
-IMPLEMENT (contour_point);
-IMPLEMENT (glyph_advance);
-IMPLEMENT (glyph_extents);
-IMPLEMENT (glyph);
-IMPLEMENT (kerning);
+HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
 
-#undef IMPLEMENT
 
+hb_bool_t
+hb_font_get_glyph (hb_font_t *font,
+		   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+		   hb_codepoint_t *glyph)
+{
+  *glyph = 0;
+  return font->klass->get.glyph (font, font->user_data,
+				 unicode, variation_selector, glyph,
+				 font->klass->user_data.glyph);
+}
 
 hb_bool_t
-hb_font_get_contour_point (hb_font_t *font,
-			   hb_codepoint_t glyph, unsigned int point_index,
-			   hb_position_t *x, hb_position_t *y)
+hb_font_get_glyph_h_advance (hb_font_t *font,
+			     hb_codepoint_t glyph,
+			     hb_position_t *x_advance, hb_position_t *y_advance)
 {
-  *x = 0; *y = 0;
-  return font->klass->get.contour_point (font, font->user_data,
-					 glyph, point_index,
-					 x, y,
-					 font->klass->user_data.contour_point);
+  *x_advance = *y_advance = 0;
+  return font->klass->get.glyph_h_advance (font, font->user_data,
+					   glyph, x_advance, y_advance,
+					   font->klass->user_data.glyph_h_advance);
 }
 
-void
-hb_font_get_glyph_advance (hb_font_t *font,
-			   hb_codepoint_t glyph,
-			   hb_position_t *x_advance, hb_position_t *y_advance)
+hb_bool_t
+hb_font_get_glyph_v_advance (hb_font_t *font,
+			     hb_codepoint_t glyph,
+			     hb_position_t *x_advance, hb_position_t *y_advance)
 {
   *x_advance = *y_advance = 0;
-  return font->klass->get.glyph_advance (font, font->user_data,
-					 glyph, x_advance, y_advance,
-					 font->klass->user_data.glyph_advance);
+  return font->klass->get.glyph_v_advance (font, font->user_data,
+					   glyph, x_advance, y_advance,
+					   font->klass->user_data.glyph_v_advance);
 }
 
-void
+hb_bool_t
+hb_font_get_glyph_v_origin (hb_font_t *font,
+			    hb_codepoint_t glyph,
+			    hb_position_t *x_origin, hb_position_t *y_origin)
+{
+  *x_origin = *y_origin = 0;
+  return font->klass->get.glyph_v_origin (font, font->user_data,
+					   glyph, x_origin, y_origin,
+					   font->klass->user_data.glyph_v_origin);
+}
+
+hb_bool_t
+hb_font_get_h_kerning (hb_font_t *font,
+		       hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
+		       hb_position_t *x_kern, hb_position_t *y_kern)
+{
+  *x_kern = *y_kern = 0;
+  return font->klass->get.h_kerning (font, font->user_data,
+				     left_glyph, right_glyph,
+				     x_kern, y_kern,
+				     font->klass->user_data.h_kerning);
+}
+
+hb_bool_t
+hb_font_get_v_kerning (hb_font_t *font,
+		       hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
+		       hb_position_t *x_kern, hb_position_t *y_kern)
+{
+  *x_kern = *y_kern = 0;
+  return font->klass->get.v_kerning (font, font->user_data,
+				     left_glyph, right_glyph,
+				     x_kern, y_kern,
+				     font->klass->user_data.v_kerning);
+}
+
+hb_bool_t
 hb_font_get_glyph_extents (hb_font_t *font,
-			   hb_codepoint_t glyph, hb_glyph_extents_t *extents)
+			   hb_codepoint_t glyph,
+			   hb_bool_t *vertical,
+			   hb_glyph_extents_t *extents)
 {
   memset (extents, 0, sizeof (*extents));
   return font->klass->get.glyph_extents (font, font->user_data,
-					 glyph, extents,
+					 glyph,
+					 vertical,
+					 extents,
 					 font->klass->user_data.glyph_extents);
 }
 
 hb_bool_t
-hb_font_get_glyph (hb_font_t *font,
-		   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
-		   hb_codepoint_t *glyph)
+hb_font_get_contour_point (hb_font_t *font,
+			   hb_codepoint_t glyph, unsigned int point_index,
+			   hb_bool_t *vertical,
+			   hb_position_t *x, hb_position_t *y)
 {
-  *glyph = 0;
-  return font->klass->get.glyph (font, font->user_data,
-				 unicode, variation_selector, glyph,
-				 font->klass->user_data.glyph);
+  *x = *y = 0;
+  return font->klass->get.contour_point (font, font->user_data,
+					 glyph, point_index,
+					 vertical,
+					 x, y,
+					 font->klass->user_data.contour_point);
 }
 
+
+/* A bit higher-level, and with fallback */
+
 void
-hb_font_get_kerning (hb_font_t *font,
-		     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-		     hb_position_t *x_kern, hb_position_t *y_kern)
+hb_font_get_glyph_advance_for_direction (hb_font_t *font,
+					 hb_codepoint_t glyph,
+					 hb_direction_t direction,
+					 hb_position_t *x_advance, hb_position_t *y_advance)
+{
+  if (HB_DIRECTION_IS_VERTICAL (direction)) {
+    hb_bool_t ret = hb_font_get_glyph_v_advance (font, glyph, x_advance, y_advance);
+    if (!ret) {
+      /* TODO Simulate using h_advance and font_extents */
+    }
+  } else {
+    hb_font_get_glyph_h_advance (font, glyph, x_advance, y_advance);
+  }
+}
+
+void
+hb_font_get_kerning_for_direction (hb_font_t *font,
+				   hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+				   hb_direction_t direction,
+				   hb_position_t *x_kern, hb_position_t *y_kern)
+{
+  switch (direction) {
+    case HB_DIRECTION_LTR:
+    case HB_DIRECTION_RTL:
+      hb_font_get_h_kerning (font, first_glyph, second_glyph, x_kern, y_kern);
+      break;
+
+    case HB_DIRECTION_TTB:
+    case HB_DIRECTION_BTT:
+      hb_font_get_v_kerning (font, first_glyph, second_glyph, x_kern, y_kern);
+      break;
+
+    case HB_DIRECTION_INVALID:
+    default:
+      break;
+  }
+}
+
+void
+hb_font_get_glyph_extents_for_direction (hb_font_t *font,
+					 hb_codepoint_t glyph,
+					 hb_direction_t direction,
+					 hb_glyph_extents_t *extents)
+{
+  hb_bool_t vertical = HB_DIRECTION_IS_VERTICAL (direction);
+  hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, &vertical, extents);
+
+  if (ret) {
+    if (vertical != HB_DIRECTION_IS_VERTICAL (direction)) {
+      /* XXX Adjust origin */
+    }
+  } else {
+    /* TODO Simulate using get_h_advance and font_extents? */
+  }
+}
+
+hb_bool_t
+hb_font_get_contour_point_for_direction (hb_font_t *font,
+					 hb_codepoint_t glyph, unsigned int point_index,
+					 hb_direction_t direction,
+					 hb_position_t *x, hb_position_t *y)
 {
-  *x_kern = *y_kern = 0;
-  return font->klass->get.kerning (font, font->user_data,
-				   left_glyph, right_glyph,
-				   x_kern, y_kern,
-				   font->klass->user_data.kerning);
+  hb_bool_t vertical = HB_DIRECTION_IS_VERTICAL (direction);
+  hb_bool_t ret = hb_font_get_contour_point (font, glyph, point_index, &vertical, x, y);
+
+  if (ret && vertical != HB_DIRECTION_IS_VERTICAL (direction)) {
+    /* XXX Adjust origin */
+  }
+
+  return ret;
 }
 
 
diff --git a/src/hb-font.h b/src/hb-font.h
index 1342c84..625ff4a 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -134,78 +134,154 @@ typedef struct _hb_glyph_extents_t
 } hb_glyph_extents_t;
 
 
-typedef hb_bool_t (*hb_font_get_contour_point_func_t) (hb_font_t *font, void *font_data,
-						       hb_codepoint_t glyph, unsigned int point_index,
-						       hb_position_t *x, hb_position_t *y,
-						       void *user_data);
-typedef void (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
-						  hb_codepoint_t glyph,
-						  hb_position_t *x_advance, hb_position_t *y_advance,
-						  void *user_data);
-typedef void (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
-						  hb_codepoint_t glyph,
-						  hb_glyph_extents_t *extents,
-						  void *user_data);
+/* func types */
+
 typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
 					       hb_codepoint_t unicode, hb_codepoint_t variation_selector,
 					       hb_codepoint_t *glyph,
 					       void *user_data);
-typedef void (*hb_font_get_kerning_func_t) (hb_font_t *font, void *font_data,
-					    hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-					    hb_position_t *x_kern, hb_position_t *y_kern,
-					    void *user_data);
 
 
+typedef hb_bool_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
+						       hb_codepoint_t glyph,
+						       hb_position_t *x_advance, hb_position_t *y_advance,
+						       void *user_data);
+typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
+typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
+
+typedef hb_bool_t (*hb_font_get_glyph_v_origin_func_t) (hb_font_t *font, void *font_data,
+							hb_codepoint_t glyph,
+							hb_position_t *x_origin, hb_position_t *y_origin,
+							void *user_data);
+
+typedef hb_bool_t (*hb_font_get_kerning_func_t) (hb_font_t *font, void *font_data,
+						 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+						 hb_position_t *x_kern, hb_position_t *y_kern,
+						 void *user_data);
+typedef hb_font_get_kerning_func_t hb_font_get_h_kerning_func_t;
+typedef hb_font_get_kerning_func_t hb_font_get_v_kerning_func_t;
+
+
+typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
+						       hb_codepoint_t glyph,
+						       hb_bool_t *vertical,
+						       hb_glyph_extents_t *extents,
+						       void *user_data);
+typedef hb_bool_t (*hb_font_get_contour_point_func_t) (hb_font_t *font, void *font_data,
+						       hb_codepoint_t glyph, unsigned int point_index,
+						       hb_bool_t *vertical,
+						       hb_position_t *x, hb_position_t *y,
+						       void *user_data);
+
+
+/* func setters */
+
 void
-hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs,
-				      hb_font_get_contour_point_func_t contour_point_func,
-				      void *user_data, hb_destroy_func_t destroy);
+hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
+			      hb_font_get_glyph_func_t glyph_func,
+			      void *user_data, hb_destroy_func_t destroy);
 
 void
-hb_font_funcs_set_glyph_advance_func (hb_font_funcs_t *ffuncs,
-				      hb_font_get_glyph_advance_func_t glyph_advance_func,
-				      void *user_data, hb_destroy_func_t destroy);
+hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
+					hb_font_get_glyph_h_advance_func_t glyph_advance_func,
+					void *user_data, hb_destroy_func_t destroy);
+void
+hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
+					hb_font_get_glyph_v_advance_func_t glyph_advance_func,
+					void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
+				       hb_font_get_glyph_v_origin_func_t glyph_advance_func,
+				       void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_font_funcs_set_h_kerning_func (hb_font_funcs_t *ffuncs,
+				  hb_font_get_h_kerning_func_t kerning_func,
+				  void *user_data, hb_destroy_func_t destroy);
+void
+hb_font_funcs_set_v_kerning_func (hb_font_funcs_t *ffuncs,
+				  hb_font_get_v_kerning_func_t kerning_func,
+				  void *user_data, hb_destroy_func_t destroy);
 
 void
 hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
 				      hb_font_get_glyph_extents_func_t glyph_extents_func,
 				      void *user_data, hb_destroy_func_t destroy);
-
 void
-hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
-			      hb_font_get_glyph_func_t glyph_func,
-			      void *user_data, hb_destroy_func_t destroy);
+hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs,
+				      hb_font_get_contour_point_func_t contour_point_func,
+				      void *user_data, hb_destroy_func_t destroy);
 
-void
-hb_font_funcs_set_kerning_func (hb_font_funcs_t *ffuncs,
-				hb_font_get_kerning_func_t kerning_func,
-				void *user_data, hb_destroy_func_t destroy);
 
+/* func dispatch */
 
 hb_bool_t
-hb_font_get_contour_point (hb_font_t *font,
-			   hb_codepoint_t glyph, unsigned int point_index,
-			   hb_position_t *x, hb_position_t *y);
+hb_font_get_glyph (hb_font_t *font,
+		   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+		   hb_codepoint_t *glyph);
 
-void
-hb_font_get_glyph_advance (hb_font_t *font,
-			   hb_codepoint_t glyph,
-			   hb_position_t *x_advance, hb_position_t *y_advance);
+hb_bool_t
+hb_font_get_glyph_h_advance (hb_font_t *font,
+			     hb_codepoint_t glyph,
+			     hb_position_t *x_advance, hb_position_t *y_advance);
+hb_bool_t
+hb_font_get_glyph_v_advance (hb_font_t *font,
+			     hb_codepoint_t glyph,
+			     hb_position_t *x_advance, hb_position_t *y_advance);
 
-void
+hb_bool_t
+hb_font_get_glyph_v_origin (hb_font_t *font,
+			    hb_codepoint_t glyph,
+			    hb_position_t *x_kern, hb_position_t *y_kern);
+
+hb_bool_t
+hb_font_get_h_kerning (hb_font_t *font,
+		       hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
+		       hb_position_t *x_kern, hb_position_t *y_kern);
+hb_bool_t
+hb_font_get_v_kerning (hb_font_t *font,
+		       hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph,
+		       hb_position_t *x_kern, hb_position_t *y_kern);
+
+hb_bool_t
 hb_font_get_glyph_extents (hb_font_t *font,
 			   hb_codepoint_t glyph,
+			   hb_bool_t *vertical,
 			   hb_glyph_extents_t *extents);
 
 hb_bool_t
-hb_font_get_glyph (hb_font_t *font,
-		   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
-		   hb_codepoint_t *glyph);
+hb_font_get_contour_point (hb_font_t *font,
+			   hb_codepoint_t glyph, unsigned int point_index,
+			   hb_bool_t *vertical,
+			   hb_position_t *x, hb_position_t *y);
+
+
+/* high-level funcs, with fallback */
+
+void
+hb_font_get_glyph_advance_for_direction (hb_font_t *font,
+					 hb_codepoint_t glyph,
+					 hb_direction_t direction,
+					 hb_position_t *x_advance, hb_position_t *y_advance);
 
 void
-hb_font_get_kerning (hb_font_t *font,
-		     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
-		     hb_position_t *x_kern, hb_position_t *y_kern);
+hb_font_get_kerning_for_direction (hb_font_t *font,
+				   hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+				   hb_direction_t direction,
+				   hb_position_t *x_kern, hb_position_t *y_kern);
+
+void
+hb_font_get_glyph_extents_for_direction (hb_font_t *font,
+					 hb_codepoint_t glyph,
+					 hb_direction_t direction,
+					 hb_glyph_extents_t *extents);
+
+hb_bool_t
+hb_font_get_contour_point_for_direction (hb_font_t *font,
+					 hb_codepoint_t glyph, unsigned int point_index,
+					 hb_direction_t direction,
+					 hb_position_t *x, hb_position_t *y);
 
 
 /*
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index aef7e6f..3e66adc 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -36,117 +36,186 @@
 HB_BEGIN_DECLS
 
 
+/* TODO:
+ *
+ * In general, this file does a fine job of what it's supposed to do.
+ * There are, however, things that need more work:
+ *
+ *   - We don't handle any load_flags.  That definitely has API implications. :(
+ *     I believe hb_ft_font_create() should take load_flags input.
+ *
+ *   - We don't handle / allow for emboldening / obliqueing.
+ *
+ *   - In the future, we should add constructors to create fonts in font space.
+ *
+ *   - I believe transforms are not correctly implemented.  FreeType does not
+ *     provide any API to get to the transform/delta set on the face. :(
+ *
+ *   - Always use FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH?
+ */
+
+
 static hb_bool_t
-hb_ft_get_contour_point (hb_font_t *font HB_UNUSED,
-			 void *font_data,
-			 hb_codepoint_t glyph,
-			 unsigned int point_index,
-			 hb_position_t *x,
-			 hb_position_t *y,
-			 void *user_data HB_UNUSED)
+hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
+		 void *font_data,
+		 hb_codepoint_t unicode,
+		 hb_codepoint_t variation_selector,
+		 hb_codepoint_t *glyph,
+		 void *user_data HB_UNUSED)
+
 {
   FT_Face ft_face = (FT_Face) font_data;
-  int load_flags = FT_LOAD_DEFAULT;
 
-  /* TODO: load_flags, embolden, etc */
+#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
+  if (unlikely (variation_selector)) {
+    *glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
+    if (*glyph)
+      return TRUE;
+  }
+#endif
+
+  *glyph = FT_Get_Char_Index (ft_face, unicode);
+  return *glyph != 0;
+}
+
+static hb_bool_t
+hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
+			   void *font_data,
+			   hb_codepoint_t glyph,
+			   hb_position_t *x_advance,
+			   hb_position_t *y_advance,
+			   void *user_data HB_UNUSED)
+{
+  FT_Face ft_face = (FT_Face) font_data;
+  int load_flags = FT_LOAD_DEFAULT;
 
   if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
-      return FALSE;
+    return FALSE;
 
-  if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
-      return FALSE;
+  *x_advance = ft_face->glyph->metrics.horiAdvance;
+  return TRUE;
+}
 
-  if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
-      return FALSE;
+static hb_bool_t
+hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
+			   void *font_data,
+			   hb_codepoint_t glyph,
+			   hb_position_t *x_advance,
+			   hb_position_t *y_advance,
+			   void *user_data HB_UNUSED)
+{
+  FT_Face ft_face = (FT_Face) font_data;
+  int load_flags = FT_LOAD_DEFAULT;
 
-  *x = ft_face->glyph->outline.points[point_index].x;
-  *y = ft_face->glyph->outline.points[point_index].y;
+  if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
+    return FALSE;
 
+  *y_advance = -ft_face->glyph->metrics.vertAdvance;
   return TRUE;
 }
 
-static void
-hb_ft_get_glyph_advance (hb_font_t *font HB_UNUSED,
-			 void *font_data,
-			 hb_codepoint_t glyph,
-			 hb_position_t *x_advance,
-			 hb_position_t *y_advance,
-			 void *user_data HB_UNUSED)
+static hb_bool_t
+hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
+			  void *font_data,
+			  hb_codepoint_t glyph,
+			  hb_position_t *x_origin,
+			  hb_position_t *y_origin,
+			  void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
   int load_flags = FT_LOAD_DEFAULT;
 
-  /* TODO: load_flags, embolden, etc */
+  if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
+    return FALSE;
 
-  if (likely (!FT_Load_Glyph (ft_face, glyph, load_flags)))
-  {
-    *x_advance = ft_face->glyph->advance.x;
-    *y_advance = ft_face->glyph->advance.y;
-  }
+  *y_origin = ft_face->glyph->metrics.vertAdvance;
+  return TRUE;
 }
 
-static void
+static hb_bool_t
+hb_ft_get_h_kerning (hb_font_t *font HB_UNUSED,
+		     void *font_data,
+		     hb_codepoint_t left_glyph,
+		     hb_codepoint_t right_glyph,
+		     hb_position_t *x_kern,
+		     hb_position_t *y_kern,
+		     void *user_data HB_UNUSED)
+{
+  FT_Face ft_face = (FT_Face) font_data;
+  FT_Vector kerning;
+
+  if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning))
+    return FALSE;
+
+  *x_kern = kerning.x;
+  *y_kern = kerning.y;
+  return TRUE;
+}
+
+static hb_bool_t
+hb_ft_get_v_kerning (hb_font_t *font HB_UNUSED,
+		     void *font_data,
+		     hb_codepoint_t top_glyph,
+		     hb_codepoint_t bottom_glyph,
+		     hb_position_t *x_kern,
+		     hb_position_t *y_kern,
+		     void *user_data HB_UNUSED)
+{
+  /* FreeType API doesn't support vertical kerning */
+  return FALSE;
+}
+
+static hb_bool_t
 hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
 			 void *font_data,
 			 hb_codepoint_t glyph,
+			 hb_bool_t *vertical,
 			 hb_glyph_extents_t *extents,
 			 void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
   int load_flags = FT_LOAD_DEFAULT;
 
-  /* TODO: load_flags, embolden, etc */
+  /* TODO: load_flags, embolden, etc, shape/transform */
 
-  if (likely (!FT_Load_Glyph (ft_face, glyph, load_flags)))
-  {
-    /* XXX: A few negations should be in order here, not sure. */
-    extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
-    extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
-    extents->width = ft_face->glyph->metrics.width;
-    extents->height = ft_face->glyph->metrics.height;
-  }
+  if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
+    return FALSE;
+
+  /* XXX: A few negations should be in order here, not sure. */
+  extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
+  extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
+  extents->width = ft_face->glyph->metrics.width;
+  extents->height = ft_face->glyph->metrics.height;
+  return TRUE;
 }
 
 static hb_bool_t
-hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
-		 void *font_data,
-		 hb_codepoint_t unicode,
-		 hb_codepoint_t variation_selector,
-		 hb_codepoint_t *glyph,
-		 void *user_data HB_UNUSED)
-
+hb_ft_get_contour_point (hb_font_t *font HB_UNUSED,
+			 void *font_data,
+			 hb_codepoint_t glyph,
+			 unsigned int point_index,
+			 hb_bool_t *vertical,
+			 hb_position_t *x,
+			 hb_position_t *y,
+			 void *user_data HB_UNUSED)
 {
   FT_Face ft_face = (FT_Face) font_data;
+  int load_flags = FT_LOAD_DEFAULT;
 
-#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
-  if (unlikely (variation_selector)) {
-    *glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
-    if (*glyph)
-      return TRUE;
-  }
-#endif
+  if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
+      return FALSE;
 
-  *glyph = FT_Get_Char_Index (ft_face, unicode);
-  return *glyph != 0;
-}
+  if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
+      return FALSE;
 
-static void
-hb_ft_get_kerning (hb_font_t *font HB_UNUSED,
-		   void *font_data,
-		   hb_codepoint_t left_glyph,
-		   hb_codepoint_t right_glyph,
-		   hb_position_t *x_kern,
-		   hb_position_t *y_kern,
-		   void *user_data HB_UNUSED)
-{
-  FT_Face ft_face = (FT_Face) font_data;
-  FT_Vector kerning;
+  if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
+      return FALSE;
 
-  if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning))
-    return;
+  *x = ft_face->glyph->outline.points[point_index].x;
+  *y = ft_face->glyph->outline.points[point_index].y;
+  *vertical = FALSE; /* We always return position in horizontal coordinates */
 
-  *x_kern = kerning.x;
-  *y_kern = kerning.y;
+  return TRUE;
 }
 
 static hb_font_funcs_t ft_ffuncs = {
@@ -155,11 +224,14 @@ static hb_font_funcs_t ft_ffuncs = {
   TRUE, /* immutable */
 
   {
-    hb_ft_get_contour_point,
-    hb_ft_get_glyph_advance,
-    hb_ft_get_glyph_extents,
     hb_ft_get_glyph,
-    hb_ft_get_kerning
+    hb_ft_get_glyph_h_advance,
+    hb_ft_get_glyph_v_advance,
+    hb_ft_get_glyph_v_origin,
+    hb_ft_get_h_kerning,
+    hb_ft_get_v_kerning,
+    hb_ft_get_glyph_extents,
+    hb_ft_get_contour_point,
   }
 };
 
@@ -210,7 +282,10 @@ hb_ft_face_create (FT_Face           ft_face,
 
     blob = hb_blob_create ((const char *) ft_face->stream->base,
 			   (unsigned int) ft_face->stream->size,
-			   /* TODO: Check FT_FACE_FLAG_EXTERNAL_STREAM? */
+			   /* TODO: We assume that it's mmap()'ed, but FreeType code
+			    * suggests that there are cases we reach here but font is
+			    * not mmapped.  For example, when mmap() fails.  No idea
+			    * how to deal with it better here. */
 			   HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
 			   ft_face, destroy);
     face = hb_face_create (blob, ft_face->face_index);
diff --git a/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh
index d06d7c2..a14dada 100644
--- a/src/hb-ot-layout-gdef-private.hh
+++ b/src/hb-ot-layout-gdef-private.hh
@@ -121,7 +121,7 @@ struct CaretValueFormat2
   inline int get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
   {
     hb_position_t x, y;
-    if (hb_font_get_contour_point (font, glyph_id, caretValuePoint, &x, &y))
+    if (hb_font_get_contour_point_for_direction (font, glyph_id, caretValuePoint, direction, &x, &y))
       return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
     else
       return 0;
diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh
index 100be67..6701a6a 100644
--- a/src/hb-ot-layout-gpos-private.hh
+++ b/src/hb-ot-layout-gpos-private.hh
@@ -210,6 +210,7 @@ struct AnchorFormat1
 
   private:
   inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
+			  hb_direction_t direction HB_UNUSED,
 			  hb_position_t *x, hb_position_t *y) const
   {
       *x = font->em_scale_x (xCoordinate);
@@ -235,6 +236,7 @@ struct AnchorFormat2
 
   private:
   inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
+			  hb_direction_t direction,
 			  hb_position_t *x, hb_position_t *y) const
   {
       unsigned int x_ppem = font->x_ppem;
@@ -243,7 +245,7 @@ struct AnchorFormat2
       hb_bool_t ret = false;
 
       if (x_ppem || y_ppem)
-	ret = hb_font_get_contour_point (font, glyph_id, anchorPoint, &cx, &cy);
+	ret = hb_font_get_contour_point_for_direction (font, glyph_id, anchorPoint, direction, &cx, &cy);
       *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate);
       *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate);
   }
@@ -268,6 +270,7 @@ struct AnchorFormat3
 
   private:
   inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
+			  hb_direction_t direction HB_UNUSED,
 			  hb_position_t *x, hb_position_t *y) const
   {
       *x = font->em_scale_x (xCoordinate);
@@ -306,14 +309,15 @@ struct AnchorFormat3
 struct Anchor
 {
   inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
+			  hb_direction_t direction,
 			  hb_position_t *x, hb_position_t *y) const
   {
     *x = *y = 0;
     switch (u.format) {
-    case 1: u.format1.get_anchor (font, glyph_id, x, y); return;
-    case 2: u.format2.get_anchor (font, glyph_id, x, y); return;
-    case 3: u.format3.get_anchor (font, glyph_id, x, y); return;
-    default:						 return;
+    case 1: u.format1.get_anchor (font, glyph_id, direction, x, y); return;
+    case 2: u.format2.get_anchor (font, glyph_id, direction, x, y); return;
+    case 3: u.format3.get_anchor (font, glyph_id, direction, x, y); return;
+    default:							    return;
     }
   }
 
@@ -403,8 +407,8 @@ struct MarkArray : ArrayOf<MarkRecord>	/* Array of MarkRecords--in Coverage orde
 
     hb_position_t mark_x, mark_y, base_x, base_y;
 
-    mark_anchor.get_anchor (c->font, c->buffer->info[c->buffer->i].codepoint, &mark_x, &mark_y);
-    glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &base_x, &base_y);
+    mark_anchor.get_anchor (c->font, c->buffer->info[c->buffer->i].codepoint, c->direction, &mark_x, &mark_y);
+    glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, c->direction, &base_x, &base_y);
 
     hb_glyph_position_t &o = c->buffer->pos[c->buffer->i];
     o.x_offset = base_x - mark_x;
@@ -859,23 +863,21 @@ struct CursivePosFormat1
     unsigned int i = c->buffer->i;
 
     hb_position_t entry_x, entry_y, exit_x, exit_y;
-    (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, &exit_x, &exit_y);
-    (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, &entry_x, &entry_y);
-
-    hb_direction_t direction = c->buffer->props.direction;
+    (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, c->direction, &exit_x, &exit_y);
+    (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, c->direction, &entry_x, &entry_y);
 
     /* Align the exit anchor of the left/top glyph with the entry anchor of the right/bottom glyph
      * by adjusting advance of the left/top glyph. */
-    if (HB_DIRECTION_IS_BACKWARD (direction))
+    if (HB_DIRECTION_IS_BACKWARD (c->direction))
     {
-      if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
+      if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
 	c->buffer->pos[j].x_advance = c->buffer->pos[j].x_offset + entry_x - exit_x;
       else
 	c->buffer->pos[j].y_advance = c->buffer->pos[j].y_offset + entry_y - exit_y;
     }
     else
     {
-      if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
+      if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
 	c->buffer->pos[i].x_advance = c->buffer->pos[i].x_offset + exit_x - entry_x;
       else
 	c->buffer->pos[i].y_advance = c->buffer->pos[i].y_offset + exit_y - entry_y;
@@ -884,7 +886,7 @@ struct CursivePosFormat1
     if  (c->lookup_props & LookupFlag::RightToLeft)
     {
       c->buffer->pos[i].cursive_chain() = j - i;
-      if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
+      if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
 	c->buffer->pos[i].y_offset = entry_y - exit_y;
       else
 	c->buffer->pos[i].x_offset = entry_x - exit_x;
@@ -892,7 +894,7 @@ struct CursivePosFormat1
     else
     {
       c->buffer->pos[j].cursive_chain() = i - j;
-      if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
+      if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
 	c->buffer->pos[j].y_offset = exit_y - entry_y;
       else
 	c->buffer->pos[j].x_offset = exit_x - entry_x;
@@ -1414,6 +1416,7 @@ struct PosLookup : Lookup
     c->font = font;
     c->face = font->face;
     c->buffer = buffer;
+    c->direction = buffer->props.direction;
     c->lookup_mask = lookup_mask;
     c->context_length = context_length;
     c->nesting_level_left = nesting_level_left;
diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index 56dc817..237b7ce 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -773,6 +773,7 @@ struct SubstLookup : Lookup
 
     c->face = face;
     c->buffer = buffer;
+    c->direction = buffer->props.direction;
     c->lookup_mask = lookup_mask;
     c->context_length = context_length;
     c->nesting_level_left = nesting_level_left;
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 422ee43..4d6656a 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -56,6 +56,7 @@ struct hb_apply_context_t
   hb_font_t *font;
   hb_face_t *face;
   hb_buffer_t *buffer;
+  hb_direction_t direction;
   hb_mask_t lookup_mask;
   unsigned int context_length;
   unsigned int nesting_level_left;
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index ad6c2e2..3b6aa5a 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -169,7 +169,7 @@ hb_ensure_native_direction (hb_ot_shape_context_t *c)
 {
   hb_direction_t direction = c->buffer->props.direction;
 
-  /* TODO vertical */
+  /* XXX vertical */
   if (HB_DIRECTION_IS_HORIZONTAL (direction) &&
       direction != hb_script_get_horizontal_direction (c->buffer->props.script))
   {
@@ -258,9 +258,10 @@ hb_position_default (hb_ot_shape_context_t *c)
 
   unsigned int count = c->buffer->len;
   for (unsigned int i = 0; i < count; i++) {
-    hb_font_get_glyph_advance (c->font, c->buffer->info[i].codepoint,
-			       &c->buffer->pos[i].x_advance,
-			       &c->buffer->pos[i].y_advance);
+    hb_font_get_glyph_advance_for_direction (c->font, c->buffer->info[i].codepoint,
+					     c->buffer->props.direction,
+					     &c->buffer->pos[i].x_advance,
+					     &c->buffer->pos[i].y_advance);
   }
 }
 
@@ -277,7 +278,10 @@ hb_truetype_kern (hb_ot_shape_context_t *c)
   unsigned int count = c->buffer->len;
   for (unsigned int i = 1; i < count; i++) {
     hb_position_t x_kern, y_kern, kern1, kern2;
-    hb_font_get_kerning (c->font, c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint, &x_kern, &y_kern);
+    hb_font_get_kerning_for_direction (c->font,
+				       c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint,
+				       c->buffer->props.direction,
+				       &x_kern, &y_kern);
 
     kern1 = x_kern >> 1;
     kern2 = x_kern - kern1;
diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc
index 9fb6f10..0ed0c83 100644
--- a/src/hb-ot-tag.cc
+++ b/src/hb-ot-tag.cc
@@ -686,7 +686,7 @@ hb_ot_tag_to_language (hb_tag_t tag)
     }
   }
 
-  /* Else return a custom language in the form of "x-hbotXXXX" */
+  /* Else return a custom language in the form of "x-hbotABCD" */
   {
     unsigned char buf[11] = "x-hbot";
     buf[6] = tag >> 24;
diff --git a/test/test-font.c b/test/test-font.c
index 1b68834..0e81b0e 100644
--- a/test/test-font.c
+++ b/test/test-font.c
@@ -117,18 +117,18 @@ _test_font_nil_funcs (hb_font_t *font)
   hb_glyph_extents_t extents;
 
   x = y = 13;
-  g_assert (!hb_font_get_contour_point (font, 17, 2, &x, &y));
+  g_assert (!hb_font_get_contour_point (font, 17, 2, HB_DIRECTION_LTR, &x, &y));
   g_assert_cmpint (x, ==, 0);
   g_assert_cmpint (y, ==, 0);
 
   x = y = 13;
-  hb_font_get_glyph_advance (font, 17, &x, &y);
+  hb_font_get_glyph_h_advance (font, 17, &x, &y);
   g_assert_cmpint (x, ==, 0);
   g_assert_cmpint (y, ==, 0);
 
   extents.x_bearing = extents.y_bearing = 13;
   extents.width = extents.height = 15;
-  hb_font_get_glyph_extents (font, 17, &extents);
+  hb_font_get_glyph_extents (font, 17, HB_DIRECTION_LTR, &extents);
   g_assert_cmpint (extents.x_bearing, ==, 0);
   g_assert_cmpint (extents.y_bearing, ==, 0);
   g_assert_cmpint (extents.width, ==, 0);
@@ -139,7 +139,7 @@ _test_font_nil_funcs (hb_font_t *font)
   g_assert_cmpint (glyph, ==, 0);
 
   x = y = 13;
-  hb_font_get_kerning (font, 17, 19, &x, &y);
+  hb_font_get_h_kerning (font, 17, 19, &x, &y);
   g_assert_cmpint (x, ==, 0);
   g_assert_cmpint (y, ==, 0);
 }
@@ -158,6 +158,7 @@ _test_fontfuncs_nil (hb_font_funcs_t *ffuncs)
   hb_blob_destroy (blob);
   g_assert (!hb_face_is_immutable (face));
   font = hb_font_create (face);
+  g_assert (font);
   g_assert (hb_face_is_immutable (face));
   hb_face_destroy (face);
 
@@ -168,6 +169,7 @@ _test_fontfuncs_nil (hb_font_funcs_t *ffuncs)
   _test_font_nil_funcs (font);
 
   subfont = hb_font_create_sub_font (font);
+  g_assert (subfont);
 
   g_assert_cmpint (freed, ==, 0);
   hb_font_destroy (font);
@@ -203,9 +205,12 @@ test_fontfuncs_nil (void)
 static hb_bool_t
 contour_point_func1 (hb_font_t *font, void *font_data,
 		     hb_codepoint_t glyph, unsigned int point_index,
+		     hb_bool_t *vertical,
 		     hb_position_t *x, hb_position_t *y,
 		     void *user_data)
 {
+  *vertical = FALSE;
+
   if (glyph == 1) {
     *x = 2;
     *y = 3;
@@ -223,6 +228,7 @@ contour_point_func1 (hb_font_t *font, void *font_data,
 static hb_bool_t
 contour_point_func2 (hb_font_t *font, void *font_data,
 		     hb_codepoint_t glyph, unsigned int point_index,
+		     hb_bool_t *vertical,
 		     hb_position_t *x, hb_position_t *y,
 		     void *user_data)
 {
@@ -233,19 +239,22 @@ contour_point_func2 (hb_font_t *font, void *font_data,
   }
 
   return hb_font_get_contour_point (hb_font_get_parent (font),
-				    glyph, point_index, x, y);
+				    glyph, point_index, vertical, x, y);
 }
 
-static void
-glyph_advance_func1 (hb_font_t *font, void *font_data,
-		     hb_codepoint_t glyph,
-		     hb_position_t *x_advance, hb_position_t *y_advance,
-		     void *user_data)
+static hb_bool_t
+glyph_h_advance_func1 (hb_font_t *font, void *font_data,
+		       hb_codepoint_t glyph,
+		       hb_position_t *x_advance, hb_position_t *y_advance,
+		       void *user_data)
 {
   if (glyph == 1) {
     *x_advance = 8;
     *y_advance = 9;
+    return TRUE;
   }
+
+  return FALSE;
 }
 
 static void
@@ -274,24 +283,24 @@ test_fontfuncs_subclassing (void)
   /* setup font1 */
   ffuncs1 = hb_font_funcs_create ();
   hb_font_funcs_set_contour_point_func (ffuncs1, contour_point_func1, NULL, NULL);
-  hb_font_funcs_set_glyph_advance_func (ffuncs1, glyph_advance_func1, NULL, NULL);
+  hb_font_funcs_set_glyph_h_advance_func (ffuncs1, glyph_h_advance_func1, NULL, NULL);
   hb_font_set_funcs (font1, ffuncs1, NULL, NULL);
   hb_font_funcs_destroy (ffuncs1);
 
   x = y = 1;
-  g_assert (hb_font_get_contour_point (font1, 1, 2, &x, &y));
+  g_assert (hb_font_get_contour_point_for_direction (font1, 1, 2, HB_DIRECTION_LTR, &x, &y));
   g_assert_cmpint (x, ==, 2);
   g_assert_cmpint (y, ==, 3);
-  g_assert (hb_font_get_contour_point (font1, 2, 5, &x, &y));
+  g_assert (hb_font_get_contour_point_for_direction (font1, 2, 5, HB_DIRECTION_LTR, &x, &y));
   g_assert_cmpint (x, ==, 4);
   g_assert_cmpint (y, ==, 5);
-  g_assert (!hb_font_get_contour_point (font1, 3, 7, &x, &y));
+  g_assert (!hb_font_get_contour_point_for_direction (font1, 3, 7, HB_DIRECTION_RTL, &x, &y));
   g_assert_cmpint (x, ==, 0);
   g_assert_cmpint (y, ==, 0);
-  hb_font_get_glyph_advance (font1, 1, &x, &y);
+  hb_font_get_glyph_h_advance (font1, 1, &x, &y);
   g_assert_cmpint (x, ==, 8);
   g_assert_cmpint (y, ==, 9);
-  hb_font_get_glyph_advance (font1, 2, &x, &y);
+  hb_font_get_glyph_h_advance (font1, 2, &x, &y);
   g_assert_cmpint (x, ==, 0);
   g_assert_cmpint (y, ==, 0);
 
@@ -307,19 +316,19 @@ test_fontfuncs_subclassing (void)
   hb_font_funcs_destroy (ffuncs2);
 
   x = y = 1;
-  g_assert (hb_font_get_contour_point (font2, 1, 2, &x, &y));
+  g_assert (hb_font_get_contour_point_for_direction (font2, 1, 2, HB_DIRECTION_LTR, &x, &y));
   g_assert_cmpint (x, ==, 6);
   g_assert_cmpint (y, ==, 7);
-  g_assert (hb_font_get_contour_point (font2, 2, 5, &x, &y));
+  g_assert (hb_font_get_contour_point_for_direction (font2, 2, 5, HB_DIRECTION_RTL, &x, &y));
   g_assert_cmpint (x, ==, 4);
   g_assert_cmpint (y, ==, 5);
-  g_assert (!hb_font_get_contour_point (font2, 3, 7, &x, &y));
+  g_assert (!hb_font_get_contour_point_for_direction (font2, 3, 7, HB_DIRECTION_LTR, &x, &y));
   g_assert_cmpint (x, ==, 0);
   g_assert_cmpint (y, ==, 0);
-  hb_font_get_glyph_advance (font2, 1, &x, &y);
+  hb_font_get_glyph_h_advance (font2, 1, &x, &y);
   g_assert_cmpint (x, ==, 8);
   g_assert_cmpint (y, ==, 9);
-  hb_font_get_glyph_advance (font2, 2, &x, &y);
+  hb_font_get_glyph_h_advance (font2, 2, &x, &y);
   g_assert_cmpint (x, ==, 0);
   g_assert_cmpint (y, ==, 0);
 
@@ -332,19 +341,19 @@ test_fontfuncs_subclassing (void)
   hb_font_set_scale (font3, 20, 30);
 
   x = y = 1;
-  g_assert (hb_font_get_contour_point (font3, 1, 2, &x, &y));
+  g_assert (hb_font_get_contour_point_for_direction (font3, 1, 2, HB_DIRECTION_RTL, &x, &y));
   g_assert_cmpint (x, ==, 6*2);
   g_assert_cmpint (y, ==, 7*3);
-  g_assert (hb_font_get_contour_point (font3, 2, 5, &x, &y));
+  g_assert (hb_font_get_contour_point_for_direction (font3, 2, 5, HB_DIRECTION_LTR, &x, &y));
   g_assert_cmpint (x, ==, 4*2);
   g_assert_cmpint (y, ==, 5*3);
-  g_assert (!hb_font_get_contour_point (font3, 3, 7, &x, &y));
+  g_assert (!hb_font_get_contour_point_for_direction (font3, 3, 7, HB_DIRECTION_LTR, &x, &y));
   g_assert_cmpint (x, ==, 0*2);
   g_assert_cmpint (y, ==, 0*3);
-  hb_font_get_glyph_advance (font3, 1, &x, &y);
+  hb_font_get_glyph_h_advance (font3, 1, &x, &y);
   g_assert_cmpint (x, ==, 8*2);
   g_assert_cmpint (y, ==, 9*3);
-  hb_font_get_glyph_advance (font3, 2, &x, &y);
+  hb_font_get_glyph_h_advance (font3, 2, &x, &y);
   g_assert_cmpint (x, ==, 0*2);
   g_assert_cmpint (y, ==, 0*3);
 
diff --git a/test/test-shape.c b/test/test-shape.c
index 82e1f10..531f721 100644
--- a/test/test-shape.c
+++ b/test/test-shape.c
@@ -37,17 +37,18 @@
 
 static const char test_data[] = "test\0data";
 
-static void
+static hb_bool_t
 glyph_advance_func (hb_font_t *font, void *font_data,
 		    hb_codepoint_t glyph,
 		    hb_position_t *x_advance, hb_position_t *y_advance,
 		    void *user_data)
 {
   switch (glyph) {
-  case 1: *x_advance = 10; return;
-  case 2: *x_advance =  6; return;
-  case 3: *x_advance =  5; return;
+  case 1: *x_advance = 10; return TRUE;
+  case 2: *x_advance =  6; return TRUE;
+  case 3: *x_advance =  5; return TRUE;
   }
+  return FALSE;
 }
 
 static hb_bool_t
@@ -65,7 +66,7 @@ glyph_func (hb_font_t *font, void *font_data,
   return FALSE;
 }
 
-static void
+static hb_bool_t
 kerning_func (hb_font_t *font, void *font_data,
 	      hb_codepoint_t left, hb_codepoint_t right,
 	      hb_position_t *x_kern, hb_position_t *y_kern,
@@ -73,7 +74,9 @@ kerning_func (hb_font_t *font, void *font_data,
 {
   if (left == 1 && right == 2) {
     *x_kern = -2;
+    return TRUE;
   }
+  return FALSE;
 }
 
 static const char TesT[] = "TesT";
@@ -98,9 +101,9 @@ test_shape (void)
   hb_font_set_scale (font, 10, 10);
 
   ffuncs = hb_font_funcs_create ();
-  hb_font_funcs_set_glyph_advance_func (ffuncs, glyph_advance_func, NULL, NULL);
+  hb_font_funcs_set_glyph_h_advance_func (ffuncs, glyph_advance_func, NULL, NULL);
   hb_font_funcs_set_glyph_func (ffuncs, glyph_func, NULL, NULL);
-  hb_font_funcs_set_kerning_func (ffuncs, kerning_func, NULL, NULL);
+  hb_font_funcs_set_h_kerning_func (ffuncs, kerning_func, NULL, NULL);
   hb_font_set_funcs (font, ffuncs, NULL, NULL);
   hb_font_funcs_destroy (ffuncs);
 
commit 80dce8b7c8202766d52cc7666355446bbf5b0565
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue May 17 17:08:36 2011 -0400

    Minor

diff --git a/TODO b/TODO
index 0435289..ad13350 100644
--- a/TODO
+++ b/TODO
@@ -9,6 +9,8 @@ General fixes:
 
 - Fix tt kern on/off and GPOS interaction
 
+- Do proper rounding when scaling from font space?
+
 API issues to fix before 1.0:
 ============================
 
commit 5be7d047f6bf54cc577e311b5426c463d2b9b131
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue May 17 15:05:34 2011 -0400

    Check for mmap()
    
    Apparently there exist systems with mprotect(), but not mmap()?

diff --git a/configure.ac b/configure.ac
index 96dbca5..ba3290a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,7 +34,7 @@ AC_SUBST(HB_VERSION)
 
 
 # Functions and headers
-AC_CHECK_FUNCS(mprotect sysconf getpagesize)
+AC_CHECK_FUNCS(mprotect sysconf getpagesize mmap)
 AC_CHECK_HEADERS(unistd.h sys/mman.h)
 
 # Compiler flags
diff --git a/test/test-blob.c b/test/test-blob.c
index f3f7a86..5fcb208 100644
--- a/test/test-blob.c
+++ b/test/test-blob.c
@@ -28,7 +28,7 @@
 
 /* Unit tests for hb-blob.h */
 
-#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT)
+#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT) && defined(HAVE_MMAP)
 
 # define TEST_MMAP 1
 
@@ -109,6 +109,7 @@ free_up_free (fixture_t *fixture)
 }
 
 
+#ifdef TEST_MMAP
 static uintptr_t
 get_pagesize (void)
 {
@@ -133,6 +134,7 @@ free_up_munmap (fixture_t *fixture)
   free_up (fixture);
   munmap (fixture->data, get_pagesize ());
 }
+#endif
 
 #include <errno.h>
 static void
@@ -164,7 +166,7 @@ fixture_init (fixture_t *fixture, gconstpointer user_data)
       free_func = (hb_destroy_func_t) free_up_free;
       break;
 
-#if TEST_MMAP
+#ifdef TEST_MMAP
     case HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE:
     {
       uintptr_t pagesize = get_pagesize ();
commit 4053f3f788353448b41e541ee617aafbe1cac366
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon May 16 16:20:48 2011 -0400

    Cosmetic

diff --git a/src/hb-font.h b/src/hb-font.h
index 34a8f7d..1342c84 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -127,10 +127,10 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
 
 typedef struct _hb_glyph_extents_t
 {
-    hb_position_t x_bearing;
-    hb_position_t y_bearing;
-    hb_position_t width;
-    hb_position_t height;
+  hb_position_t x_bearing;
+  hb_position_t y_bearing;
+  hb_position_t width;
+  hb_position_t height;
 } hb_glyph_extents_t;
 
 
diff --git a/test/test-shape.c b/test/test-shape.c
index 36e4160..82e1f10 100644
--- a/test/test-shape.c
+++ b/test/test-shape.c
@@ -67,9 +67,9 @@ glyph_func (hb_font_t *font, void *font_data,
 
 static void
 kerning_func (hb_font_t *font, void *font_data,
-		    hb_codepoint_t left, hb_codepoint_t right,
-		    hb_position_t *x_kern, hb_position_t *y_kern,
-		    void *user_data)
+	      hb_codepoint_t left, hb_codepoint_t right,
+	      hb_position_t *x_kern, hb_position_t *y_kern,
+	      void *user_data)
 {
   if (left == 1 && right == 2) {
     *x_kern = -2;
commit 56d12e0356bee5a95b870dfbc2100b8caeb5d593
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon May 16 16:01:58 2011 -0400

    Remove unnecessary TODO item

diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index a9186f8..aef7e6f 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -142,7 +142,6 @@ hb_ft_get_kerning (hb_font_t *font HB_UNUSED,
   FT_Face ft_face = (FT_Face) font_data;
   FT_Vector kerning;
 
-  /* TODO: Kern type? */
   if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning))
     return;
 
commit 1883af3796459cafe2d194064403b6b1152c584d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon May 16 15:18:16 2011 -0400

    [hb-view] Start work on vertical support

diff --git a/src/hb-view.cc b/src/hb-view.cc
index 76ee4d9..35d8a5f 100644
--- a/src/hb-view.cc
+++ b/src/hb-view.cc
@@ -350,7 +350,7 @@ _hb_cr_text_glyphs (cairo_t *cr,
   hb_glyph_info_t *hb_glyph;
   hb_glyph_position_t *hb_position;
   unsigned int num_glyphs, i;
-  hb_position_t x;
+  hb_position_t x, y;
 
   hb_buffer = hb_buffer_create (0);
 
@@ -372,12 +372,14 @@ _hb_cr_text_glyphs (cairo_t *cr,
   hb_position = hb_buffer_get_glyph_positions (hb_buffer, NULL);
   cairo_glyphs = cairo_glyph_allocate (num_glyphs);
   x = 0;
+  y = 0;
   for (i = 0; i < num_glyphs; i++)
     {
       cairo_glyphs[i].index = hb_glyph->codepoint;
-      cairo_glyphs[i].x = (hb_position->x_offset + x) * (1./64);
-      cairo_glyphs[i].y = -(hb_position->y_offset)    * (1./64);
-      x += hb_position->x_advance;
+      cairo_glyphs[i].x = ( hb_position->x_offset + x) * (1./64);
+      cairo_glyphs[i].y = (-hb_position->y_offset + y) * (1./64);
+      x +=  hb_position->x_advance;
+      y += -hb_position->y_advance;
 
       hb_glyph++;
       hb_position++;
commit 9aa6f96af5e5940ba5c9596c6ae377fea23c0ec0
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon May 16 15:08:31 2011 -0400

    [hb-view] No need to allocate an extra glyph item at the end

diff --git a/src/hb-view.cc b/src/hb-view.cc
index fac4109..76ee4d9 100644
--- a/src/hb-view.cc
+++ b/src/hb-view.cc
@@ -370,7 +370,7 @@ _hb_cr_text_glyphs (cairo_t *cr,
   num_glyphs = hb_buffer_get_length (hb_buffer);
   hb_glyph = hb_buffer_get_glyph_infos (hb_buffer, NULL);
   hb_position = hb_buffer_get_glyph_positions (hb_buffer, NULL);
-  cairo_glyphs = cairo_glyph_allocate (num_glyphs + 1);
+  cairo_glyphs = cairo_glyph_allocate (num_glyphs);
   x = 0;
   for (i = 0; i < num_glyphs; i++)
     {
@@ -382,7 +382,6 @@ _hb_cr_text_glyphs (cairo_t *cr,
       hb_glyph++;
       hb_position++;
     }
-  cairo_glyphs[i].x = x * (1./64);
   hb_buffer_destroy (hb_buffer);
   hb_font_destroy (hb_font);
   cairo_ft_scaled_font_unlock_face (scaled_font);
commit a0359485c9997e3a211f7c00d40c09074d906c4f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon May 16 15:07:48 2011 -0400

    Minor

diff --git a/test/test-shape.c b/test/test-shape.c
index ab3ddf1..36e4160 100644
--- a/test/test-shape.c
+++ b/test/test-shape.c
@@ -28,6 +28,12 @@
 
 /* Unit tests for hb-shape.h */
 
+/*
+ * This test provides a framework to test aspects of hb_shape() that are
+ * font-independent.  Please add tests for any feature that fits that
+ * description.
+ */
+
 
 static const char test_data[] = "test\0data";
 
commit 92de53ea450eaee077eb1730e6d7a487b20ac721
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon May 16 12:24:56 2011 -0400

    [test/buffer] Add more tests for nil buffer

diff --git a/test/test-buffer.c b/test/test-buffer.c
index 6fba9e2..d387284 100644
--- a/test/test-buffer.c
+++ b/test/test-buffer.c
@@ -712,10 +712,48 @@ test_buffer_utf16_conversion (void)
 }
 
 static void
+test_empty (hb_buffer_t *b)
+{
+  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
+  g_assert (!hb_buffer_get_glyph_infos (b, NULL));
+  g_assert (!hb_buffer_get_glyph_positions (b, NULL));
+}
+
+static void
 test_buffer_empty (void)
 {
+  hb_buffer_t *b = hb_buffer_get_empty ();
+
   g_assert (hb_buffer_get_empty ());
+  g_assert (hb_buffer_get_empty () == b);
   g_assert (hb_buffer_get_empty () == hb_buffer_create (-1));
+
+  g_assert (!hb_buffer_allocation_successful (b));
+
+  test_empty (b);
+
+  hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
+
+  test_empty (b);
+
+  hb_buffer_reverse (b);
+  hb_buffer_reverse_clusters (b);
+
+  g_assert (!hb_buffer_set_length (b, 10));
+
+  test_empty (b);
+
+  g_assert (hb_buffer_set_length (b, 0));
+
+  test_empty (b);
+
+  g_assert (!hb_buffer_allocation_successful (b));
+
+  hb_buffer_reset (b);
+
+  test_empty (b);
+
+  g_assert (!hb_buffer_allocation_successful (b));
 }
 
 int



More information about the HarfBuzz mailing list