From 4ca8911d2a732b0e254fd8763279aeba07caf325 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 4 Apr 2022 21:52:04 -0400 Subject: [PATCH] glyphy: Implement synthetic italic Use the font matrix found in the FcPattern to transform the quads we use to render the glyphs. This makes Cantarell Italic come out just like it does with freetype. --- gsk/gl/gskglrenderjob.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/gsk/gl/gskglrenderjob.c b/gsk/gl/gskglrenderjob.c index 885f0aa8fc..fc1525537f 100644 --- a/gsk/gl/gskglrenderjob.c +++ b/gsk/gl/gskglrenderjob.c @@ -3159,21 +3159,35 @@ add_encoded_glyph (GskGLDrawVertex *vertices, *vertices = (GskGLDrawVertex) { .position = { eg->x, eg->y}, .uv = { eg->g16hi, eg->g16lo}, .color = { c[0], c[1], c[2], c[3] } }; } -static gboolean -font_is_synthetic_bold (PangoFont *font) +static void +get_synthetic_font_params (PangoFont *font, + gboolean *embolden, + PangoMatrix *matrix) { + *embolden = FALSE; + *matrix = (PangoMatrix) PANGO_MATRIX_INIT; + #ifdef HAVE_PANGOFT if (PANGO_IS_FC_FONT (font)) { FcPattern *pattern = pango_fc_font_get_pattern (PANGO_FC_FONT (font)); - gboolean ret; + FcBool b; + FcMatrix mat; + FcMatrix *m; - if (FcPatternGetBool (pattern, FC_EMBOLDEN, 0, &ret) == FcResultMatch) - return ret; + if (FcPatternGetBool (pattern, FC_EMBOLDEN, 0, &b) == FcResultMatch) + *embolden = b; + + FcMatrixInit (&mat); + for (int i = 0; FcPatternGetMatrix (pattern, FC_MATRIX, i, &m) == FcResultMatch; i++) + FcMatrixMultiply (&mat, &mat, m); + + matrix->xx = mat.xx; + matrix->xy = mat.xy; + matrix->yx = mat.yx; + matrix->yy = mat.yy; } #endif - - return FALSE; } static inline void @@ -3199,7 +3213,8 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job, guint i; int x_position = 0; float font_scale; - gboolean synthetic_bold; + gboolean embolden; + PangoMatrix matrix = PANGO_MATRIX_INIT; #define GRID_SIZE 20 @@ -3212,7 +3227,7 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job, return; font = (PangoFont *)gsk_text_node_get_font (node); - synthetic_bold = font_is_synthetic_bold (font); + get_synthetic_font_params (font, &embolden, &matrix); glyphs = gsk_text_node_get_glyphs (node, NULL); library = job->driver->glyphy_library; @@ -3280,7 +3295,7 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job, /* 0.0208 is the value used by freetype for synthetic emboldening */ gsk_gl_program_set_uniform1f (job->current_program, UNIFORM_GLYPHY_BOLDNESS, 0, - synthetic_bold ? 0.0208 * GRID_SIZE : 0.0); + embolden ? 0.0208 * GRID_SIZE : 0.0); #if 0 gsk_gl_program_set_uniform1f (job->current_program, @@ -3303,8 +3318,10 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob *job, EncodedGlyph encoded[4]; #define ENCODE_CORNER(_cx, _cy) \ G_STMT_START { \ - float _vx = x + cx + font_scale * ((1-_cx) * glyph->extents.min_x + _cx * glyph->extents.max_x); \ - float _vy = y + cy - font_scale * ((1-_cy) * glyph->extents.min_y + _cy * glyph->extents.max_y); \ + float _dx = _cx * (glyph->extents.max_x - glyph->extents.min_x); \ + float _dy = _cy * (glyph->extents.max_y - glyph->extents.min_y); \ + float _vx = x + cx + font_scale * (glyph->extents.min_x + matrix.xx * _dx + matrix.xy * _dy); \ + float _vy = y + cy - font_scale * (glyph->extents.min_y + matrix.yx * _dx + matrix.yy * _dy); \ encoded_glyph_init (&encoded[_cx * 2 + _cy], _vx, _vy, _cx, _cy, glyph); \ } G_STMT_END ENCODE_CORNER (0, 0);