diff options
author | Matthias Clasen <mclasen@redhat.com> | 2022-06-21 20:37:42 -0700 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2022-06-22 13:57:26 -0400 |
commit | ceb53e4cb96329e3e77e499df3162b22ec95bd9c (patch) | |
tree | 0a5d34c009bf75e426c5234f5a15cc286df14f12 | |
parent | 9a493245ac5818530526e3ba0853bb415979194a (diff) | |
download | pango-ceb53e4cb96329e3e77e499df3162b22ec95bd9c.tar.gz |
Fix gravities for user fonts
This is enormous fiddling, and should be much simpler.
-rw-r--r-- | pango/pango-hbfont.c | 4 | ||||
-rw-r--r-- | pango/pango-userface.c | 35 | ||||
-rw-r--r-- | pango/pango-userfont.c | 34 | ||||
-rw-r--r-- | pango/pangocairo-font.c | 55 | ||||
-rw-r--r-- | utils/userfont.c | 8 |
5 files changed, 101 insertions, 35 deletions
diff --git a/pango/pango-hbfont.c b/pango/pango-hbfont.c index d9fe88cc..fd523a98 100644 --- a/pango/pango-hbfont.c +++ b/pango/pango-hbfont.c @@ -681,9 +681,9 @@ pango_hb_font_get_glyph_extents (PangoFont *font, m.yx = - face->transform->yx; m.xy = - face->transform->xy; m.yy = face->transform->yy; - } - pango_matrix_transform_rectangle (&m, &r); + pango_matrix_transform_rectangle (&m, &r); + } switch (font->gravity) { diff --git a/pango/pango-userface.c b/pango/pango-userface.c index 0a76cfdf..597674b6 100644 --- a/pango/pango-userface.c +++ b/pango/pango-userface.c @@ -120,6 +120,8 @@ default_shape_func (PangoUserFace *face, gboolean is_color; hb_glyph_extents_t ext; hb_position_t dummy; + hb_font_t *hb_font; + hb_font_extents_t font_extents; n_chars = g_utf8_strlen (text, length); @@ -127,11 +129,15 @@ default_shape_func (PangoUserFace *face, last_cluster = -1; + hb_font = pango_font_get_hb_font (analysis->font); + hb_font_get_h_extents (hb_font, &font_extents); + p = text; for (i = 0; i < n_chars; i++) { gunichar wc; PangoGlyph glyph; + PangoRectangle ink_rect; PangoRectangle logical_rect; wc = g_utf8_get_char (p); @@ -145,16 +151,37 @@ default_shape_func (PangoUserFace *face, glyph = PANGO_GET_UNKNOWN_GLYPH (wc); face->glyph_info_func (face, size, glyph, &ext, &dummy, &dummy, &is_color, face->user_data); - pango_font_get_glyph_extents (analysis->font, glyph, NULL, &logical_rect); + pango_font_get_glyph_extents (analysis->font, glyph, &ink_rect, &logical_rect); glyphs->glyphs[i].glyph = glyph; glyphs->glyphs[i].attr.is_cluster_start = cluster != last_cluster; glyphs->glyphs[i].attr.is_color = is_color; - glyphs->glyphs[i].geometry.x_offset = 0; - glyphs->glyphs[i].geometry.y_offset = 0; - glyphs->glyphs[i].geometry.width = logical_rect.width; + if (analysis->gravity == PANGO_GRAVITY_EAST) + { + glyphs->glyphs[i].geometry.x_offset = font_extents.ascender; + glyphs->glyphs[i].geometry.y_offset = - logical_rect.y - (logical_rect.height - ink_rect.height) / 2; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + else if (analysis->gravity == PANGO_GRAVITY_WEST) + { + glyphs->glyphs[i].geometry.x_offset = font_extents.descender; + glyphs->glyphs[i].geometry.y_offset = logical_rect.y + (logical_rect.height - ink_rect.height) / 2; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + else if (analysis->gravity == PANGO_GRAVITY_SOUTH) + { + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = logical_rect.width; + } + else if (analysis->gravity == PANGO_GRAVITY_NORTH) + { + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.y_offset = 0; + glyphs->glyphs[i].geometry.width = - logical_rect.width; + } glyphs->log_clusters[i] = cluster; last_cluster = cluster; diff --git a/pango/pango-userfont.c b/pango/pango-userfont.c index 5bbd8098..d88babee 100644 --- a/pango/pango-userfont.c +++ b/pango/pango-userfont.c @@ -160,8 +160,6 @@ pango_user_font_get_glyph_extents (PangoFont *font, hb_font_get_h_extents (hb_font, &extents); logical_rect->x = 0; - logical_rect->y = - extents.ascender; - logical_rect->width = h_advance; logical_rect->height = extents.ascender - extents.descender; switch (font->gravity) @@ -266,11 +264,21 @@ glyph_extents_func (hb_font_t *hb_font, void *font_data, hb_position_t h_advance, v_advance; gboolean is_color; - return face->glyph_info_func (face, size, glyph, - extents, - &h_advance, &v_advance, - &is_color, - face->user_data); + face->glyph_info_func (face, size, glyph, + extents, + &h_advance, &v_advance, + &is_color, + face->user_data); + + if (PANGO_GRAVITY_IS_IMPROPER (font->gravity)) + { + extents->x_bearing = - extents->x_bearing; + extents->y_bearing = - extents->y_bearing; + extents->width = - extents->width; + extents->height = - extents->height; + } + + return TRUE; } static hb_bool_t @@ -281,8 +289,17 @@ font_extents_func (hb_font_t *hb_font, void *font_data, PangoFont *font = font_data; PangoUserFace *face = PANGO_USER_FACE (font->face); int size = font->size * font->dpi / 72.; + gboolean ret; + + ret = face->font_info_func (face, size, extents, face->user_data); + + if (PANGO_GRAVITY_IS_IMPROPER (font->gravity)) + { + extents->ascender = - extents->ascender; + extents->descender = - extents->descender; + } - return face->font_info_func (face, size, extents, face->user_data); + return ret; } static hb_font_t * @@ -305,6 +322,7 @@ pango_user_font_create_hb_font (PangoFont *font) hb_font_funcs_set_glyph_h_advance_func (funcs, glyph_h_advance_func, NULL, NULL); hb_font_funcs_set_glyph_extents_func (funcs, glyph_extents_func, NULL, NULL); hb_font_funcs_set_font_h_extents_func (funcs, font_extents_func, NULL, NULL); + hb_font_funcs_set_font_v_extents_func (funcs, font_extents_func, NULL, NULL); hb_font_set_funcs (hb_font, funcs, font, NULL); diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index 432d0166..d23d006a 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -49,12 +49,6 @@ #endif -#define PANGO_CAIRO_FONT_PRIVATE(font) \ - ((PangoCairoFontPrivate *) \ - (font == NULL ? NULL : \ - G_STRUCT_MEMBER_P (font, \ - PANGO_CAIRO_FONT_GET_IFACE(PANGO_CAIRO_FONT(font))->cf_priv_offset))) - static PangoCairoFontPrivate * _pango_font_get_cairo_font_private (PangoFont *font); static cairo_scaled_font_t * _pango_font_get_scaled_font (PangoFont *font); static void _pango_cairo_font_private_initialize (PangoCairoFontPrivate *cf_priv, @@ -120,12 +114,12 @@ render_func (cairo_scaled_font_t *scaled_font, 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; + 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, @@ -139,6 +133,31 @@ render_func (cairo_scaled_font_t *scaled_font, 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; + PangoFont *font; + PangoUserFace *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 = (PangoUserFace *) pango_font_get_face (font); + + face->font_info_func (face, + pango_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 (PangoFont *font) { @@ -146,6 +165,7 @@ create_cairo_font_face_for_user_font (PangoFont *font) 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; @@ -602,7 +622,7 @@ _pango_font_get_cairo_font_private (PangoFont *font) { PangoCairoFontPrivate *cf_priv; - cf_priv = g_object_get_data (G_OBJECT (font), "pango-hb-font-cairo_private"); + cf_priv = g_object_get_data (G_OBJECT (font), "pango-font-cairo_private"); if (!cf_priv) { cairo_font_options_t *font_options; @@ -654,7 +674,7 @@ _pango_font_get_cairo_font_private (PangoFont *font) cairo_font_options_destroy (font_options); - g_object_set_data_full (G_OBJECT (font), "pango-hb-font-cairo_private", + g_object_set_data_full (G_OBJECT (font), "pango-font-cairo_private", cf_priv, free_cairo_font_private); } @@ -687,9 +707,10 @@ _pango_cairo_font_private_initialize (PangoCairoFontPrivate *cf_priv, /* first apply gravity rotation, then font_matrix, such that * vertical italic text comes out "correct". we don't do anything * like baseline adjustment etc though. should be specially - * handled when we support italic correction. */ - cairo_matrix_init_rotate(&gravity_matrix, - pango_gravity_to_rotation (cf_priv->gravity)); + * handled when we support italic correction. + */ + cairo_matrix_init_rotate (&gravity_matrix, + pango_gravity_to_rotation (cf_priv->gravity)); cairo_matrix_multiply (&cf_priv->data->font_matrix, font_matrix, &gravity_matrix); diff --git a/utils/userfont.c b/utils/userfont.c index f5fbf795..a3491e0e 100644 --- a/utils/userfont.c +++ b/utils/userfont.c @@ -91,9 +91,9 @@ glyph_info_cb (PangoUserFace *face, test_scaled_font_glyph_t *glyphs = user_data; extents->x_bearing = 0; - extents->y_bearing = - 0.75 * size; + extents->y_bearing = 0.75 * size; extents->width = glyphs[glyph].width / 4.0 * size; - extents->height = size; + extents->height = - size; *h_advance = *v_advance = glyphs[glyph].width / 4.0 * size; @@ -108,8 +108,8 @@ font_info_cb (PangoUserFace *face, hb_font_extents_t *extents, gpointer user_data) { - extents->ascender = - 0.75 * size; - extents->descender = 0.25 * size; + extents->ascender = 0.75 * size; + extents->descender = - 0.25 * size; extents->line_gap = 0; return TRUE; |