unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Pieter van Prooijen <pieter.van.prooijen@teloden.nl>
To: Po Lu <luangruo@yahoo.com>
Cc: 54564@debbugs.gnu.org
Subject: bug#54564: 29.0.50; [PATCH] Use gsettings font rendering entries for pgtk builds
Date: Wed, 30 Mar 2022 10:01:49 +0200	[thread overview]
Message-ID: <88d833f72df4f4cbb5769f1a75057d3f957a812c.camel@teloden.nl> (raw)
In-Reply-To: <87o81s2osr.fsf@yahoo.com>

[-- Attachment #1: Type: text/plain, Size: 1926 bytes --]

Hello All,

Here's the second version of my patch to use the gsettings for font
rendering:

- Every change is scoped to the pgtk build. 
- Changing settings redisplay dynamically by hooking into the
cached_font_ok field of the cairo font driver and storing a font-render
event upon a gsettings change.
- Formatting is now in line with the gnu c style.
- Commit message was split into multiple parts per changed file.

When playing around with the font settings, I noticed that cairo/pgtk
doesn't seem to use the subpixel antialias (e.g. cleartype style)
rendering setting, even though that option is set. I'll investigate
further, it doesn't look like a regression due to this patch, but
existing behavior.

Kind Regards,

Pieter

On Sun, 2022-03-27 at 08:59 +0800, Po Lu wrote:
> Pieter van Prooijen <pieter.van.prooijen@teloden.nl> writes:
> 
> > Hello All, 
> > 
> > Thanks for looking into my patch!, I'll fix the formatting issues
> > you
> > mentioned and narrow the changes to the HAVE_PGTK define in the
> > various
> > source files, so it's is only present for that build.
> 
> Indeed, and thanks for working on Emacs as well.
> 
> > Not sure about having this functionality controlled by a user
> > defined
> > variable (as is possible with using the system font), as far as I
> > know,
> > the current cairo X backend doesn't have this as well, it will
> > always
> > use the gsettings/xrdb defined parameters for rendering.
> 
> We don't support using the PGTK build on X Windows anyway, so that's
> not
> a real problem.  Besides, manually specified font options will
> override
> whatever Cairo thinks is best.
> 
> > Regarding the re-rendering upon a config change, I'll have a look
> > at
> > the options mentioned (clearing the font cache and marking each
> > frame
> > for redisplay), but that will probably be a separate patch.
> 
> I think it would be best to have that feature as part of this change.


[-- Attachment #2: 0001-Use-gsettings-font-rendering-entries-for-pgtk-builds.patch --]
[-- Type: text/x-patch, Size: 10122 bytes --]

From bc0aa23777f2aae42b29597a04c0d14007063149 Mon Sep 17 00:00:00 2001
From: Pieter van Prooijen <pieter.van.prooijen@teloden.nl>
Date: Tue, 29 Mar 2022 21:21:52 +0200
Subject: [PATCH] Use gsettings font rendering entries for pgtk builds

If present, apply the gsettings font hinting and antialiasing entries
when creating a font in cairo.  Do this at initialization and when the
entries change, re-rendering the frames.

* src/ftcrfont.c (ftcrfont_open): Use the font_options derived from gsettings
  when opening a font.
* src/ftcrfont.c: (ftcrfont_cached_font_ok): Report a cached font as invalid
  if its font options differ from the current gsettings ones.
* src/xsettings.c, src/xsettings.h (xsettings_get_font_options): Retrieve the
  current gsettings derived cairo font_options.
* src/xsettings.c (apply_gsettings_font_hinting): Convert the gsettings hint
  setting to the font_options struct.
* src/xsettings.c (apply_gsettings_font_antialias): Convert the gsettings
  antialias setting to the font_options struct.
* src/xsettings.c (apply_gsettings_font_rgba_order): Convert the gsettings
  rgba order setting to the font_options struct.
* src/xsettings.c (init_gsettings): Invoke the apply functions when
  initializing from gsettings.
* src/xsettings.c (something_changed_gsettingsCB): Invoke the apply functions
  if the relevant gsettings changed.
* src/xsettings.c (store_font_options_changed): Store an event to re-render
  the fonts.
---
 src/ftcrfont.c  |  32 ++++++++++
 src/xsettings.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/xsettings.h |   4 ++
 3 files changed, 187 insertions(+)

diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index 98a28af5f2..103da93d51 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -37,6 +37,9 @@
 #include "font.h"
 #include "ftfont.h"
 #include "pdumper.h"
+#ifdef HAVE_PGTK
+#include "xsettings.h"
+#endif
 
 #ifdef USE_BE_CAIRO
 #define RED_FROM_ULONG(color)	(((color) >> 16) & 0xff)
@@ -168,7 +171,12 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
   cairo_matrix_t font_matrix, ctm;
   cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size);
   cairo_matrix_init_identity (&ctm);
+
+#ifdef HAVE_PGTK
+  cairo_font_options_t *options = xsettings_get_font_options ();
+#else
   cairo_font_options_t *options = cairo_font_options_create ();
+#endif
 #ifdef USE_BE_CAIRO
   if (be_use_subpixel_antialiasing ())
     cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_SUBPIXEL);
