diff options
| author | Pieter van Prooijen | 2022-05-08 16:27:38 +0200 |
|---|---|---|
| committer | Po Lu | 2022-05-13 20:52:02 +0800 |
| commit | 526e9758de7d163ce3b25fde69a4e122ce9c3742 (patch) | |
| tree | 94ef87a41be88f91f76bdeaae27e5cf8eed9c26d /src | |
| parent | 784a3bde24be0637646ad0bf22f695c84b8e3e05 (diff) | |
| download | emacs-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.c | 33 | ||||
| -rw-r--r-- | src/xsettings.c | 147 | ||||
| -rw-r--r-- | src/xsettings.h | 5 |
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. */ | ||
| 639 | static bool | ||
| 640 | ftcrfont_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 | ||
| 629 | static Lisp_Object | 659 | static 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 |
| 699 | struct font_driver ftcrhbfont_driver; | 732 | struct 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 | ||
| 221 | static GSettings *gsettings_client; | 226 | static GSettings *gsettings_client; |
| 222 | 227 | ||
| 228 | #ifdef HAVE_PGTK | ||
| 229 | |||
| 230 | /* The cairo font_options as obtained using gsettings. */ | ||
| 231 | static cairo_font_options_t *font_options; | ||
| 232 | |||
| 233 | /* Store an event for re-rendering of the fonts. */ | ||
| 234 | static void | ||
| 235 | store_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. */ | ||
| 243 | static void | ||
| 244 | apply_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. */ | ||
| 272 | static void | ||
| 273 | apply_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. */ | ||
| 298 | static void | ||
| 299 | apply_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 | ||
| 225 | static void | 330 | static 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 (¤t_font, g_variant_get_string (val, NULL)); | 1022 | dupstring (¤t_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. */ | ||
| 1160 | cairo_font_options_t * | ||
| 1161 | xsettings_get_font_options (void) | ||
| 1162 | { | ||
| 1163 | return cairo_font_options_copy (font_options); | ||
| 1164 | } | ||
| 1165 | #endif | ||
| 1166 | |||
| 1024 | DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font, | 1167 | DEFUN ("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 | ||
| 28 | struct x_display_info; | 30 | struct x_display_info; |
| @@ -41,5 +43,8 @@ extern const char *xsettings_get_system_font (void); | |||
| 41 | extern const char *xsettings_get_system_normal_font (void); | 43 | extern const char *xsettings_get_system_normal_font (void); |
| 42 | #endif | 44 | #endif |
| 43 | 45 | ||
| 46 | #ifdef HAVE_PGTK | ||
| 47 | extern cairo_font_options_t *xsettings_get_font_options (void); | ||
| 48 | #endif | ||
| 44 | 49 | ||
| 45 | #endif /* XSETTINGS_H */ | 50 | #endif /* XSETTINGS_H */ |