[API] Pass down closure user_data to font funcs
authorBehdad Esfahbod <behdad@behdad.org>
Wed, 11 May 2011 00:41:13 +0000 (20:41 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Wed, 11 May 2011 00:41:13 +0000 (20:41 -0400)
src/hb-font-private.hh
src/hb-font.cc
src/hb-font.h
src/hb-ft.cc

index 66ebfd8..e6c79fb 100644 (file)
@@ -46,13 +46,31 @@ struct _hb_font_funcs_t {
 
   hb_bool_t immutable;
 
+  /* Don't access these directly.  Call hb_font_get_*() instead. */
+
+  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;
+  } get;
+
+  struct {
+    void                               *contour_point;
+    void                               *glyph_advance;
+    void                               *glyph_extents;
+    void                               *glyph;
+    void                               *kerning;
+  } user_data;
+
   struct {
-    hb_font_get_glyph_func_t           get_glyph;
-    hb_font_get_glyph_advance_func_t   get_glyph_advance;
-    hb_font_get_glyph_extents_func_t   get_glyph_extents;
-    hb_font_get_contour_point_func_t   get_contour_point;
-    hb_font_get_kerning_func_t         get_kerning;
-  } v;
+    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;
+  } destroy;
 };
 
 
index ae0beaa..6fd247c 100644 (file)
@@ -41,42 +41,47 @@ HB_BEGIN_DECLS
  * hb_font_funcs_t
  */
 
-static hb_codepoint_t
-hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
-                      const void *user_data HB_UNUSED,
-                      hb_codepoint_t unicode HB_UNUSED,
-                      hb_codepoint_t variation_selector HB_UNUSED)
-{ return 0; }
+static hb_bool_t
+hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED,
+                              const void *font_data HB_UNUSED,
+                              unsigned int point_index HB_UNUSED,
+                              hb_codepoint_t glyph HB_UNUSED,
+                              hb_position_t *x HB_UNUSED,
+                              hb_position_t *y HB_UNUSED,
+                              const void *user_data HB_UNUSED)
+{ return false; }
 
 static void
 hb_font_get_glyph_advance_nil (hb_font_t *font HB_UNUSED,
-                              const void *user_data HB_UNUSED,
+                              const void *font_data HB_UNUSED,
                               hb_codepoint_t glyph HB_UNUSED,
                               hb_position_t *x_advance HB_UNUSED,
-                              hb_position_t *y_advance HB_UNUSED)
+                              hb_position_t *y_advance HB_UNUSED,
+                              const void *user_data HB_UNUSED)
 { }
 
 static void
 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
-                              const void *user_data HB_UNUSED,
+                              const void *font_data HB_UNUSED,
                               hb_codepoint_t glyph HB_UNUSED,
-                              hb_glyph_extents_t *extents HB_UNUSED)
+                              hb_glyph_extents_t *extents HB_UNUSED,
+                              const void *user_data HB_UNUSED)
 { }
 
-static hb_bool_t
-hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED,
-                              const void *user_data HB_UNUSED,
-                              unsigned int point_index HB_UNUSED,
-                              hb_codepoint_t glyph HB_UNUSED,
-                              hb_position_t *x HB_UNUSED,
-                              hb_position_t *y HB_UNUSED)
-{ return false; }
+static hb_codepoint_t
+hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
+                      const void *font_data HB_UNUSED,
+                      hb_codepoint_t unicode HB_UNUSED,
+                      hb_codepoint_t variation_selector HB_UNUSED,
+                      const void *user_data HB_UNUSED)
+{ return 0; }
 
 static hb_position_t
 hb_font_get_kerning_nil (hb_font_t *font HB_UNUSED,
-                        const void *user_data HB_UNUSED,
+                        const void *font_data HB_UNUSED,
                         hb_codepoint_t first_glyph HB_UNUSED,
-                        hb_codepoint_t second_glyph HB_UNUSED)
+                        hb_codepoint_t second_glyph HB_UNUSED,
+                        const void *user_data HB_UNUSED)
 { return 0; }
 
 
@@ -84,11 +89,12 @@ static hb_font_funcs_t _hb_font_funcs_nil = {
   HB_OBJECT_HEADER_STATIC,
 
   TRUE, /* immutable */
+
   {
-    hb_font_get_glyph_nil,
+    hb_font_get_contour_point_nil,
     hb_font_get_glyph_advance_nil,
     hb_font_get_glyph_extents_nil,
-    hb_font_get_contour_point_nil,
+    hb_font_get_glyph_nil,
     hb_font_get_kerning_nil
   }
 };
