From aacd4840dd432e1004bb385bd966add35b5a10be 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 8d02a52ada..9ce9c9a6ea 100644 --- a/gsk/gl/gskglrenderjob.c +++ b/gsk/gl/gskglrenderjob.c @@ -3153,21 +3153,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 @@ -3193,7 +3207,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 @@ -3206,7 +3221,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; @@ -3274,7 +3289,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, @@ -3297,8 +3312,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);