[API] Add support for vertical text
authorBehdad Esfahbod <behdad@behdad.org>
Mon, 16 May 2011 22:15:37 +0000 (18:15 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Tue, 17 May 2011 21:12:34 +0000 (17:12 -0400)
Design not final yet, and in fact I'm going to change it immediately,
but this is an standalone change for itself.

12 files changed:
src/hb-font-private.hh
src/hb-font.cc
src/hb-font.h
src/hb-ft.cc
src/hb-ot-layout-gdef-private.hh
src/hb-ot-layout-gpos-private.hh
src/hb-ot-layout-gsub-private.hh
src/hb-ot-layout-gsubgpos-private.hh
src/hb-ot-shape.cc
src/hb-ot-tag.cc
test/test-font.c
test/test-shape.c

index 8821ac1..875a884 100644 (file)
@@ -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;
 };
 
index cff8527..9cdb302 100644 (file)
@@ -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;
 }
 
 
index 1342c84..625ff4a 100644 (file)
@@ -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);
 
 
 /*
index aef7e6f..3e66adc 100644 (file)
 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);
index d06d7c2..a14dada 100644 (file)
@@ -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;
index 100be67..6701a6a 100644 (file)
@@ -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;
index 56dc817..237b7ce 100644 (file)
@@ -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;
index 422ee43..4d6656a 100644 (file)
@@ -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;
index ad6c2e2..3b6aa5a 100644 (file)
@@ -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;
index 9fb6f10..0ed0c83 100644 (file)
@@ -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;
index 1b68834..0e81b0e 100644 (file)
@@ -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);
 
index 82e1f10..531f721 100644 (file)
 
 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);