From 429478f914201098ae13cd79e29dc1dc8ecd0aca Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Wed, 23 Apr 2025 19:52:54 +0100 Subject: [PATCH] GTK: less-fuzzy bitmap font scaling with Cairo This commit fixes a problem that Simon observed when using an X bitmap font with Cairo and making a line double-width or double-size. When using Cairo, PuTTY implements double-width and double-size by just asking Cairo to scale all its drawing operations. This works fine with outline fonts, but when using a bitmap font the results are a bit fuzzy. This appears to be because Cairo's default is to use bilinear interpolation when scaling an image, which is fine for photos but not so good for fonts. In this commit, I decompose PuTTY's cairo_mask_surface() call into its component parts so that I can set the mask pattern's filter to CAIRO_FILTER_NEAREST before using it. That solves the problem, but it suggests that maybe we should be caching the pattern rather then the surface. --- unix/unifont.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/unix/unifont.c b/unix/unifont.c index 5d9eceef..04a65ccf 100644 --- a/unix/unifont.c +++ b/unix/unifont.c @@ -716,9 +716,16 @@ static void x11font_cairo_draw_glyph(unifont_drawctx *ctx, int glyphindex) { if (xfi->glyphcache[glyphindex].surface) { - cairo_mask_surface(ctx->u.cairo.cr, - xfi->glyphcache[glyphindex].surface, - x - xfi->pixoriginx, y - xfi->pixoriginy); + cairo_pattern_t *glyph_pattern = cairo_pattern_create_for_surface( + xfi->glyphcache[glyphindex].surface); + cairo_matrix_t xfrm; + /* We really don't want bilinear interpolation of bitmap fonts. */ + cairo_pattern_set_filter(glyph_pattern, CAIRO_FILTER_NEAREST); + cairo_matrix_init_translate(&xfrm, -(x - xfi->pixoriginx), + -(y - xfi->pixoriginy)); + cairo_pattern_set_matrix(glyph_pattern, &xfrm); + cairo_mask(ctx->u.cairo.cr, glyph_pattern); + cairo_pattern_destroy(glyph_pattern); } }