emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 833e60ae1a 1/2: Fix recent Cairo xsettings changes


From: Po Lu
Subject: master 833e60ae1a 1/2: Fix recent Cairo xsettings changes
Date: Tue, 15 Nov 2022 06:48:51 -0500 (EST)

branch: master
commit 833e60ae1a5dd4301eb556460285414f4fea9fec
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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)
---
 lisp/dynamic-setting.el | 19 ++++++-------------
 src/ftcrfont.c          | 38 +++++++++++++++++++++++++++++++++++++-
 src/ftfont.h            |  7 +++++++
 src/xsettings.c         |  2 ++
 4 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/lisp/dynamic-setting.el b/lisp/dynamic-setting.el
index 8ac9a1e9e6..ff7bf182d1 100644
--- a/lisp/dynamic-setting.el
+++ b/lisp/dynamic-setting.el
@@ -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.
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index dc765e5aee..ede8f1323c 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -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)
 {
diff --git a/src/ftfont.h b/src/ftfont.h
index cfab8d3154..ee56e2d760 100644
--- a/src/ftfont.h
+++ b/src/ftfont.h
@@ -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 */
diff --git a/src/xsettings.c b/src/xsettings.c
index 15e7ff5499..1a9f1a8d5a 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]