@@ -102,7 +108,7 @@ hb_font_funcs_create (void)
   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
     return &_hb_font_funcs_nil;
 
-  ffuncs->v = _hb_font_funcs_nil.v;
+  ffuncs->get = _hb_font_funcs_nil.get;
 
   return ffuncs;
 }
@@ -118,6 +124,14 @@ 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
+
   free (ffuncs);
 }
 
@@ -154,63 +168,50 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
 }
 
 
-void
-hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
-                             hb_font_get_glyph_func_t glyph_func)
-{
-  if (ffuncs->immutable)
-    return;
-
-  ffuncs->v.get_glyph = glyph_func ? glyph_func : hb_font_get_glyph_nil;
-}
+#define IMPLEMENT(name)                                                  \
+                                                                         \
+void                                                                     \
+hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
+                                 hb_font_get_##name##_func_t  func,      \
+                                 void                        *user_data, \
+                                 hb_destroy_func_t            destroy)   \
+{                                                                        \
+  if (ffuncs->immutable)                                                 \
+    return;                                                              \
+                                                                         \
+  if (ffuncs->destroy.name)                                              \
+    ffuncs->destroy.name (ffuncs->user_data.name);                       \
+                                                                         \
+  if (func) {                                                            \
+    ffuncs->get.name = func;                                             \
+    ffuncs->user_data.name = user_data;                                  \
+    ffuncs->destroy.name = destroy;                                      \
+  } else {                                                               \
+    ffuncs->get.name = hb_font_get_##name##_nil;                         \
+    ffuncs->user_data.name = NULL;                                       \
+    ffuncs->destroy.name = NULL;                                         \
+  }                                                                      \
+}
+
+IMPLEMENT (contour_point);
+IMPLEMENT (glyph_advance);
+IMPLEMENT (glyph_extents);
+IMPLEMENT (glyph);
+IMPLEMENT (kerning);
+
+#undef IMPLEMENT
 
-void
-hb_font_funcs_set_glyph_advance_func (hb_font_funcs_t *ffuncs,
-                                     hb_font_get_glyph_advance_func_t glyph_advance_func)
-{
-  if (ffuncs->immutable)
-    return;
-
-  ffuncs->v.get_glyph_advance = glyph_advance_func ? glyph_advance_func : hb_font_get_glyph_advance_nil;
-}
 
-void
-hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
-                                     hb_font_get_glyph_extents_func_t glyph_extents_func)
-{
-  if (ffuncs->immutable)
-    return;
-
-  ffuncs->v.get_glyph_extents = glyph_extents_func ? glyph_extents_func : hb_font_get_glyph_extents_nil;
-}
-
-void
-hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs,
-                                     hb_font_get_contour_point_func_t contour_point_func)
-{
-  if (ffuncs->immutable)
-    return;
-
-  ffuncs->v.get_contour_point = contour_point_func ? contour_point_func : hb_font_get_contour_point_nil;
-}
-
-void
-hb_font_funcs_set_kerning_func (hb_font_funcs_t *ffuncs,
-                               hb_font_get_kerning_func_t kerning_func)
-{
-  if (ffuncs->immutable)
-    return;
-
-  ffuncs->v.get_kerning = kerning_func ? kerning_func : hb_font_get_kerning_nil;
-}
-
-
-hb_codepoint_t
-hb_font_get_glyph (hb_font_t *font,
-                  hb_codepoint_t unicode, hb_codepoint_t variation_selector)
+hb_bool_t
+hb_font_get_contour_point (hb_font_t *font,
+                          unsigned int point_index,
+                          hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y)
 {
-  return font->klass->v.get_glyph (font, font->user_data,
-                                  unicode, variation_selector);
+  *x = 0; *y = 0;
+  return font->klass->get.contour_point (font, font->user_data,
+                                        point_index,
+                                        glyph, x, y,
+                                        font->klass->user_data.contour_point);
 }
 
 void
@@ -219,8 +220,9 @@ hb_font_get_glyph_advance (hb_font_t *font,
                           hb_position_t *x_advance, hb_position_t *y_advance)
 {
   *x_advance = *y_advance = 0;
-  return font->klass->v.get_glyph_advance (font, font->user_data,
-                                          glyph, x_advance, y_advance);
+  return font->klass->get.glyph_advance (font, font->user_data,
+                                        glyph, x_advance, y_advance,
+                                        font->klass->user_data.glyph_advance);
 }
 
 void
