From de08441d4d60adc28ee358afe9dab024c25ac856 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 28a3334292..35d4416ff0 100644 --- a/gsk/gl/gskglrenderjob.c +++ b/gsk/gl/gskglrenderjob.c @@ -3158,21 +3158,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 @@ -3198,7 +3212,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 @@ -3211,7 +3226,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; @@ -3279,7 +3294,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, @@ -3302,8 +3317,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);