From b66ec0c25751f432745448333d95727391092f2a Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Tue, 6 May 2025 22:17:45 +0100 Subject: [PATCH] GTK/x11font/Cairo: use XDrawString16 instead of XDrawImageString16 On my test case, this reduces Xwayland's CPU usage by 5-10%, though curiously in glamor_block_handler rather than the drawing routine itself. XDrawImageString16 isn't as helpful as it might be for two reasons. First, "M" type fonts (e.g. Courier Oblique) can extend beyond the rectangle erased by XDrawImageString16, and PuTTY tries to support such fonts. And second, we really want to blank the pixmap after drawing rather than before, because otherwise we have to muck around clipping the mask operation. So avoinding the XFillRectangle calls is difficult, at which point we may as well use XDrawString16. --- unix/unifont.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/unix/unifont.c b/unix/unifont.c index 9b7df28c..497fcfc6 100644 --- a/unix/unifont.c +++ b/unix/unifont.c @@ -686,16 +686,10 @@ static void x11font_cairo_ensure_pixmap( xfi->pattern = cairo_pattern_create_for_surface(xfi->surface); /* We really don't want bilinear interpolation of bitmap fonts. */ cairo_pattern_set_filter(xfi->pattern, CAIRO_FILTER_NEAREST); - XGCValues gcvals = { - .function = GXclear, - .foreground = 0xffffffff, - .background = 0, - .font = xfi->xfs->fid, - }; - xfi->gc = XCreateGC(disp, newpixmap, - GCFunction | GCForeground | GCBackground | GCFont, - &gcvals); + XGCValues gcvals = { .font = xfi->xfs->fid }; + xfi->gc = XCreateGC(disp, newpixmap, GCFont, &gcvals); } + XSetFunction(disp, xfi->gc, GXclear); XFillRectangle(disp, newpixmap, xfi->gc, 0, 0, width, height); xfi->pixmap = newpixmap; xfi->pixwidth = width; @@ -715,7 +709,8 @@ static void x11font_cairo_draw( pixheight = bounds.ascent + bounds.descent; if (pixwidth > 0 && pixheight > 0) { x11font_cairo_ensure_pixmap(ctx, xfi, disp, pixwidth, pixheight); - XDrawImageString16(disp, xfi->pixmap, xfi->gc, + XSetFunction(disp, xfi->gc, GXset); + XDrawString16(disp, xfi->pixmap, xfi->gc, -bounds.lbearing, bounds.ascent, string+start, length); cairo_surface_mark_dirty(xfi->surface); @@ -725,6 +720,7 @@ static void x11font_cairo_draw( cairo_pattern_set_matrix(xfi->pattern, &xfrm); cairo_mask(ctx->u.cairo.cr, xfi->pattern); /* Clear the part of the pixmap that we used. */ + XSetFunction(disp, xfi->gc, GXclear); XFillRectangle(disp, xfi->pixmap, xfi->gc, 0, 0, pixwidth, pixheight); } }