diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh index 66ebfd879..e6c79fb58 100644 --- a/src/hb-font-private.hh +++ b/src/hb-font-private.hh @@ -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_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_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_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; }; diff --git a/src/hb-font.cc b/src/hb-font.cc index ae0beaa20..6fd247c77 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -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 ())) 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; \ + } \ } -void -hb_font_funcs_set_glyph_advance_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_advance_func_t glyph_advance_func) +IMPLEMENT (contour_point); +IMPLEMENT (glyph_advance); +IMPLEMENT (glyph_extents); +IMPLEMENT (glyph); +IMPLEMENT (kerning); + +#undef IMPLEMENT + + +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) { - 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) -{ - 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); } diff --git a/src/hb-font.h b/src/hb-font.h index 78a6c8367..d937eab13 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -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); diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 9d1dbd120..50ab09fa9 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -36,74 +36,16 @@ 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) -{ - FT_Face ft_face = (FT_Face) user_data; - -#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 FT_Get_Char_Index (ft_face, unicode); -} - -static void -hb_ft_get_glyph_advance (hb_font_t *font HB_UNUSED, - const void *user_data, - hb_codepoint_t glyph, - hb_position_t *x_advance, - hb_position_t *y_advance) -{ - FT_Face ft_face = (FT_Face) user_data; - int load_flags = FT_LOAD_DEFAULT; - - /* TODO: load_flags, embolden, etc */ - - if (likely (!FT_Load_Glyph (ft_face, glyph, load_flags))) - { - *x_advance = ft_face->glyph->advance.x; - *y_advance = ft_face->glyph->advance.y; - } -} - -static void -hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED, - const void *user_data, - hb_codepoint_t glyph, - hb_glyph_extents_t *extents) -{ - FT_Face ft_face = (FT_Face) user_data; - int load_flags = FT_LOAD_DEFAULT; - - /* TODO: load_flags, embolden, etc */ - - 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; - } -} - static hb_bool_t hb_ft_get_contour_point (hb_font_t *font HB_UNUSED, - const void *user_data, + const void *font_data, unsigned int point_index, hb_codepoint_t glyph, hb_position_t *x, - hb_position_t *y) + 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; /* TODO: load_flags, embolden, etc */ @@ -123,13 +65,77 @@ hb_ft_get_contour_point (hb_font_t *font HB_UNUSED, return TRUE; } +static void +hb_ft_get_glyph_advance (hb_font_t *font HB_UNUSED, + const void *font_data, + hb_codepoint_t glyph, + hb_position_t *x_advance, + hb_position_t *y_advance, + const 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 (likely (!FT_Load_Glyph (ft_face, glyph, load_flags))) + { + *x_advance = ft_face->glyph->advance.x; + *y_advance = ft_face->glyph->advance.y; + } +} + +static void +hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED, + const void *font_data, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + const 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 (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; + } +} + +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) + +{ + FT_Face ft_face = (FT_Face) font_data; + +#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 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 } };