diff options
author | Matthias Clasen <mclasen@redhat.com> | 2022-01-27 00:46:15 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2022-01-28 18:43:39 -0500 |
commit | 73effe2d038f05fb9b107eb9189068acb3e68415 (patch) | |
tree | a9b76ca845ace8ea25442496f7352e0ca61c3950 /pango/pangocairo-font.c | |
parent | 71a597754cd977186a6c9541366a3c893c6ddfc2 (diff) | |
download | pango-73effe2d038f05fb9b107eb9189068acb3e68415.tar.gz |
Introduce user fonts
Add a way to create callback-based faces
and fonts. The cairo implementation of this
uses cairos user fonts.
New APIs: PangoUserFace and PangoUserFont
Diffstat (limited to 'pango/pangocairo-font.c')
-rw-r--r-- | pango/pangocairo-font.c | 115 |
1 files changed, 99 insertions, 16 deletions
diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index e265e540..ca503666 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -30,6 +30,8 @@ #include "pango-impl-utils.h" #include "pango-hbfont-private.h" #include "pango-hbface-private.h" +#include "pango-userfont-private.h" +#include "pango-userface-private.h" #include "pangocairo-fc.h" #pragma GCC diagnostic push @@ -73,6 +75,76 @@ _pango_cairo_font_private_scaled_font_data_destroy (PangoCairoFontPrivateScaledF static FT_Library ft_library; +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; + PangoUserFont *font; + 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); + + extents->x_bearing = 0; + extents->y_bearing = 0; + extents->width = 0; + extents->height = 0; + extents->x_advance = 0; + extents->y_advance = 0; + + if (!font->face->glyph_info_func (font->face, 1024, + (hb_codepoint_t)glyph, + &glyph_extents, + &h_advance, &v_advance, + &is_color, + font->face->user_data)) + { + return CAIRO_STATUS_USER_FONT_ERROR; + } + + extents->x_bearing = glyph_extents.x_bearing / (double) 1024; + extents->y_bearing = glyph_extents.y_bearing / (double) 1024; + extents->width = glyph_extents.width / (double) 1024; + extents->height = glyph_extents.height / (double) 1024; + extents->x_advance = h_advance / (double) 1024; + extents->y_advance = v_advance / (double) 1024; + + if (!font->face->render_func (font->face, font->size, + (hb_codepoint_t)glyph, + font->face->user_data, + "cairo", + cr)) + { + return CAIRO_STATUS_USER_FONT_ERROR; + } + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_font_face_t * +create_font_face_for_user_font (PangoUserFont *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); +#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC + cairo_user_font_face_set_render_color_glyph_func (cairo_face, render_func); +#else + cairo_user_font_face_set_render_glyph_func (cairo_face, render_func); +#endif + + return cairo_face; +} + static cairo_font_face_t * create_font_face_for_hb_font (PangoHbFont *font) { @@ -144,8 +216,10 @@ _pango_cairo_font_private_get_scaled_font (PangoCairoFontPrivate *cf_priv) if (PANGO_IS_CAIRO_FONT (cf_priv->cfont)) font_face = (* PANGO_CAIRO_FONT_GET_IFACE (cf_priv->cfont)->create_font_face) (cf_priv->cfont); - else + else if (PANGO_IS_HB_FONT (cf_priv->cfont)) font_face = create_font_face_for_hb_font (PANGO_HB_FONT (cf_priv->cfont)); + else if (PANGO_IS_USER_FONT (cf_priv->cfont)) + font_face = create_font_face_for_user_font (PANGO_USER_FONT (cf_priv->cfont)); if (G_UNLIKELY (font_face == NULL)) goto done; @@ -688,26 +762,35 @@ _pango_font_get_cairo_font_private (PangoFont *font) cf_priv = g_object_get_data (G_OBJECT (font), "pango-hb-font-cairo_private"); if (!cf_priv) { - PangoHbFont *hbfont = PANGO_HB_FONT (font); + CommonFont *cf = (CommonFont *)font; cairo_font_options_t *font_options; cairo_matrix_t font_matrix; + double x_scale, y_scale; int size; - if (hbfont->face->matrix) - cairo_matrix_init (&font_matrix, - hbfont->face->matrix->xx, - - hbfont->face->matrix->yx, - - hbfont->face->matrix->xy, - hbfont->face->matrix->yy, - 0., 0.); - else - cairo_matrix_init (&font_matrix, 1., 0., 0., 1., 0., 0.); + cairo_matrix_init (&font_matrix, 1., 0., 0., 1., 0., 0.); + x_scale = y_scale = 1; + + if (PANGO_IS_HB_FONT (font)) + { + PangoHbFont *hbfont = PANGO_HB_FONT (font); + if (hbfont->face->matrix) + cairo_matrix_init (&font_matrix, + hbfont->face->matrix->xx, + - hbfont->face->matrix->yx, + - hbfont->face->matrix->xy, + hbfont->face->matrix->yy, + 0., 0.); + + x_scale = hbfont->face->x_scale; + y_scale = hbfont->face->y_scale; + } - size = hbfont->size * hbfont->dpi / 72.; + size = cf->size * cf->dpi / 72.; cairo_matrix_scale (&font_matrix, - hbfont->face->x_scale * size / (double)PANGO_SCALE, - hbfont->face->y_scale * size / (double)PANGO_SCALE); + x_scale * size / (double)PANGO_SCALE, + y_scale * size / (double)PANGO_SCALE); font_options = cairo_font_options_create (); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); @@ -716,9 +799,9 @@ _pango_font_get_cairo_font_private (PangoFont *font) cf_priv = g_new0 (PangoCairoFontPrivate, 1); _pango_cairo_font_private_initialize (cf_priv, (PangoCairoFont *)font, - hbfont->gravity, + cf->gravity, font_options, - &hbfont->matrix, + &cf->matrix, &font_matrix); cairo_font_options_destroy (font_options); |