@@ -228,27 +230,27 @@ hb_font_get_glyph_extents (hb_font_t *font,
                           hb_codepoint_t glyph, hb_glyph_extents_t *extents)
 {
   memset (extents, 0, sizeof (*extents));
-  return font->klass->v.get_glyph_extents (font, font->user_data,
-                                          glyph, extents);
+  return font->klass->get.glyph_extents (font, font->user_data,
+                                        glyph, extents,
+                                        font->klass->user_data.glyph_extents);
 }
 
-hb_bool_t
-hb_font_get_contour_point (hb_font_t *font,
-                          unsigned int point_index,
-                          hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y)
+hb_codepoint_t
+hb_font_get_glyph (hb_font_t *font,
+                  hb_codepoint_t unicode, hb_codepoint_t variation_selector)
 {
-  *x = 0; *y = 0;
-  return font->klass->v.get_contour_point (font, font->user_data,
-                                          point_index,
-                                          glyph, x, y);
+  return font->klass->get.glyph (font, font->user_data,
+                                unicode, variation_selector,
+                                font->klass->user_data.glyph);
 }
 
 hb_position_t
 hb_font_get_kerning (hb_font_t *font,
                     hb_codepoint_t first_glyph, hb_codepoint_t second_glyph)
 {
-  return font->klass->v.get_kerning (font, font->user_data,
-                                    first_glyph, second_glyph);
+  return font->klass->get.kerning (font, font->user_data,
+                                  first_glyph, second_glyph,
+                                  font->klass->user_data.kerning);
 }
 
 
index 78a6c83..d937eab 100644 (file)
@@ -121,40 +121,50 @@ typedef struct _hb_glyph_extents_t
     hb_position_t height;
 } hb_glyph_extents_t;
 
-typedef hb_codepoint_t (*hb_font_get_glyph_func_t) (hb_font_t *font, const void *user_data,
-                                                   hb_codepoint_t unicode, hb_codepoint_t variation_selector);
-typedef void (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, const void *user_data,
+typedef hb_codepoint_t (*hb_font_get_glyph_func_t) (hb_font_t *font, const void *font_data,
+                                                   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+                                                   const void *user_data);
+typedef void (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, const void *font_data,
                                                  hb_codepoint_t glyph,
-                                                 hb_position_t *x_advance, hb_position_t *y_advance);
-typedef void (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, const void *user_data,
+                                                 hb_position_t *x_advance, hb_position_t *y_advance,
+                                                 const void *user_data);
+typedef void (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, const void *font_data,
                                                  hb_codepoint_t glyph,
-                                                 hb_glyph_extents_t *extents);
-typedef hb_bool_t (*hb_font_get_contour_point_func_t) (hb_font_t *font, const void *user_data,
+                                                 hb_glyph_extents_t *extents,
+                                                 const void *user_data);
+typedef hb_bool_t (*hb_font_get_contour_point_func_t) (hb_font_t *font, const void *font_data,
                                                       unsigned int point_index, hb_codepoint_t glyph,
-                                                      hb_position_t *x, hb_position_t *y);
-typedef hb_position_t (*hb_font_get_kerning_func_t) (hb_font_t *font, const void *user_data,
-                                                    hb_codepoint_t first_glyph, hb_codepoint_t second_glyph);
+                                                      hb_position_t *x, hb_position_t *y,
+                                                      const void *user_data);
+typedef hb_position_t (*hb_font_get_kerning_func_t) (hb_font_t *font, const void *font_data,
+                                                    hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+                                                    const void *user_data);
 
 
 void
 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
-                             hb_font_get_glyph_func_t glyph_func);
+                             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);
+                                     hb_font_get_glyph_advance_func_t glyph_advance_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);
+                                     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);
+                                     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);
+                               hb_font_get_kerning_func_t kerning_func,
+                               void *user_data, hb_destroy_func_t destroy);
 
 
 hb_codepoint_t
@@ -226,7 +236,7 @@ hb_font_get_face (hb_font_t *font);
 void
 hb_font_set_funcs (hb_font_t         *font,
                   hb_font_funcs_t   *klass,
-                  void              *user_data,
+                  void              *font_data,
                   hb_destroy_func_t  destroy);
 
 
index 9d1dbd1..50ab09f 100644 (file)
 HB_BEGIN_DECLS
 
 