@@ -624,6 +632,27 @@ ftcrfont_draw (struct glyph_string *s,
   return len;
 }
 
+#ifdef HAVE_PGTK
+/* Determine if the cached font should be re-opened, by comparing
+   its font_options with the ones derived from gsettings.  */
+static bool
+ftcrfont_cached_font_ok (struct frame *f, Lisp_Object font_object,
+			 Lisp_Object entity)
+{
+  struct font_info *info = (struct font_info *) XFONT_OBJECT (font_object);
+
+  cairo_font_options_t *options = cairo_font_options_create ();
+  cairo_scaled_font_get_font_options (info->cr_scaled_font, options);
+  cairo_font_options_t *gsettings_options = xsettings_get_font_options ();
+
+  bool equal = cairo_font_options_equal (options, gsettings_options);
+  cairo_font_options_destroy (options);
+  cairo_font_options_destroy (gsettings_options);
+
+  return equal;
+}
+#endif
+
 #ifdef HAVE_HARFBUZZ
 
 static Lisp_Object
@@ -694,6 +723,9 @@ ftcrhbfont_end_hb_font (struct font *font, hb_font_t *hb_font)
 #endif
   .filter_properties = ftfont_filter_properties,
   .combining_capability = ftfont_combining_capability,
+#ifdef HAVE_PGTK
+  .cached_font_ok = ftcrfont_cached_font_ok
+#endif
   };
 #ifdef HAVE_HARFBUZZ
 struct font_driver ftcrhbfont_driver;
diff --git a/src/xsettings.c b/src/xsettings.c
index 71d02e6152..2538ab51b3 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -215,11 +215,118 @@ #define GSETTINGS_MONO_FONT  "monospace-font-name"
 #define GSETTINGS_FONT_NAME  "font-name"
 #endif
 
+#ifdef HAVE_PGTK
+#define GSETTINGS_FONT_ANTIALIASING  "font-antialiasing"
+#define GSETTINGS_FONT_RGBA_ORDER    "font-rgba-order"
+#define GSETTINGS_FONT_HINTING       "font-hinting"
+#endif
 
 /* The single GSettings instance, or NULL if not connected to GSettings.  */
 
 static GSettings *gsettings_client;
 
