[API] Add hb_ft_font_set_funcs(), remove hb_ft_get_font_funcs()
authorBehdad Esfahbod <behdad@behdad.org>
Tue, 9 Aug 2011 08:51:24 +0000 (10:51 +0200)
committerBehdad Esfahbod <behdad@behdad.org>
Tue, 9 Aug 2011 09:10:32 +0000 (11:10 +0200)
Remove hb_ft_get_font_funcs() as it cannot be used by the user anyway.

Add hb_ft_font_set_funcs().  Which will make the font internally use
FreeType.  That is, no need for the font to have created using the
hb-ft API.  Just create using hb_face_create()/hb_font_create() and
then call this on the font (after having set font scale).  This
internally creates an FT_Face and attached to the font.

src/Makefile.am
src/hb-ft.cc
src/hb-ft.h
src/test.cc
test/Makefile.am
test/test-object.c

index e999c6c..9b0307a 100644 (file)
@@ -167,8 +167,8 @@ main_CPPFLAGS = $(HBCFLAGS)
 main_LDADD = libharfbuzz.la $(HBLIBS)
 
 test_SOURCES = test.cc
-test_CPPFLAGS = $(HBCFLAGS)
-test_LDADD = libharfbuzz.la $(HBLIBS)
+test_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
+test_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
 
 dist_check_SCRIPTS = \
        check-c-linkage-decls.sh \
index 7152805..497fde7 100644 (file)
 
 
 
+#ifndef HB_DEBUG_FT
+#define HB_DEBUG_FT (HB_DEBUG+0)
+#endif
+
+
 /* TODO:
  *
  * In general, this file does a fine job of what it's supposed to do.
@@ -235,8 +240,8 @@ static hb_font_funcs_t ft_ffuncs = {
   }
 };
 
-hb_font_funcs_t *
-hb_ft_get_font_funcs (void)
+static hb_font_funcs_t *
+_hb_ft_get_font_funcs (void)
 {
   return &ft_ffuncs;
 }
@@ -332,7 +337,7 @@ hb_ft_font_create (FT_Face           ft_face,
   font = hb_font_create (face);
   hb_face_destroy (face);
   hb_font_set_funcs (font,
-                    hb_ft_get_font_funcs (),
+                    _hb_ft_get_font_funcs (),
                     ft_face, NULL);
   hb_font_set_scale (font,
                     ((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM) >> 16,
@@ -345,3 +350,68 @@ hb_ft_font_create (FT_Face           ft_face,
 }
 
 
+
+
+static FT_Library ft_library;
+static hb_bool_t ft_library_initialized;
+static struct ft_library_destructor {
+  ~ft_library_destructor (void) {
+    if (ft_library)
+      FT_Done_FreeType (ft_library);
+  }
+} static_ft_library_destructor;
+
+static FT_Library
+_get_ft_library (void)
+{
+  if (unlikely (!ft_library_initialized)) {
+    FT_Init_FreeType (&ft_library);
+    ft_library_initialized = TRUE;
+  }
+
+  return ft_library;
+}
+
+static void
+_release_blob (FT_Face ft_face)
+{
+  hb_blob_destroy ((hb_blob_t *) ft_face->generic.data);
+}
+
+void
+hb_ft_font_set_funcs (hb_font_t *font)
+{
+  hb_blob_t *blob = hb_face_reference_blob (font->face);
+  unsigned int blob_length;
+  const char *blob_data = hb_blob_get_data (blob, &blob_length);
+  if (unlikely (!blob_length))
+    DEBUG_MSG (FT, font, "Font face has empty blob");
+
+  FT_Face ft_face = NULL;
+  FT_Error err = FT_New_Memory_Face (_get_ft_library (),
+                                    (const FT_Byte *) blob_data,
+                                    blob_length,
+                                    hb_face_get_index (font->face),
+                                    &ft_face);
+
+  if (unlikely (err)) {
+    hb_blob_destroy (blob);
+    DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed");
+    return;
+  }
+
+  hb_font_make_immutable (font);
+
+  FT_Set_Char_Size (ft_face,
+                   font->x_scale, font->y_scale,
+                   font->x_ppem * 72 * 64 / font->x_scale,
+                   font->y_ppem * 72 * 64 / font->y_scale);
+
+  ft_face->generic.data = blob;
+  ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
+
+  hb_font_set_funcs (font,
+                    _hb_ft_get_font_funcs (),
+                    ft_face,
+                    (hb_destroy_func_t) FT_Done_Face);
+}
index 54cce2a..f575d2e 100644 (file)
@@ -38,9 +38,6 @@ HB_BEGIN_DECLS
 
 /* Note: FreeType is not thread-safe.  Hence, these functions are not either. */
 
-hb_font_funcs_t *
-hb_ft_get_font_funcs (void);
-
 hb_face_t *
 hb_ft_face_create (FT_Face           ft_face,
                   hb_destroy_func_t destroy);
@@ -53,6 +50,13 @@ hb_ft_font_create (FT_Face           ft_face,
                   hb_destroy_func_t destroy);
 
 
+
+/* Makes an hb_font_t use FreeType internally to implement font functions. */
+void
+hb_ft_font_set_funcs (hb_font_t *font);
+
+
+
 HB_END_DECLS
 
 #endif /* HB_FT_H */
index d096ab3..c446429 100644 (file)
@@ -37,6 +37,9 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#ifdef HAVE_FREETYPE
+#include "hb-ft.h"
+#endif
 
 int
 main (int argc, char **argv)
@@ -91,6 +94,10 @@ main (int argc, char **argv)
   hb_font_t *font = hb_font_create (face);
   hb_font_set_scale (font, upem, upem);
 
+#if HAVE_FREETYPE
+  hb_ft_font_set_funcs (font);
+#endif
+
   hb_buffer_t *buffer = hb_buffer_create (0);
 
   hb_buffer_add_utf8 (buffer, "\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x8d\xe0\xa4\x95", -1, 0, -1);
index 07f3ccf..b3c8cc2 100644 (file)
@@ -55,14 +55,6 @@ test_shape_complex_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS)
 test_shape_complex_LDADD = $(LDADD) $(FREETYPE_LIBS)
 endif
 
-if HAVE_FREETYPE
-test_object_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS)
-test_object_LDADD = $(LDADD) $(FREETYPE_LIBS)
-else
-test_object_CPPFLAGS = $(AM_CPPFLAGS)
-test_object_LDADD = $(LDADD)
-endif
-
 
 # Default test running environment
 TESTS = $(TEST_PROGS)
index 07cf158..8878cf1 100644 (file)
 /* Unit tests for hb-object-private.h */
 
 
-#ifdef HAVE_FREETYPE
-#include <hb-ft.h>
-#endif
-
-
 static void *
 create_blob (void)
 {
@@ -93,11 +88,7 @@ create_font_funcs (void)
 static void *
 create_font_funcs_inert (void)
 {
-#ifdef HAVE_FREETYPE
-  return hb_ft_get_font_funcs ();
-#else
   return NULL;
-#endif
 }
 
 static void *