diff options
Diffstat (limited to 'pango2')
-rw-r--r-- | pango2/meson.build | 7 | ||||
-rw-r--r-- | pango2/pangocairo-coretext-font.c | 51 | ||||
-rw-r--r-- | pango2/pangocairo-dwrite-font.cpp | 10 | ||||
-rw-r--r-- | pango2/pangocairo-font.c | 219 | ||||
-rw-r--r-- | pango2/pangocairo-ft-font.c | 99 | ||||
-rw-r--r-- | pango2/pangocairo-private.h | 15 | ||||
-rw-r--r-- | pango2/pangocairo-user-font.c | 123 |
7 files changed, 319 insertions, 205 deletions
diff --git a/pango2/meson.build b/pango2/meson.build index 8dce43d8..dbe56249 100644 --- a/pango2/meson.build +++ b/pango2/meson.build @@ -109,6 +109,8 @@ if cairo_dep.found() 'pangocairo-context.c', 'pangocairo-font.c', 'pangocairo-render.c', + 'pangocairo-user-font.c', + 'pangocairo-ft-font.c', ] pango_gir_includes += [ @@ -124,6 +126,11 @@ if host_system == 'darwin' pango_sources += [ 'pangocoretext-fontmap.c', ] + if cairo_dep.found() + pango_sources += [ + 'pangocairo-coretext-font.c', + ] + endif endif if host_system == 'linux' diff --git a/pango2/pangocairo-coretext-font.c b/pango2/pangocairo-coretext-font.c new file mode 100644 index 00000000..e8f0faca --- /dev/null +++ b/pango2/pangocairo-coretext-font.c @@ -0,0 +1,51 @@ +/* + * pangocairo-coretext-font.c: CoreText font handling + * + * Copyright (C) 2022 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "pangocairo-private.h" +#include "pango-font.h" + +#include <Carbon/Carbon.h> +#include <cairo-quartz.h> +#include <hb-coretext.h> + +cairo_font_face_t * +create_cairo_core_text_font_face (Pango2Font *font) +{ + hb_font_t *hbfont; + CTFontRef ctfont; + CGFontRef cgfont; + cairo_font_face_t *cairo_face; + + hbfont = pango2_font_get_hb_font (font); + ctfont = hb_coretext_font_get_ct_font (hbfont); + + if (!ctfont) + return NULL; + + cgfont = CTFontCopyGraphicsFont (ctfont, NULL); + cairo_face = cairo_quartz_font_face_create_for_cgfont (cgfont); + CFRelease (cgfont); + + return cairo_face; +} + diff --git a/pango2/pangocairo-dwrite-font.cpp b/pango2/pangocairo-dwrite-font.cpp index ed5b4f0c..7068d59f 100644 --- a/pango2/pangocairo-dwrite-font.cpp +++ b/pango2/pangocairo-dwrite-font.cpp @@ -32,16 +32,16 @@ /* {{{ DirectWrite PangoCairo utilities */ cairo_font_face_t * -pango_cairo_create_font_face_for_dwrite_pango_font (PangoFont *font) +create_cairo_dwrite_font_face (Pango2Font *font) { hb_font_t *hb_font; IDWriteFontFace *dwrite_font_face = NULL; - cairo_font_face_t *result; + cairo_font_face_t *result = NULL; - hb_font = pango_font_get_hb_font (font); + hb_font = pango2_font_get_hb_font (font); dwrite_font_face = hb_directwrite_face_get_font_face (hb_font_get_face (hb_font)); - - result = cairo_dwrite_font_face_create_for_dwrite_fontface (dwrite_font_face); + if (dwrite_font_face) + result = cairo_dwrite_font_face_create_for_dwrite_fontface (dwrite_font_face); return result; } diff --git a/pango2/pangocairo-font.c b/pango2/pangocairo-font.c index 3eda3d5a..6536671d 100644 --- a/pango2/pangocairo-font.c +++ b/pango2/pangocairo-font.c @@ -35,20 +35,6 @@ #include "pango-userface-private.h" #include "pango-font-private.h" -#if defined (HAVE_CORE_TEXT) - -#include <Carbon/Carbon.h> -#include <cairo-quartz.h> -#include <hb-coretext.h> - -#elif defined (HAVE_FONTCONFIG) - -#include <hb-ot.h> -#include <cairo-ft.h> -#include <freetype/ftmm.h> - -#endif - static Pango2CairoFontPrivate * _pango2_font_get_cairo_font_private (Pango2Font *font); static cairo_scaled_font_t * _pango2_font_get_scaled_font (Pango2Font *font); static void _pango2_cairo_font_private_initialize (Pango2CairoFontPrivate *cf_priv, @@ -77,197 +63,35 @@ _pango2_cairo_font_private_scaled_font_data_destroy (Pango2CairoFontPrivateScale } } -static cairo_user_data_key_t cairo_user_data; - -static cairo_status_t -render_func (cairo_scaled_font_t *scaled_font, - unsigned long glyph, - cairo_t *cr, - cairo_text_extents_t *extents) -{ - cairo_font_face_t *font_face; - Pango2Font *font; - Pango2UserFace *face; - hb_glyph_extents_t glyph_extents; - hb_position_t h_advance; - hb_position_t v_advance; - gboolean is_color; - - font_face = cairo_scaled_font_get_font_face (scaled_font); - font = cairo_font_face_get_user_data (font_face, &cairo_user_data); - face = PANGO2_USER_FACE (font->face); - - extents->x_bearing = 0; - extents->y_bearing = 0; - extents->width = 0; - extents->height = 0; - extents->x_advance = 0; - extents->y_advance = 0; - - if (!face->glyph_info_func (face, 1024, - (hb_codepoint_t)glyph, - &glyph_extents, - &h_advance, &v_advance, - &is_color, - face->user_data)) - { - return CAIRO_STATUS_USER_FONT_ERROR; - } - - extents->x_bearing = glyph_extents.x_bearing / 1024.; - extents->y_bearing = - glyph_extents.y_bearing / 1024.; - extents->width = glyph_extents.width / 1024.; - extents->height = - glyph_extents.height / 1024.; - extents->x_advance = h_advance / 1024.; - extents->y_advance = v_advance / 1024.; - - if (!face->render_func (face, font->size, - (hb_codepoint_t)glyph, - face->user_data, - "cairo", - cr)) - { - return CAIRO_STATUS_USER_FONT_ERROR; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -init_func (cairo_scaled_font_t *scaled_font, - cairo_t *cr, - cairo_font_extents_t *extents) -{ - cairo_font_face_t *cairo_face; - Pango2Font *font; - Pango2UserFace *face; - hb_font_extents_t font_extents; - - cairo_face = cairo_scaled_font_get_font_face (scaled_font); - font = cairo_font_face_get_user_data (cairo_face, &cairo_user_data); - face = (Pango2UserFace *) pango2_font_get_face (font); - - face->font_info_func (face, - pango2_font_get_size (font), - &font_extents, - face->user_data); - - extents->ascent = font_extents.ascender / (font_extents.ascender + font_extents.descender); - extents->descent = font_extents.descender / (font_extents.ascender + font_extents.descender); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_font_face_t * -create_cairo_font_face_for_user_font (Pango2Font *font) -{ - cairo_font_face_t *cairo_face; - - cairo_face = cairo_user_font_face_create (); - cairo_font_face_set_user_data (cairo_face, &cairo_user_data, font, NULL); - cairo_user_font_face_set_init_func (cairo_face, init_func); - cairo_user_font_face_set_render_color_glyph_func (cairo_face, render_func); - - return cairo_face; -} - -#if defined (HAVE_CORE_TEXT) - static cairo_font_face_t * -create_cairo_font_face_for_hb_font (Pango2Font *font) +create_cairo_font_face (Pango2Font *font) { - hb_font_t *hbfont; - CTFontRef ctfont; - CGFontRef cgfont; cairo_font_face_t *cairo_face; - hbfont = pango2_font_get_hb_font (font); - ctfont = hb_coretext_font_get_ct_font (hbfont); - cgfont = CTFontCopyGraphicsFont (ctfont, NULL); + if (PANGO2_IS_USER_FONT (font)) + return create_cairo_user_font_face (font); - cairo_face = cairo_quartz_font_face_create_for_cgfont (cgfont); - - CFRelease (cgfont); - - return cairo_face; -} - -#elif defined (HAVE_DIRECT_WRITE) - -static cairo_font_face_t * -create_cairo_font_face_for_hb_font (Pango2Font *font) -{ - return pango2_cairo_create_font_face_for_dwrite_pango2_font (font); -} - -#else - -static cairo_font_face_t * -create_cairo_font_face_for_hb_font (Pango2Font *font) -{ - static FT_Library ft_library; - - Pango2HbFace *face = PANGO2_HB_FACE (font->face); - hb_blob_t *blob; - const char *blob_data; - unsigned int blob_length; - FT_Face ft_face; - hb_font_t *hb_font; - unsigned int num_coords; - const int *coords; - cairo_font_face_t *cairo_face; - static const cairo_user_data_key_t key; - static const cairo_user_data_key_t key2; - FT_Error error; - - if (g_once_init_enter (&ft_library)) - { - FT_Library library; - FT_Init_FreeType (&library); - g_once_init_leave (&ft_library, library); - } - - hb_font = pango2_font_get_hb_font (font); - blob = hb_face_reference_blob (hb_font_get_face (hb_font)); - blob_data = hb_blob_get_data (blob, &blob_length); - - if ((error = FT_New_Memory_Face (ft_library, - (const FT_Byte *) blob_data, - blob_length, - hb_face_get_index (face->face), - &ft_face)) != 0) - { - hb_blob_destroy (blob); - g_warning ("FT_New_Memory_Face failed: %d %s", error, FT_Error_String (error)); - return NULL; - } - - coords = hb_font_get_var_coords_normalized (hb_font, &num_coords); - if (num_coords > 0) - { - FT_Fixed *ft_coords = (FT_Fixed *) g_alloca (num_coords * sizeof (FT_Fixed)); - - for (unsigned int i = 0; i < num_coords; i++) - ft_coords[i] = coords[i] << 2; - - FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); - } - - cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, FT_LOAD_NO_HINTING | FT_LOAD_COLOR); +#ifdef HAVE_CORE_TEXT + cairo_face = create_cairo_core_text_font_face (font); + if (cairo_face) + return cairo_face; +#endif - if (face->embolden) - cairo_ft_font_face_set_synthesize (cairo_face, CAIRO_FT_SYNTHESIZE_BOLD); +#ifdef HAVE_DIRECT_WRITE + cairo_face = create_dwrite_font_face (font); + if (cairo_face) + return cairo_face; +#endif - cairo_font_face_set_user_data (cairo_face, &key, - ft_face, (cairo_destroy_func_t) FT_Done_Face); - cairo_font_face_set_user_data (cairo_face, &key2, - blob, (cairo_destroy_func_t) hb_blob_destroy); +#ifdef CAIRO_HAS_FT_FONT + cairo_face = create_cairo_ft_font_face (font); + if (cairo_face) + return cairo_face; +#endif - return cairo_face; + return NULL; } -#endif - static cairo_scaled_font_t * _pango2_cairo_font_private_get_scaled_font (Pango2CairoFontPrivate *cf_priv) { @@ -284,10 +108,7 @@ _pango2_cairo_font_private_get_scaled_font (Pango2CairoFontPrivate *cf_priv) return NULL; } - if (PANGO2_IS_HB_FONT (cf_priv->cfont)) - font_face = create_cairo_font_face_for_hb_font (cf_priv->cfont); - else if (PANGO2_IS_USER_FONT (cf_priv->cfont)) - font_face = create_cairo_font_face_for_user_font (cf_priv->cfont); + font_face = create_cairo_font_face (cf_priv->cfont); if (G_UNLIKELY (font_face == NULL)) goto done; diff --git a/pango2/pangocairo-ft-font.c b/pango2/pangocairo-ft-font.c new file mode 100644 index 00000000..f8595ac0 --- /dev/null +++ b/pango2/pangocairo-ft-font.c @@ -0,0 +1,99 @@ +/* + * pangocairo-ft-font.c: Freetype font handling + * + * Copyright (C) 2022 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "pango-features.h" +#include "pangocairo-private.h" +#include "pango-hbfont-private.h" +#include "pango-hbface-private.h" + +#ifdef CAIRO_HAS_FT_FONT + +#include <hb-ot.h> +#include <cairo-ft.h> +#include <freetype/ftmm.h> + +cairo_font_face_t * +create_cairo_ft_font_face (Pango2Font *font) +{ + static FT_Library ft_library; + + Pango2HbFace *face = PANGO2_HB_FACE (font->face); + hb_blob_t *blob; + const char *blob_data; + unsigned int blob_length; + FT_Face ft_face; + hb_font_t *hb_font; + unsigned int num_coords; + const int *coords; + cairo_font_face_t *cairo_face; + static const cairo_user_data_key_t key; + static const cairo_user_data_key_t key2; + FT_Error error; + + if (g_once_init_enter (&ft_library)) + { + FT_Library library; + FT_Init_FreeType (&library); + g_once_init_leave (&ft_library, library); + } + + hb_font = pango2_font_get_hb_font (font); + blob = hb_face_reference_blob (hb_font_get_face (hb_font)); + blob_data = hb_blob_get_data (blob, &blob_length); + + if ((error = FT_New_Memory_Face (ft_library, + (const FT_Byte *) blob_data, + blob_length, + hb_face_get_index (face->face), + &ft_face)) != 0) + { + hb_blob_destroy (blob); + g_warning ("FT_New_Memory_Face failed: %d %s", error, FT_Error_String (error)); + return NULL; + } + + coords = hb_font_get_var_coords_normalized (hb_font, &num_coords); + if (num_coords > 0) + { + FT_Fixed *ft_coords = (FT_Fixed *) g_alloca (num_coords * sizeof (FT_Fixed)); + + for (unsigned int i = 0; i < num_coords; i++) + ft_coords[i] = coords[i] << 2; + + FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); + } + + cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, FT_LOAD_NO_HINTING | FT_LOAD_COLOR); + + if (face->embolden) + cairo_ft_font_face_set_synthesize (cairo_face, CAIRO_FT_SYNTHESIZE_BOLD); + + cairo_font_face_set_user_data (cairo_face, &key, + ft_face, (cairo_destroy_func_t) FT_Done_Face); + cairo_font_face_set_user_data (cairo_face, &key2, + blob, (cairo_destroy_func_t) hb_blob_destroy); + + return cairo_face; +} + +#endif diff --git a/pango2/pangocairo-private.h b/pango2/pangocairo-private.h index d3ad6994..be9fa8cf 100644 --- a/pango2/pangocairo-private.h +++ b/pango2/pangocairo-private.h @@ -66,9 +66,22 @@ GType pango2_cairo_renderer_get_type (void) G_GNUC_CONST; const cairo_font_options_t * pango2_cairo_context_get_merged_font_options (Pango2Context *context); +cairo_font_face_t * +create_cairo_user_font_face (Pango2Font *font); + +#ifdef CAIRO_HAS_FT_FONT +cairo_font_face_t * +create_cairo_ft_font_face (Pango2Font *font); +#endif + +#ifdef HAVE_CORE_TEXT +cairo_font_face_t * +create_cairo_core_text_font_face (Pango2Font *font); +#endif + #ifdef HAVE_DIRECT_WRITE cairo_font_face_t * -pango2_cairo_create_font_face_for_dwrite_pango2_font (Pango2Font *font); +create_cairo_dwrite_font_face (Pango2Font *font); #endif G_END_DECLS diff --git a/pango2/pangocairo-user-font.c b/pango2/pangocairo-user-font.c new file mode 100644 index 00000000..edf49457 --- /dev/null +++ b/pango2/pangocairo-user-font.c @@ -0,0 +1,123 @@ +/* + * pangocairo-user-font.c: User font handling + * + * Copyright (C) 2022 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "pango-features.h" +#include "pangocairo-private.h" +#include "pango-userfont-private.h" +#include "pango-userface-private.h" + +#include <hb-ot.h> + +static cairo_user_data_key_t cairo_user_data; + +static cairo_status_t +render_func (cairo_scaled_font_t *scaled_font, + unsigned long glyph, + cairo_t *cr, + cairo_text_extents_t *extents) +{ + cairo_font_face_t *font_face; + Pango2Font *font; + Pango2UserFace *face; + hb_glyph_extents_t glyph_extents; + hb_position_t h_advance; + hb_position_t v_advance; + gboolean is_color; + + font_face = cairo_scaled_font_get_font_face (scaled_font); + font = cairo_font_face_get_user_data (font_face, &cairo_user_data); + face = PANGO2_USER_FACE (font->face); + + extents->x_bearing = 0; + extents->y_bearing = 0; + extents->width = 0; + extents->height = 0; + extents->x_advance = 0; + extents->y_advance = 0; + + if (!face->glyph_info_func (face, 1024, + (hb_codepoint_t)glyph, + &glyph_extents, + &h_advance, &v_advance, + &is_color, + face->user_data)) + { + return CAIRO_STATUS_USER_FONT_ERROR; + } + + extents->x_bearing = glyph_extents.x_bearing / 1024.; + extents->y_bearing = - glyph_extents.y_bearing / 1024.; + extents->width = glyph_extents.width / 1024.; + extents->height = - glyph_extents.height / 1024.; + extents->x_advance = h_advance / 1024.; + extents->y_advance = v_advance / 1024.; + + if (!face->render_func (face, font->size, + (hb_codepoint_t)glyph, + face->user_data, + "cairo", + cr)) + { + return CAIRO_STATUS_USER_FONT_ERROR; + } + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +init_func (cairo_scaled_font_t *scaled_font, + cairo_t *cr, + cairo_font_extents_t *extents) +{ + cairo_font_face_t *cairo_face; + Pango2Font *font; + Pango2UserFace *face; + hb_font_extents_t font_extents; + + cairo_face = cairo_scaled_font_get_font_face (scaled_font); + font = cairo_font_face_get_user_data (cairo_face, &cairo_user_data); + face = (Pango2UserFace *) pango2_font_get_face (font); + + face->font_info_func (face, + pango2_font_get_size (font), + &font_extents, + face->user_data); + + extents->ascent = font_extents.ascender / (font_extents.ascender + font_extents.descender); + extents->descent = font_extents.descender / (font_extents.ascender + font_extents.descender); + + return CAIRO_STATUS_SUCCESS; +} + +cairo_font_face_t * +create_cairo_user_font_face (Pango2Font *font) +{ + cairo_font_face_t *cairo_face; + + cairo_face = cairo_user_font_face_create (); + cairo_font_face_set_user_data (cairo_face, &cairo_user_data, font, NULL); + cairo_user_font_face_set_init_func (cairo_face, init_func); + cairo_user_font_face_set_render_color_glyph_func (cairo_face, render_func); + + return cairo_face; +} |