aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPieter van Prooijen2022-05-08 16:27:38 +0200
committerPo Lu2022-05-13 20:52:02 +0800
commit526e9758de7d163ce3b25fde69a4e122ce9c3742 (patch)
tree94ef87a41be88f91f76bdeaae27e5cf8eed9c26d /src
parent784a3bde24be0637646ad0bf22f695c84b8e3e05 (diff)
downloademacs-526e9758de7d163ce3b25fde69a4e122ce9c3742.tar.gz
emacs-526e9758de7d163ce3b25fde69a4e122ce9c3742.zip
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. (ftcrfont_cached_font_ok): Report a cached font as invalid if its font options differ from the current options inside gsettings. * src/xsettings.c (apply_gsettings_font_hinting) (apply_gsettings_font_alias, apply_gsettings_font_rgba_order): Convert the settings from GSettings to the cairo_font_options_t object. (init_gsettings, something_changed_gsettingsCB): Invoke the apply functions if the relevant settings changed. (store_font_options_changed): Store an event to re-render the fonts. (xsetting_get_font_options) * src/xsettings.h (xsettings_get_font_options): New function.
Diffstat (limited to 'src')
-rw-r--r--src/ftcrfont.c33
-rw-r--r--src/xsettings.c147
-rw-r--r--src/xsettings.h5
3 files changed, 185 insertions, 0 deletions
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index 98a28af5f22..6bb41110d5c 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -37,6 +37,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
37#include "font.h" 37#include "font.h"
38#include "ftfont.h" 38#include "ftfont.h"
39#include "pdumper.h" 39#include "pdumper.h"
40#ifdef HAVE_PGTK
41#include "xsettings.h"
42#endif
40 43
41#ifdef USE_BE_CAIRO 44#ifdef USE_BE_CAIRO
42#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff) 45#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
@@ -168,7 +171,12 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
168 cairo_matrix_t font_matrix, ctm; 171 cairo_matrix_t font_matrix, ctm;
169 cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size); 172 cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size);
170 cairo_matrix_init_identity (&ctm); 173 cairo_matrix_init_identity (&ctm);
174
175#ifdef HAVE_PGTK
176 cairo_font_options_t *options = xsettings_get_font_options ();
177#else
171 cairo_font_options_t *options = cairo_font_options_create (); 178 cairo_font_options_t *options = cairo_font_options_create ();
179#endif
172#ifdef USE_BE_CAIRO 180#ifdef USE_BE_CAIRO
173 if (be_use_subpixel_antialiasing ()) 181 if (be_use_subpixel_antialiasing ())
174 cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_SUBPIXEL); 182 cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_SUBPIXEL);
@@ -624,6 +632,28 @@ ftcrfont_draw (struct glyph_string *s,
624 return len; 632 return len;
625} 633}
626 634
635#ifdef HAVE_PGTK
636/* Determine if FONT_OBJECT is a valid cached font for ENTITY by
637 comparing the options used to open it with the user's current
638 preferences specified via GSettings. */
639static bool
640ftcrfont_cached_font_ok (struct frame *f, Lisp_Object font_object,
641 Lisp_Object entity)
642{
643 struct font_info *info = (struct font_info *) XFONT_OBJECT (font_object);
644
645 cairo_font_options_t *options = cairo_font_options_create ();
646 cairo_scaled_font_get_font_options (info->cr_scaled_font, options);
647 cairo_font_options_t *gsettings_options = xsettings_get_font_options ();
648
649 bool equal = cairo_font_options_equal (options, gsettings_options);
650 cairo_font_options_destroy (options);
651 cairo_font_options_destroy (gsettings_options);
652
653 return equal;
654}
655#endif
656
627#ifdef HAVE_HARFBUZZ 657#ifdef HAVE_HARFBUZZ
628 658
629static Lisp_Object 659static Lisp_Object
@@ -694,6 +724,9 @@ struct font_driver const ftcrfont_driver =
694#endif 724#endif
695 .filter_properties = ftfont_filter_properties, 725 .filter_properties = ftfont_filter_properties,
696 .combining_capability = ftfont_combining_capability, 726 .combining_capability = ftfont_combining_capability,
727#ifdef HAVE_PGTK
728 .cached_font_ok = ftcrfont_cached_font_ok
729#endif
697 }; 730 };
698#ifdef HAVE_HARFBUZZ 731#ifdef HAVE_HARFBUZZ
699struct font_driver ftcrhbfont_driver; 732struct font_driver ftcrhbfont_driver;
diff --git a/src/xsettings.c b/src/xsettings.c
index 71d02e61525..e71887e03d9 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -215,11 +215,116 @@ struct xsettings
215#define GSETTINGS_FONT_NAME "font-name" 215#define GSETTINGS_FONT_NAME "font-name"
216#endif 216#endif
217 217
218#ifdef HAVE_PGTK
219#define GSETTINGS_FONT_ANTIALIASING "font-antialiasing"
220#define GSETTINGS_FONT_RGBA_ORDER "font-rgba-order"
221#define GSETTINGS_FONT_HINTING "font-hinting"
222#endif
218 223
219/* The single GSettings instance, or NULL if not connected to GSettings. */ 224/* The single GSettings instance, or NULL if not connected to GSettings. */
220 225
221static GSettings *gsettings_client; 226static GSettings *gsettings_client;
222 227
228#ifdef HAVE_PGTK
229
230/* The cairo font_options as obtained using gsettings. */
231static cairo_font_options_t *font_options;
232
233/* Store an event for re-rendering of the fonts. */
234static void
235store_font_options_changed (void)
236{
237 if (dpyinfo_valid (first_dpyinfo))
238 store_config_changed_event (Qfont_render,
239 XCAR (first_dpyinfo->name_list_element));
240}
241
242/* Apply changes in the hinting system setting. */
243static void
244apply_gsettings_font_hinting (GSettings *settings)
245{
246 GVariant *val = g_settings_get_value (settings, GSETTINGS_FONT_HINTING);
247 if (val)
248 {
249 g_variant_ref_sink (val);
250 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
251 {
252 const char *hinting = g_variant_get_string (val, NULL);
253
254 if (!strcmp (hinting, "full"))
255 cairo_font_options_set_hint_style (font_options,
256 CAIRO_HINT_STYLE_FULL);
257 else if (!strcmp (hinting, "medium"))
258 cairo_font_options_set_hint_style (font_options,
259 CAIRO_HINT_STYLE_MEDIUM);
260 else if (!strcmp (hinting, "slight"))
261 cairo_font_options_set_hint_style (font_options,
262 CAIRO_HINT_STYLE_SLIGHT);
263 else if (!strcmp (hinting, "none"))
264 cairo_font_options_set_hint_style (font_options,
265 CAIRO_HINT_STYLE_NONE);
266 }
267 g_variant_unref (val);
268 }
269}
270
271/* Apply changes in the antialiasing system setting. */
272static void
273apply_gsettings_font_antialias (GSettings *settings)
274{
275 GVariant *val = g_settings_get_value (settings, GSETTINGS_FONT_ANTIALIASING);
276 if (val)
277 {
278 g_variant_ref_sink (val);
279 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
280 {
281 const char *antialias = g_variant_get_string (val, NULL);
282
283 if (!strcmp (antialias, "none"))
284 cairo_font_options_set_antialias (font_options,
285 CAIRO_ANTIALIAS_NONE);
286 else if (!strcmp (antialias, "grayscale"))
287 cairo_font_options_set_antialias (font_options,
288 CAIRO_ANTIALIAS_GRAY);
289 else if (!strcmp (antialias, "rgba"))
290 cairo_font_options_set_antialias (font_options,
291 CAIRO_ANTIALIAS_SUBPIXEL);
292 }
293 g_variant_unref (val);
294 }
295}
296
297/* Apply the settings for the rgb element ordering. */
298static void
299apply_gsettings_font_rgba_order (GSettings *settings)
300{
301 GVariant *val = g_settings_get_value (settings,
302 GSETTINGS_FONT_RGBA_ORDER);
303 if (val)
304 {
305 g_variant_ref_sink (val);
306 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
307 {
308 const char *rgba_order = g_variant_get_string (val, NULL);
309
310 if (!strcmp (rgba_order, "rgb"))
311 cairo_font_options_set_subpixel_order (font_options,
312 CAIRO_SUBPIXEL_ORDER_RGB);
313 else if (!strcmp (rgba_order, "bgr"))
314 cairo_font_options_set_subpixel_order (font_options,
315 CAIRO_SUBPIXEL_ORDER_BGR);
316 else if (!strcmp (rgba_order, "vrgb"))
317 cairo_font_options_set_subpixel_order (font_options,
318 CAIRO_SUBPIXEL_ORDER_VRGB);
319 else if (!strcmp (rgba_order, "vbgr"))
320 cairo_font_options_set_subpixel_order (font_options,
321 CAIRO_SUBPIXEL_ORDER_VBGR);
322 }
323 g_variant_unref (val);
324 }
325}
326#endif /* HAVE_PGTK */
327
223/* Callback called when something changed in GSettings. */ 328/* Callback called when something changed in GSettings. */
224 329
225static void 330static void
@@ -273,6 +378,23 @@ something_changed_gsettingsCB (GSettings *settings,
273 } 378 }
274 } 379 }
275#endif /* USE_CAIRO || HAVE_XFT */ 380#endif /* USE_CAIRO || HAVE_XFT */
381#ifdef HAVE_PGTK
382 else if (!strcmp (key, GSETTINGS_FONT_ANTIALIASING))
383 {
384 apply_gsettings_font_antialias (settings);
385 store_font_options_changed ();
386 }
387 else if (!strcmp (key, GSETTINGS_FONT_HINTING))
388 {
389 apply_gsettings_font_hinting (settings);
390 store_font_options_changed ();
391 }
392 else if (!strcmp (key, GSETTINGS_FONT_RGBA_ORDER))
393 {
394 apply_gsettings_font_rgba_order (settings);
395 store_font_options_changed ();
396 }
397#endif /* HAVE_PGTK */
276} 398}
277 399
278#endif /* HAVE_GSETTINGS */ 400#endif /* HAVE_GSETTINGS */
@@ -900,6 +1022,16 @@ init_gsettings (void)
900 dupstring (&current_font, g_variant_get_string (val, NULL)); 1022 dupstring (&current_font, g_variant_get_string (val, NULL));
901 g_variant_unref (val); 1023 g_variant_unref (val);
902 } 1024 }
1025
1026 /* Only use the gsettings font entries for the Cairo backend
1027 running on PGTK. */
1028#ifdef HAVE_PGTK
1029 font_options = cairo_font_options_create ();
1030 apply_gsettings_font_antialias (gsettings_client);
1031 apply_gsettings_font_hinting (gsettings_client);
1032 apply_gsettings_font_rgba_order (gsettings_client);
1033#endif /* HAVE_PGTK */
1034
903#endif /* USE_CAIRO || HAVE_XFT */ 1035#endif /* USE_CAIRO || HAVE_XFT */
904 1036
905#endif /* HAVE_GSETTINGS */ 1037#endif /* HAVE_GSETTINGS */
@@ -1021,6 +1153,17 @@ xsettings_get_system_normal_font (void)
1021} 1153}
1022#endif 1154#endif
1023 1155
1156#ifdef HAVE_PGTK
1157/* Return the cairo font options, updated from the gsettings font
1158 config entries. The caller should call cairo_font_options_destroy
1159 on the result. */
1160cairo_font_options_t *
1161xsettings_get_font_options (void)
1162{
1163 return cairo_font_options_copy (font_options);
1164}
1165#endif
1166
1024DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font, 1167DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font,
1025 Sfont_get_system_normal_font, 1168 Sfont_get_system_normal_font,
1026 0, 0, 0, 1169 0, 0, 0,
@@ -1073,6 +1216,10 @@ syms_of_xsettings (void)
1073 gconf_client = NULL; 1216 gconf_client = NULL;
1074 PDUMPER_IGNORE (gconf_client); 1217 PDUMPER_IGNORE (gconf_client);
1075#endif 1218#endif
1219#ifdef HAVE_PGTK
1220 font_options = NULL;
1221 PDUMPER_IGNORE (font_options);
1222#endif
1076 1223
1077 DEFSYM (Qmonospace_font_name, "monospace-font-name"); 1224 DEFSYM (Qmonospace_font_name, "monospace-font-name");
1078 DEFSYM (Qfont_name, "font-name"); 1225 DEFSYM (Qfont_name, "font-name");
diff --git a/src/xsettings.h b/src/xsettings.h
index ccaa36489d0..5e5df37062b 100644
--- a/src/xsettings.h
+++ b/src/xsettings.h
@@ -23,6 +23,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
23#ifndef HAVE_PGTK 23#ifndef HAVE_PGTK
24#include "dispextern.h" 24#include "dispextern.h"
25#include <X11/Xlib.h> 25#include <X11/Xlib.h>
26#else
27#include <cairo.h>
26#endif 28#endif
27 29
28struct x_display_info; 30struct x_display_info;
@@ -41,5 +43,8 @@ extern const char *xsettings_get_system_font (void);
41extern const char *xsettings_get_system_normal_font (void); 43extern const char *xsettings_get_system_normal_font (void);
42#endif 44#endif
43 45
46#ifdef HAVE_PGTK
47extern cairo_font_options_t *xsettings_get_font_options (void);
48#endif
44 49
45#endif /* XSETTINGS_H */ 50#endif /* XSETTINGS_H */