-static hb_codepoint_t
-hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
-                const void *user_data,
-                hb_codepoint_t unicode,
-                hb_codepoint_t variation_selector)
+static hb_bool_t
+hb_ft_get_contour_point (hb_font_t *font HB_UNUSED,
+                        const void *font_data,
+                        unsigned int point_index,
+                        hb_codepoint_t glyph,
+                        hb_position_t *x,
+                        hb_position_t *y,
+                        const void *user_data HB_UNUSED)
 {
-  FT_Face ft_face = (FT_Face) user_data;
+  FT_Face ft_face = (FT_Face) font_data;
+  int load_flags = FT_LOAD_DEFAULT;
 
-#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
-  if (unlikely (variation_selector)) {
-    hb_codepoint_t glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
-    if (glyph)
-      return glyph;
-  }
-#endif
+  /* TODO: load_flags, embolden, etc */
 
-  return FT_Get_Char_Index (ft_face, unicode);
+  if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
+      return FALSE;
+
+  if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
+      return FALSE;
+
+  if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
+      return FALSE;
+
+  *x = ft_face->glyph->outline.points[point_index].x;
+  *y = ft_face->glyph->outline.points[point_index].y;
+
+  return TRUE;
 }
 
 static void
 hb_ft_get_glyph_advance (hb_font_t *font HB_UNUSED,
-                        const void *user_data,
+                        const void *font_data,
                         hb_codepoint_t glyph,
                         hb_position_t *x_advance,
-                        hb_position_t *y_advance)
+                        hb_position_t *y_advance,
+                        const void *user_data HB_UNUSED)
 {
-  FT_Face ft_face = (FT_Face) user_data;
+  FT_Face ft_face = (FT_Face) font_data;
   int load_flags = FT_LOAD_DEFAULT;
 
   /* TODO: load_flags, embolden, etc */
@@ -76,11 +87,12 @@ hb_ft_get_glyph_advance (hb_font_t *font HB_UNUSED,
 
 static void
 hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
-                        const void *user_data,
+                        const void *font_data,
                         hb_codepoint_t glyph,
-                        hb_glyph_extents_t *extents)
+                        hb_glyph_extents_t *extents,
+                        const void *user_data HB_UNUSED)
 {
-  FT_Face ft_face = (FT_Face) user_data;
+  FT_Face ft_face = (FT_Face) font_data;
   int load_flags = FT_LOAD_DEFAULT;
 
   /* TODO: load_flags, embolden, etc */
@@ -95,41 +107,35 @@ 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,
-                        const void *user_data,
-                        unsigned int point_index,
-                        hb_codepoint_t glyph,
-                        hb_position_t *x,
-                        hb_position_t *y)
-{
-  FT_Face ft_face = (FT_Face) user_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 (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
-      return FALSE;
+static hb_codepoint_t
+hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
+                const void *font_data,
+                hb_codepoint_t unicode,
+                hb_codepoint_t variation_selector,
+                const void *user_data HB_UNUSED)
 
-  if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
-      return FALSE;
+{
+  FT_Face ft_face = (FT_Face) font_data;
 
-  *x = ft_face->glyph->outline.points[point_index].x;
-  *y = ft_face->glyph->outline.points[point_index].y;
+#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
+  if (unlikely (variation_selector)) {
+    hb_codepoint_t glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
+    if (glyph)
+      return glyph;
+  }
+#endif
 
-  return TRUE;
+  return FT_Get_Char_Index (ft_face, unicode);
 }
 
 static hb_position_t
 hb_ft_get_kerning (hb_font_t *font HB_UNUSED,
-                  const void *user_data,
+                  const void *font_data,
                   hb_codepoint_t first_glyph,
-                  hb_codepoint_t second_glyph)
+                  hb_codepoint_t second_glyph,
+                  const void *user_data HB_UNUSED)
 {
-  FT_Face ft_face = (FT_Face) user_data;
+  FT_Face ft_face = (FT_Face) font_data;
   FT_Vector kerning;
 
   /* TODO: Kern type? */
@@ -143,11 +149,12 @@ static hb_font_funcs_t ft_ffuncs = {
   HB_OBJECT_HEADER_STATIC,
 
   TRUE, /* immutable */
+
   {
-    hb_ft_get_glyph,
+    hb_ft_get_contour_point,
     hb_ft_get_glyph_advance,
     hb_ft_get_glyph_extents,
-    hb_ft_get_contour_point,
+    hb_ft_get_glyph,
     hb_ft_get_kerning
   }
 };