+#ifdef HAVE_PGTK
+
+/* The cairo font_options as obtained using gsettings.  */
+static cairo_font_options_t *font_options;
+
+/* Store an event for re-rendering of the fonts.  */
+static void
+store_font_options_changed (void)
+{
+  if (dpyinfo_valid (first_dpyinfo))
+    {
+      store_config_changed_event (Qfont_render,
+                                  XCAR (first_dpyinfo->name_list_element));
+    }
+}
+
+/* Apply changes in the hinting system setting.  */
+static void
+apply_gsettings_font_hinting (GSettings *settings)
+{
+  GVariant *val = g_settings_get_value (settings, GSETTINGS_FONT_HINTING);
+  if (val)
+    {
+      g_variant_ref_sink (val);
+      if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
+	{
+	  const char *hinting = g_variant_get_string (val, NULL);
+
+	  if (!strcmp (hinting, "full"))
+	    cairo_font_options_set_hint_style (font_options,
+					       CAIRO_HINT_STYLE_FULL);
+	  else if (!strcmp (hinting, "medium"))
+	    cairo_font_options_set_hint_style (font_options,
+					       CAIRO_HINT_STYLE_MEDIUM);
+	  else if (!strcmp (hinting, "slight"))
+	    cairo_font_options_set_hint_style (font_options,
+					       CAIRO_HINT_STYLE_SLIGHT);
+	  else if (!strcmp (hinting, "none"))
+	    cairo_font_options_set_hint_style (font_options,
+					       CAIRO_HINT_STYLE_NONE);
+	}
+      g_variant_unref (val);
+    }
+}
+
+/* Apply changes in the antialiasing system setting.  */
+static void
+apply_gsettings_font_antialias (GSettings *settings)
+{
+  GVariant *val = g_settings_get_value (settings, GSETTINGS_FONT_ANTIALIASING);
+  if (val)
+    {
+      g_variant_ref_sink (val);
+      if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
+	{
+	  const char *antialias = g_variant_get_string (val, NULL);
+
+	  if (!strcmp (antialias, "none"))
+	    cairo_font_options_set_antialias (font_options,
+					      CAIRO_ANTIALIAS_NONE);
+	  else if (!strcmp (antialias, "grayscale"))
+	    cairo_font_options_set_antialias (font_options,
+					      CAIRO_ANTIALIAS_GRAY);
+	  else if (!strcmp (antialias, "rgba"))
+	    cairo_font_options_set_antialias (font_options,
+					      CAIRO_ANTIALIAS_SUBPIXEL);
+	}
+      g_variant_unref (val);
+    }
+}
+
+/* Apply the settings for the rgb element ordering.  */
+static void
+apply_gsettings_font_rgba_order (GSettings *settings)
+{
+  GVariant *val = g_settings_get_value (settings,
+					GSETTINGS_FONT_RGBA_ORDER);
+  if (val)
+    {
+      g_variant_ref_sink (val);
+      if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
+	{
+	  const char *rgba_order = g_variant_get_string (val, NULL);
+
+	  if (!strcmp (rgba_order, "rgb"))
+	    cairo_font_options_set_subpixel_order (font_options,
+						   CAIRO_SUBPIXEL_ORDER_RGB);
+	  else if (!strcmp (rgba_order, "bgr"))
+	    cairo_font_options_set_subpixel_order (font_options,
+						   CAIRO_SUBPIXEL_ORDER_BGR);
+	  else if (!strcmp (rgba_order, "vrgb"))
+	    cairo_font_options_set_subpixel_order (font_options,
+						   CAIRO_SUBPIXEL_ORDER_VRGB);
+	  else if (!strcmp (rgba_order, "vbgr"))
+	    cairo_font_options_set_subpixel_order (font_options,
+						   CAIRO_SUBPIXEL_ORDER_VBGR);
+	}
+      g_variant_unref (val);
+    }
+}
+#endif /* HAVE_PGTK */
+
 /* Callback called when something changed in GSettings.  */
 
 static void
@@ -273,6 +380,23 @@ something_changed_gsettingsCB (GSettings *settings,
         }
     }
 #endif /* USE_CAIRO || HAVE_XFT */
+#ifdef HAVE_PGTK
+  else if (strcmp (key, GSETTINGS_FONT_ANTIALIASING) == 0)
+    {
+      apply_gsettings_font_antialias (settings);
+      store_font_options_changed ();
+    }
+  else if (strcmp (key, GSETTINGS_FONT_HINTING) == 0)
+    {
+      apply_gsettings_font_hinting (settings);
+      store_font_options_changed ();
+    }
+  else if (strcmp (key, GSETTINGS_FONT_RGBA_ORDER) == 0)
+    {
+      apply_gsettings_font_rgba_order (settings);
+      store_font_options_changed ();
+    }
+#endif /* HAVE_PGTK */
 }
 
 #endif /* HAVE_GSETTINGS */
