From 38b2118724600521c6ad1e49df0667dcdf863634 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 9 Aug 2011 10:51:24 +0200 Subject: [PATCH] [API] Add hb_ft_font_set_funcs(), remove hb_ft_get_font_funcs() 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 | 4 +-- src/hb-ft.cc | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++--- src/hb-ft.h | 10 ++++--- src/test.cc | 7 +++++ test/Makefile.am | 8 ------ test/test-object.c | 9 ------- 6 files changed, 89 insertions(+), 25 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index e999c6c..9b0307a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 7152805..497fde7 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -35,6 +35,11 @@ +#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); +} diff --git a/src/hb-ft.h b/src/hb-ft.h index 54cce2a..f575d2e 100644 --- a/src/hb-ft.h +++ b/src/hb-ft.h @@ -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 */ diff --git a/src/test.cc b/src/test.cc index d096ab3..c446429 100644 --- a/src/test.cc +++ b/src/test.cc @@ -37,6 +37,9 @@ #include #include +#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); diff --git a/test/Makefile.am b/test/Makefile.am index 07f3ccf..b3c8cc2 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -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) diff --git a/test/test-object.c b/test/test-object.c index 07cf158..8878cf1 100644 --- a/test/test-object.c +++ b/test/test-object.c @@ -29,11 +29,6 @@ /* Unit tests for hb-object-private.h */ -#ifdef HAVE_FREETYPE -#include -#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 * -- 2.7.4