Add a new font rendering setting

Add a high-level setting that gives us more freedom to tweak
font rendering knobs according to our needs. It has a 'manual'
value that lets users continue to influence font rendering using
the low-level font-related settings as before.

Once the schemas have this, we can support setting this session-wide.
See https://gitlab.gnome.org/GNOME/gsettings-desktop-schemas/-/merge_requests/79

The initial implementation of 'automatic' font rendering is fairly
simplistic: if the monitor dpi is less than 200, prefer sharpness,
so turn on metrics hinting and slight hinting. If the monitor dpi
is at least 200, we both off.
This commit is contained in:
Matthias Clasen 2024-04-05 10:54:29 +02:00
parent 558db5a3a7
commit 5f7cab4632
4 changed files with 89 additions and 0 deletions

View File

@ -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 } },

View File

@ -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

View File

@ -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;

View File

@ -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);
}