summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-06-21 20:37:42 -0700
committerMatthias Clasen <mclasen@redhat.com>2022-06-22 13:57:26 -0400
commitceb53e4cb96329e3e77e499df3162b22ec95bd9c (patch)
tree0a5d34c009bf75e426c5234f5a15cc286df14f12
parent9a493245ac5818530526e3ba0853bb415979194a (diff)
downloadpango-ceb53e4cb96329e3e77e499df3162b22ec95bd9c.tar.gz
Fix gravities for user fonts
This is enormous fiddling, and should be much simpler.
-rw-r--r--pango/pango-hbfont.c4
-rw-r--r--pango/pango-userface.c35
-rw-r--r--pango/pango-userfont.c34
-rw-r--r--pango/pangocairo-font.c55
-rw-r--r--utils/userfont.c8
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;