From 6fe888e7c14ef5aad124c0d68fcd071cd5b65e81 Mon Sep 17 00:00:00 2001 From: Pieter van Prooijen Date: Fri, 25 Mar 2022 11:47:39 +0100 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. * src/xsettings.c, src/xsettings.h: read and apply gsetting entries. * src/ftcrfont.c: use the font_options from xsettings.c when creating a font. --- src/ftcrfont.c | 6 ++- src/xsettings.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ src/xsettings.h | 5 +- 3 files changed, 127 insertions(+), 2 deletions(-) diff --git a/src/ftcrfont.c b/src/ftcrfont.c index 98a28af5f2..b659024524 100644 --- a/src/ftcrfont.c +++ b/src/ftcrfont.c @@ -37,6 +37,7 @@ #include "font.h" #include "ftfont.h" #include "pdumper.h" +#include "xsettings.h" #ifdef USE_BE_CAIRO #define RED_FROM_ULONG(color) (((color) >> 16) & 0xff) @@ -168,10 +169,13 @@ 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); - cairo_font_options_t *options = cairo_font_options_create (); + #ifdef USE_BE_CAIRO + cairo_font_options_t *options = cairo_font_options_create(); if (be_use_subpixel_antialiasing ()) cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_SUBPIXEL); +#else + cairo_font_options_t *options = xsettings_get_font_options(); #endif cairo_scaled_font_t *scaled_font = cairo_scaled_font_create (font_face, &font_matrix, &ctm, options); diff --git a/src/xsettings.c b/src/xsettings.c index 71d02e6152..c72d59e99b 100644 --- a/src/xsettings.c +++ b/src/xsettings.c @@ -57,6 +57,7 @@ Copyright (C) 2009-2022 Free Software Foundation, Inc. #if defined USE_CAIRO || defined HAVE_XFT #ifdef USE_CAIRO #include +#include #else /* HAVE_XFT */ #include #endif @@ -67,6 +68,10 @@ Copyright (C) 2009-2022 Free Software Foundation, Inc. static Display_Info *first_dpyinfo; static Lisp_Object current_tool_bar_style; +#ifdef USE_CAIRO +static cairo_font_options_t *font_options; +#endif + /* Store a config changed event in to the event queue. */ static void @@ -215,11 +220,96 @@ #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; +/* For hinting and antialias no dynamic re-display is (yet) possible, + because cairo applies these options when creating the font, not when + rendering it. +*/ + +#ifdef HAVE_PGTK +/* 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") == 0) + cairo_font_options_set_hint_style(font_options, CAIRO_HINT_STYLE_FULL); + else if (strcmp (hinting, "medium") == 0) + cairo_font_options_set_hint_style(font_options, CAIRO_HINT_STYLE_MEDIUM); + else if (strcmp (hinting, "slight") == 0) + cairo_font_options_set_hint_style(font_options, CAIRO_HINT_STYLE_SLIGHT); + else if (strcmp (hinting, "none") == 0) + 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") == 0) + cairo_font_options_set_antialias(font_options, CAIRO_ANTIALIAS_NONE); + else if (strcmp(antialias, "grayscale") == 0) + cairo_font_options_set_antialias(font_options, CAIRO_ANTIALIAS_GRAY); + else if (strcmp(antialias, "rgba") == 0) + 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") == 0) + cairo_font_options_set_subpixel_order(font_options, CAIRO_SUBPIXEL_ORDER_RGB); + else if (strcmp (rgba_order, "bgr") == 0) + cairo_font_options_set_subpixel_order(font_options, CAIRO_SUBPIXEL_ORDER_BGR); + else if (strcmp (rgba_order, "vrgb") == 0) + cairo_font_options_set_subpixel_order(font_options, CAIRO_SUBPIXEL_ORDER_VRGB); + else if (strcmp (rgba_order, "vbgr") == 0) + 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 @@ -900,6 +990,18 @@ init_gsettings (void) dupstring (¤t_font, g_variant_get_string (val, NULL)); g_variant_unref (val); } + + /* Only use the gsettings font entries for non-X cairo backends + (which is the recommended way of running pgtk builds). + For the X 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 +1123,18 @@ xsettings_get_system_normal_font (void) } #endif +#ifdef USE_CAIRO +/* Return the cairo font options, possibly initialized in + init_gsettings() */ +cairo_font_options_t * +xsettings_get_font_options (void) { + if (font_options == NULL) + return cairo_font_options_create(); + else + 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 +1187,10 @@ syms_of_xsettings (void) gconf_client = NULL; PDUMPER_IGNORE (gconf_client); #endif +#ifdef USE_CAIRO + 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..15984e8865 100644 --- a/src/xsettings.h +++ b/src/xsettings.h @@ -40,6 +40,9 @@ #define XSETTINGS_H #ifdef USE_LUCID extern const char *xsettings_get_system_normal_font (void); #endif - +#ifdef USE_CAIRO +struct cairo_font_options_t; +extern cairo_font_options_t *xsettings_get_font_options (void); +#endif #endif /* XSETTINGS_H */ -- 2.32.0