diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index c7990ec178..7cff83ce22 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -1811,6 +1811,7 @@ static TranslationEntry translations[] = { { FALSE, "org.gnome.desktop.interface", "font-hinting", "gtk-xft-hinting", G_TYPE_NONE, { .i = 1 } }, { FALSE, "org.gnome.desktop.interface", "font-hinting", "gtk-xft-hintstyle", G_TYPE_NONE, { .i = 1 } }, { FALSE, "org.gnome.desktop.interface", "font-rgba-order", "gtk-xft-rgba", G_TYPE_NONE, { .i = 0 } }, + { FALSE, "org.gnome.desktop.interface", "font-rendering", "gtk-font-rendering", G_TYPE_ENUM, { .i = 0 } }, { FALSE, "org.gnome.settings-daemon.plugins.xsettings", "antialiasing", "gtk-xft-antialias", G_TYPE_NONE, { .i = 1 } }, { FALSE, "org.gnome.settings-daemon.plugins.xsettings", "hinting", "gtk-xft-hinting", G_TYPE_NONE, { .i = 1 } }, { FALSE, "org.gnome.settings-daemon.plugins.xsettings", "hinting", "gtk-xft-hintstyle", G_TYPE_NONE, { .i = 1 } }, diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index c8e7713e44..584c296f15 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -1852,4 +1852,29 @@ typedef enum { /*< prefix=GTK_POPOVER_MENU >*/ GTK_POPOVER_MENU_NESTED = 1 << 0 } GtkPopoverMenuFlags; +/** + * GtkFontRendering: + * @GTK_FONT_RENDERING_AUTOMATIC: Set up font rendering automatically, + * taking factors like screen resolution and scale into account + * @GTK_FONT_RENDERING_MANUAL: Follow low-level font-related settings + * when configuring font rendering + * + * Values for the [property@Gtk.Settings:gtk-font-rendering] setting + * that influence how GTK renders fonts. + * + * The @GTK_FONT_RENDERING_AUTOMATIC value allows GTK to disregard the + * low-level font-related settings: + * [property@Gtk.Settings:gtk-hint-font-metrics], + * [property@Gtk.Settings:gtk-xft-antialias], + * [property@Gtk.Settings:gtk-xft-hinting], + * [property@Gtk.Settings:gtk-xft-hintstyle] and + * [property@Gtk.Settings:gtk-xft-rgba]. + * + * Since: 4.16 + */ +typedef enum { + GTK_FONT_RENDERING_AUTOMATIC, + GTK_FONT_RENDERING_MANUAL, +} GtkFontRendering; + G_END_DECLS diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c index 8b4522bee2..742ba182f8 100644 --- a/gtk/gtksettings.c +++ b/gtk/gtksettings.c @@ -202,6 +202,7 @@ enum { PROP_LONG_PRESS_TIME, PROP_KEYNAV_USE_CARET, PROP_OVERLAY_SCROLLING, + PROP_FONT_RENDERING, NUM_PROPERTIES }; @@ -955,6 +956,18 @@ gtk_settings_class_init (GtkSettingsClass *class) TRUE, GTK_PARAM_READWRITE); + /** + * GtkSettings:gtk-font-rendering: + * + * How GTK font rendering is set up. + * + * Since: 4.16 + */ + pspecs[PROP_FONT_RENDERING] = g_param_spec_enum ("gtk-font-rendering", NULL, NULL, + GTK_TYPE_FONT_RENDERING, + GTK_FONT_RENDERING_AUTOMATIC, + GTK_PARAM_READWRITE); + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, pspecs); } @@ -1260,6 +1273,9 @@ gtk_settings_notify (GObject *object, if (settings_update_fontconfig (settings)) gtk_system_setting_changed (settings->display, GTK_SYSTEM_SETTING_FONT_CONFIG); break; + case PROP_FONT_RENDERING: + gtk_system_setting_changed (settings->display, GTK_SYSTEM_SETTING_FONT_CONFIG); + break; case PROP_ENABLE_ANIMATIONS: settings_invalidate_style (settings); break; diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index e63b200aee..0e7f578b6d 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -74,6 +74,7 @@ #include "gdk/gdkeventsprivate.h" #include "gdk/gdkprofilerprivate.h" +#include "gdk/gdkmonitorprivate.h" #include "gsk/gskdebugprivate.h" #include "gsk/gskrendererprivate.h" @@ -6464,6 +6465,7 @@ gtk_widget_update_pango_context (GtkWidget *widget, PangoFontDescription *font_desc; GtkSettings *settings; guint old_serial; + GtkFontRendering font_rendering; old_serial = pango_context_get_serial (context); @@ -6483,6 +6485,11 @@ gtk_widget_update_pango_context (GtkWidget *widget, settings = gtk_widget_get_settings (widget); if (settings) + g_object_get (settings, "gtk-font-rendering", &font_rendering, NULL); + else + font_rendering = GTK_FONT_RENDERING_AUTOMATIC; + + if (font_rendering == GTK_FONT_RENDERING_MANUAL) { gboolean hint_font_metrics; cairo_font_options_t *font_options, *options; @@ -6501,6 +6508,46 @@ gtk_widget_update_pango_context (GtkWidget *widget, pango_context_set_round_glyph_positions (context, hint_font_metrics); pango_cairo_context_set_font_options (context, options); + cairo_font_options_destroy (options); + } + else + { + cairo_font_options_t *options; + double dpi = 96.; + GdkSurface *surface; + + surface = gtk_widget_get_surface (widget); + if (surface) + { + GdkDisplay *display; + GdkMonitor *monitor; + + display = gdk_surface_get_display (surface); + monitor = gdk_display_get_monitor_at_surface (display, surface); + if (monitor) + dpi = gdk_monitor_get_dpi (monitor); + } + + options = cairo_font_options_create (); + + cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY); + + if (dpi < 200.) + { + /* Not high-dpi. Prefer sharpness by enabling hinting */ + cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON); + cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_SLIGHT); + } + else + { + /* High-dpi. Prefer precise positioning */ + cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF); + cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE); + } + + pango_context_set_round_glyph_positions (context, FALSE); + pango_cairo_context_set_font_options (context, options); + cairo_font_options_destroy (options); }