@@ -900,6 +1024,18 @@ init_gsettings (void)
         dupstring (&current_font, g_variant_get_string (val, NULL));
       g_variant_unref (val);
     }
+
+  /* Only use the gsettings font entries for non-X11 cairo backends
+     (which is the recommended way of running pgtk builds).
+     For the X11 backend cairo will apply these entries itself,
+     reading them from xrdb.  */
+#ifdef HAVE_PGTK
+  font_options = cairo_font_options_create ();
+  apply_gsettings_font_antialias (gsettings_client);
+  apply_gsettings_font_hinting (gsettings_client);
+  apply_gsettings_font_rgba_order (gsettings_client);
+#endif /* HAVE_PGTK */
+
 #endif /* USE_CAIRO || HAVE_XFT */
 
 #endif /* HAVE_GSETTINGS */
@@ -1021,6 +1157,17 @@ xsettings_get_system_normal_font (void)
 }
 #endif
 
+#ifdef HAVE_PGTK
+/* Return the cairo font options, updated from the gsettings font
+   config entries. The caller should call cairo_font_options_destroy
+   on the result.  */
+cairo_font_options_t *
+xsettings_get_font_options (void)
+{
+  return cairo_font_options_copy (font_options);
+}
+#endif
+
 DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font,
        Sfont_get_system_normal_font,
        0, 0, 0,
@@ -1073,6 +1220,10 @@ syms_of_xsettings (void)
   gconf_client = NULL;
   PDUMPER_IGNORE (gconf_client);
 #endif
+#ifdef HAVE_PGTK
+  font_options = NULL;
+  PDUMPER_IGNORE (font_options);
+#endif
 
   DEFSYM (Qmonospace_font_name, "monospace-font-name");
   DEFSYM (Qfont_name, "font-name");
diff --git a/src/xsettings.h b/src/xsettings.h
index ccaa36489d..c7fe861c40 100644
--- a/src/xsettings.h
+++ b/src/xsettings.h
@@ -41,5 +41,9 @@ #define XSETTINGS_H
 extern const char *xsettings_get_system_normal_font (void);
 #endif
 
+#ifdef HAVE_PGTK
+#include <cairo.h>
+extern cairo_font_options_t *xsettings_get_font_options (void);
+#endif
 
 #endif /* XSETTINGS_H */
-- 
2.32.0


  reply	other threads:[~2022-03-30  8:01 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-25 11:23 bug#54564: 29.0.50; [PATCH] Use gsettings font rendering entries for pgtk builds Pieter van Prooijen
2022-03-26  1:16 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-03-26  6:01   ` Eli Zaretskii
2022-03-26  6:07     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-03-26  6:20       ` Eli Zaretskii
2022-03-26  6:44         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-03-26  7:45           ` Eli Zaretskii
2022-03-26  8:11             ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-03-26  9:36           ` Eli Zaretskii
2022-03-26 15:48           ` Pieter van Prooijen
2022-03-27  0:59             ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-03-30  8:01               ` Pieter van Prooijen [this message]
2022-03-30  8:59                 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-03-31 17:30                   ` Pieter van Prooijen
2022-04-01  2:00                     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-04-07 19:24                       ` Pieter van Prooijen
2022-04-07 23:38                         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-04-08 18:44                           ` Pieter van Prooijen
2022-04-09  0:35                             ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-05-13 11:38                             ` Pieter van Prooijen
2022-05-13 11:55                               ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-05-13 11:57                                 ` Lars Ingebrigtsen
2022-05-13 12:12                                 ` Eli Zaretskii
2022-05-13 12:51                               ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=88d833f72df4f4cbb5769f1a75057d3f957a812c.camel@teloden.nl \
    --to=pieter.van.prooijen@teloden.nl \
    --cc=54564@debbugs.gnu.org \
    --cc=luangruo@yahoo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).