Fix recent Cairo xsettings changes

* lisp/dynamic-setting.el (font-setting-change-default-font):
Instead of setting the font frame parameter, just clear the font
and face cache and redraw the display.  This will re-open all
fonts as well.
* src/ftcrfont.c (ftcrfont_get_default_font_options): New
function.
* src/ftfont.h: Export.
* src/xsettings.c (apply_xft_settings): Call that function to
obtain the default font settings on Cairo.  (bug#58912,
bug#59283, bug#59271)
scratch/comp-static-data
Po Lu 2022-11-15 19:07:44 +08:00
parent 0ac626f1d4
commit 833e60ae1a
4 changed files with 52 additions and 14 deletions

View File

@ -51,19 +51,12 @@ the current form for the frame (i.e. hinting or somesuch changed)."
;; Set the font on all current and future frames, as though
;; the `default' face had been "set for this session":
(set-frame-font new-font nil frame-list)
;; Just redraw the existing fonts on all frames:
(dolist (f frame-list)
(let ((frame-font
(or (font-get (face-attribute 'default :font f 'default)
:user-spec)
(frame-parameter f 'font-parameter))))
(when frame-font
(set-frame-parameter f 'font-parameter frame-font)
(set-face-attribute 'default f
:width 'normal
:weight 'normal
:slant 'normal
:font frame-font))))))))
;; Just redraw the existing fonts on all frames, by clearing
;; the font and face caches. This will cause all fonts to be
;; recreated.
(clear-font-cache)
(clear-face-cache t)
(redraw-display)))))
(defun dynamic-setting-handle-config-changed-event (event)
"Handle config-changed-event on the display in EVENT.

View File

@ -737,7 +737,7 @@ struct font_driver const ftcrfont_driver =
.filter_properties = ftfont_filter_properties,
.combining_capability = ftfont_combining_capability,
#ifdef HAVE_PGTK
.cached_font_ok = ftcrfont_cached_font_ok
.cached_font_ok = ftcrfont_cached_font_ok,
#endif
};
#ifdef HAVE_HARFBUZZ
@ -755,6 +755,42 @@ syms_of_ftcrfont (void)
pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper);
}
#ifdef HAVE_X_WINDOWS
/* Place the default font options used by Cairo on the given display
in OPTIONS. */
void
ftcrfont_get_default_font_options (struct x_display_info *dpyinfo,
cairo_font_options_t *options)
{
Pixmap drawable;
cairo_surface_t *surface;
/* Cairo doesn't allow fetching the default font options for a
display, so the only option is to create a drawable, and an Xlib
surface for that drawable, and to get the font options from there
instead. */
drawable = XCreatePixmap (dpyinfo->display, dpyinfo->root_window,
1, 1, dpyinfo->n_planes);
surface = cairo_xlib_surface_create (dpyinfo->display, drawable,
dpyinfo->visual, 1, 1);
if (!surface)
{
XFreePixmap (dpyinfo->display, drawable);
return;
}
cairo_surface_get_font_options (surface, options);
XFreePixmap (dpyinfo->display, drawable);
cairo_surface_destroy (surface);
return;
}
#endif
static void
syms_of_ftcrfont_for_pdumper (void)
{

View File

@ -84,4 +84,11 @@ struct font_info
#endif
};
#if defined USE_CAIRO && defined HAVE_X_WINDOWS
extern void ftcrfont_get_default_font_options (struct x_display_info *,
cairo_font_options_t *);
#endif /* USE_CAIRO && HAVE_X_WINDOWS */
#endif /* EMACS_FTFONT_H */

View File

@ -56,6 +56,7 @@ typedef unsigned int CARD32;
#ifdef USE_CAIRO
#include <fontconfig/fontconfig.h>
#include "ftfont.h"
#elif defined HAVE_XFT
#include <X11/Xft/Xft.h>
#endif
@ -826,6 +827,7 @@ apply_xft_settings (Display_Info *dpyinfo,
#else
FcConfigSubstitute (NULL, pat, FcMatchPattern);
options = cairo_font_options_create ();
ftcrfont_get_default_font_options (dpyinfo, options);
cairo_ft_font_options_substitute (options, pat);
cairo_font_options_destroy (options);
FcDefaultSubstitute (pat);