From befccc943a542a82ed997e94bf416b870bbe6e80 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 20 Feb 2024 18:20:30 -0500 Subject: [PATCH] gsk: Add a way to get a scaled font Add a function to change the size of a font while keeping everything else the same. We use pango api for this if available. --- gsk/gskprivate.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ gsk/gskprivate.h | 5 ++- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/gsk/gskprivate.c b/gsk/gskprivate.c index 8404b9dbc6..f0045a1e39 100644 --- a/gsk/gskprivate.c +++ b/gsk/gskprivate.c @@ -1,6 +1,10 @@ #include "gskresources.h" #include "gskprivate.h" +#include +#include +#include + static gpointer register_resources (gpointer data) { @@ -15,3 +19,78 @@ gsk_ensure_resources (void) g_once (®ister_resources_once, register_resources, NULL); } + +/*< private > + * gsk_get_scaled_font: + * @font: a `PangoFont` + * @scale: the scale + * + * Returns a font that is just like @font, at a size that + * is multiplied by @scale. + * + * Returns: (transfer full): a scaled version of @font + */ +PangoFont * +gsk_get_scaled_font (PangoFont *font, + float scale) +{ + if (scale == 1.0) + return g_object_ref (font); + +#if PANGO_VERSION_CHECK (1, 52, 0) + return pango_font_map_reload_font (pango_font_get_font_map (font), font, scale, NULL, NULL); +#else + GHashTable *fonts; + int key; + PangoFont *font2; + PangoFontDescription *desc; + int size; + PangoFontMap *fontmap; + PangoContext *context; + cairo_scaled_font_t *sf; + cairo_font_options_t *options; + + key = (int) roundf (scale * PANGO_SCALE); + + fonts = (GHashTable *) g_object_get_data (G_OBJECT (font), "gsk-scaled-fonts"); + + if (fonts) + { + font2 = g_hash_table_lookup (fonts, GINT_TO_POINTER (key)); + if (font2) + return g_object_ref (font2); + } + else + { + fonts = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); + g_object_set_data_full (G_OBJECT (font), "gsk-scaled-fonts", + fonts, (GDestroyNotify) g_hash_table_unref); + } + + desc = pango_font_describe (font); + size = pango_font_description_get_size (desc); + + if (pango_font_description_get_size_is_absolute (desc)) + pango_font_description_set_absolute_size (desc, size * scale); + else + pango_font_description_set_size (desc, (int) roundf (size * scale)); + + fontmap = pango_font_get_font_map (font); + context = pango_font_map_create_context (fontmap); + + sf = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font)); + options = cairo_font_options_create (); + cairo_scaled_font_get_font_options (sf, options); + pango_cairo_context_set_font_options (context, options); + cairo_font_options_destroy (options); + + font2 = pango_font_map_load_font (fontmap, context, desc); + + pango_font_description_free (desc); + g_object_unref (context); + + g_hash_table_insert (fonts, GINT_TO_POINTER (key), font2); + + return g_object_ref (font2); +#endif +} diff --git a/gsk/gskprivate.h b/gsk/gskprivate.h index 150b89eb78..051a9e2ec9 100644 --- a/gsk/gskprivate.h +++ b/gsk/gskprivate.h @@ -5,7 +5,10 @@ G_BEGIN_DECLS -void gsk_ensure_resources (void); +void gsk_ensure_resources (void); + +PangoFont *gsk_get_scaled_font (PangoFont *font, + float scale); G_END_DECLS