From 5e6b52fbfc6f8d50d69be21f2c551ceeb9d1527c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 22 Jan 2023 17:05:29 -0500 Subject: [PATCH] Add GtkGlyphPaintable This is a paintable that wraps a font file, and renders a single glyph. The glyph can be selected by the "glyph" property, but the paintable looks for a glyph with the name "icon0" first, so single-icon fonts can be made to work out of the box. The paintable has properties to set font variations, as well as colors. It implements GtkSymbolicPaintable, and will override the foreground, error, warning and success colors with theme colors when used symbolically. --- demos/gtk-demo/demo.gresource.xml | 2 - demos/gtk-demo/glyphpaintable.h | 45 ----- demos/gtk-demo/meson.build | 1 - demos/gtk-demo/paintable_glyph.c | 4 +- demos/gtk-demo/paintable_glyph.ui | 2 +- gtk/gtk.h | 1 + .../gtkglyphpaintable.c | 174 +++++++++--------- gtk/gtkglyphpaintable.h | 58 ++++++ gtk/meson.build | 4 + 9 files changed, 151 insertions(+), 140 deletions(-) delete mode 100644 demos/gtk-demo/glyphpaintable.h rename demos/gtk-demo/glyphpaintable.c => gtk/gtkglyphpaintable.c (66%) create mode 100644 gtk/gtkglyphpaintable.h diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index d8f481045c..270cf58a98 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -223,8 +223,6 @@ paintable_glyph.ui paintable_glyph.css - glyphpaintable.h - glyphpaintable.c fontvariations.h fontvariations.c fontvariations.ui diff --git a/demos/gtk-demo/glyphpaintable.h b/demos/gtk-demo/glyphpaintable.h deleted file mode 100644 index 2be90cd251..0000000000 --- a/demos/gtk-demo/glyphpaintable.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include -#include - -G_BEGIN_DECLS - -#define GLYPH_TYPE_PAINTABLE (glyph_paintable_get_type ()) - -G_DECLARE_FINAL_TYPE (GlyphPaintable, glyph_paintable, GLYPH, PAINTABLE, GObject) - -GdkPaintable * glyph_paintable_new (hb_face_t *face, - hb_codepoint_t glyph); - -void glyph_paintable_set_face (GlyphPaintable *self, - hb_face_t *face); - -hb_face_t * glyph_paintable_get_face (GlyphPaintable *self); - -void glyph_paintable_set_glyph (GlyphPaintable *self, - hb_codepoint_t glyph); - -hb_codepoint_t glyph_paintable_get_glyph (GlyphPaintable *self); - -void glyph_paintable_set_variations (GlyphPaintable *self, - const char *variations); - -const char * glyph_paintable_get_variations (GlyphPaintable *self); - -void glyph_paintable_set_color (GlyphPaintable *self, - const GdkRGBA *color); - -const GdkRGBA * glyph_paintable_get_color (GlyphPaintable *self); - -void glyph_paintable_set_palette_index (GlyphPaintable *self, - unsigned int palette_index); - -unsigned int glyph_paintable_get_palette_index (GlyphPaintable *self); - -void glyph_paintable_set_custom_colors (GlyphPaintable *self, - const char *palette); - -const char * glyph_paintable_get_custom_colors (GlyphPaintable *self); - -G_END_DECLS diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build index 9985204568..ddcf1f217d 100644 --- a/demos/gtk-demo/meson.build +++ b/demos/gtk-demo/meson.build @@ -132,7 +132,6 @@ extra_demo_sources = files([ 'unicode-names.c', 'suggestionentry.c', 'language-names.c', - 'glyphpaintable.c', 'fontvariations.c', 'rangeedit.c', 'fontcolors.c', diff --git a/demos/gtk-demo/paintable_glyph.c b/demos/gtk-demo/paintable_glyph.c index d92fc194fb..508457386b 100644 --- a/demos/gtk-demo/paintable_glyph.c +++ b/demos/gtk-demo/paintable_glyph.c @@ -9,7 +9,6 @@ #include #include -#include "glyphpaintable.h" #include "fontvariations.h" #include "fontcolors.h" #include "glyphpicker.h" @@ -49,7 +48,7 @@ set_font_from_path (GdkPaintable *paintable, face = hb_face_create (blob, 0); hb_blob_destroy (blob); - glyph_paintable_set_face (GLYPH_PAINTABLE (paintable), face); + gtk_glyph_paintable_set_face (GTK_GLYPH_PAINTABLE (paintable), face); update_font_name (font_name, face); @@ -205,7 +204,6 @@ do_paintable_glyph (GtkWidget *do_widget) 800); g_object_unref (provider); - g_type_ensure (GLYPH_TYPE_PAINTABLE); g_type_ensure (FONT_VARIATIONS_TYPE); g_type_ensure (FONT_COLORS_TYPE); g_type_ensure (GLYPH_PICKER_TYPE); diff --git a/demos/gtk-demo/paintable_glyph.ui b/demos/gtk-demo/paintable_glyph.ui index ead6108520..458e897ca7 100644 --- a/demos/gtk-demo/paintable_glyph.ui +++ b/demos/gtk-demo/paintable_glyph.ui @@ -1,6 +1,6 @@ - + diff --git a/gtk/gtk.h b/gtk/gtk.h index ccb9c98fa3..97f65acaa1 100644 --- a/gtk/gtk.h +++ b/gtk/gtk.h @@ -154,6 +154,7 @@ #include #include #include +#include #include #include #include diff --git a/demos/gtk-demo/glyphpaintable.c b/gtk/gtkglyphpaintable.c similarity index 66% rename from demos/gtk-demo/glyphpaintable.c rename to gtk/gtkglyphpaintable.c index cea7e040df..bbc6bfd0c2 100644 --- a/demos/gtk-demo/glyphpaintable.c +++ b/gtk/gtkglyphpaintable.c @@ -1,11 +1,11 @@ #include "config.h" -#include "glyphpaintable.h" +#include "gtkglyphpaintable.h" #include #include #include -struct _GlyphPaintable +struct _GtkGlyphPaintable { GObject parent_instance; hb_face_t *face; @@ -18,7 +18,7 @@ struct _GlyphPaintable GdkRGBA color; }; -struct _GlyphPaintableClass +struct _GtkGlyphPaintableClass { GObjectClass parent_class; }; @@ -36,14 +36,14 @@ enum { static GParamSpec *properties[NUM_PROPERTIES] = { NULL, }; static void -glyph_paintable_snapshot_symbolic (GtkSymbolicPaintable *paintable, - GdkSnapshot *snapshot, - double width, - double height, - const GdkRGBA *colors, - gsize n_colors) +gtk_glyph_paintable_snapshot_symbolic (GtkSymbolicPaintable *paintable, + GdkSnapshot *snapshot, + double width, + double height, + const GdkRGBA *colors, + gsize n_colors) { - GlyphPaintable *self = GLYPH_PAINTABLE (paintable); + GtkGlyphPaintable *self = GTK_GLYPH_PAINTABLE (paintable); cairo_t *cr; unsigned int upem; cairo_font_face_t *cairo_face; @@ -91,7 +91,7 @@ glyph_paintable_snapshot_symbolic (GtkSymbolicPaintable *paintable, g_strfreev (entries); } - for (int i = 0; i +1 < MIN (4, n_colors); i++) + for (int i = 0; i + 1 < MIN (4, n_colors); i++) cairo_font_options_set_custom_palette_color (font_options, i, colors[i + 1].red, colors[i + 1].green, @@ -134,19 +134,19 @@ glyph_paintable_snapshot_symbolic (GtkSymbolicPaintable *paintable, } static void -glyph_paintable_snapshot (GdkPaintable *paintable, - GdkSnapshot *snapshot, - double width, - double height) +gtk_glyph_paintable_snapshot (GdkPaintable *paintable, + GdkSnapshot *snapshot, + double width, + double height) { - glyph_paintable_snapshot_symbolic (GTK_SYMBOLIC_PAINTABLE (paintable), - snapshot, width, height, NULL, 0); + gtk_glyph_paintable_snapshot_symbolic (GTK_SYMBOLIC_PAINTABLE (paintable), + snapshot, width, height, NULL, 0); } static int -glyph_paintable_get_intrinsic_width (GdkPaintable *paintable) +gtk_glyph_paintable_get_intrinsic_width (GdkPaintable *paintable) { - GlyphPaintable *self = GLYPH_PAINTABLE (paintable); + GtkGlyphPaintable *self = GTK_GLYPH_PAINTABLE (paintable); hb_glyph_extents_t extents; if (!self->font) @@ -159,9 +159,9 @@ glyph_paintable_get_intrinsic_width (GdkPaintable *paintable) } static int -glyph_paintable_get_intrinsic_height (GdkPaintable *paintable) +gtk_glyph_paintable_get_intrinsic_height (GdkPaintable *paintable) { - GlyphPaintable *self = GLYPH_PAINTABLE (paintable); + GtkGlyphPaintable *self = GTK_GLYPH_PAINTABLE (paintable); hb_glyph_extents_t extents; if (!self->font) @@ -174,77 +174,77 @@ glyph_paintable_get_intrinsic_height (GdkPaintable *paintable) } static void -glyph_paintable_init_interface (GdkPaintableInterface *iface) +gtk_glyph_paintable_init_interface (GdkPaintableInterface *iface) { - iface->snapshot = glyph_paintable_snapshot; - iface->get_intrinsic_width = glyph_paintable_get_intrinsic_width; - iface->get_intrinsic_height = glyph_paintable_get_intrinsic_height; + iface->snapshot = gtk_glyph_paintable_snapshot; + iface->get_intrinsic_width = gtk_glyph_paintable_get_intrinsic_width; + iface->get_intrinsic_height = gtk_glyph_paintable_get_intrinsic_height; } static void glyph_symbolic_paintable_init_interface (GtkSymbolicPaintableInterface *iface) { - iface->snapshot_symbolic = glyph_paintable_snapshot_symbolic; + iface->snapshot_symbolic = gtk_glyph_paintable_snapshot_symbolic; } -G_DEFINE_TYPE_WITH_CODE (GlyphPaintable, glyph_paintable, G_TYPE_OBJECT, +G_DEFINE_TYPE_WITH_CODE (GtkGlyphPaintable, gtk_glyph_paintable, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, - glyph_paintable_init_interface) + gtk_glyph_paintable_init_interface) G_IMPLEMENT_INTERFACE (GTK_TYPE_SYMBOLIC_PAINTABLE, glyph_symbolic_paintable_init_interface)) static void -glyph_paintable_init (GlyphPaintable *self) +gtk_glyph_paintable_init (GtkGlyphPaintable *self) { self->subpixel_bits = 6; self->color = (GdkRGBA) { 0, 0, 0, 1 }; } static void -glyph_paintable_dispose (GObject *object) +gtk_glyph_paintable_dispose (GObject *object) { - GlyphPaintable *self = GLYPH_PAINTABLE (object); + GtkGlyphPaintable *self = GTK_GLYPH_PAINTABLE (object); g_clear_pointer (&self->face, hb_face_destroy); g_clear_pointer (&self->font, hb_font_destroy); g_free (self->variations); g_free (self->custom_colors); - G_OBJECT_CLASS (glyph_paintable_parent_class)->dispose (object); + G_OBJECT_CLASS (gtk_glyph_paintable_parent_class)->dispose (object); } static void -glyph_paintable_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +gtk_glyph_paintable_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - GlyphPaintable *self = GLYPH_PAINTABLE (object); + GtkGlyphPaintable *self = GTK_GLYPH_PAINTABLE (object); switch (prop_id) { case PROP_FACE: - glyph_paintable_set_face (self, (hb_face_t *)g_value_get_boxed (value)); + gtk_glyph_paintable_set_face (self, (hb_face_t *)g_value_get_boxed (value)); break; case PROP_GLYPH: - glyph_paintable_set_glyph (self, g_value_get_uint (value)); + gtk_glyph_paintable_set_glyph (self, g_value_get_uint (value)); break; case PROP_VARIATIONS: - glyph_paintable_set_variations (self, g_value_get_string (value)); + gtk_glyph_paintable_set_variations (self, g_value_get_string (value)); break; case PROP_COLOR: - glyph_paintable_set_color (self, g_value_get_boxed (value)); + gtk_glyph_paintable_set_color (self, g_value_get_boxed (value)); break; case PROP_PALETTE_INDEX: - glyph_paintable_set_palette_index (self, g_value_get_uint (value)); + gtk_glyph_paintable_set_palette_index (self, g_value_get_uint (value)); break; case PROP_CUSTOM_COLORS: - glyph_paintable_set_custom_colors (self, g_value_get_string (value)); + gtk_glyph_paintable_set_custom_colors (self, g_value_get_string (value)); break; default: @@ -253,12 +253,12 @@ glyph_paintable_set_property (GObject *object, } static void -glyph_paintable_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +gtk_glyph_paintable_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - GlyphPaintable *self = GLYPH_PAINTABLE (object); + GtkGlyphPaintable *self = GTK_GLYPH_PAINTABLE (object); switch (prop_id) { @@ -293,13 +293,13 @@ glyph_paintable_get_property (GObject *object, static void -glyph_paintable_class_init (GlyphPaintableClass *class) +gtk_glyph_paintable_class_init (GtkGlyphPaintableClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - object_class->dispose = glyph_paintable_dispose; - object_class->set_property = glyph_paintable_set_property; - object_class->get_property = glyph_paintable_get_property; + object_class->dispose = gtk_glyph_paintable_dispose; + object_class->set_property = gtk_glyph_paintable_set_property; + object_class->get_property = gtk_glyph_paintable_get_property; properties[PROP_FACE] = g_param_spec_boxed ("face", NULL, NULL, HB_GOBJECT_TYPE_FACE, @@ -329,12 +329,10 @@ glyph_paintable_class_init (GlyphPaintableClass *class) } GdkPaintable * -glyph_paintable_new (hb_face_t *face, - hb_codepoint_t glyph) +gtk_glyph_paintable_new (hb_face_t *face) { - return g_object_new (GLYPH_TYPE_PAINTABLE, + return g_object_new (GTK_TYPE_GLYPH_PAINTABLE, "face", face, - "glyph", glyph, NULL); } @@ -373,7 +371,7 @@ count_variations (const char *string) } static void -update_font (GlyphPaintable *self) +update_font (GtkGlyphPaintable *self) { unsigned int upem; int scale; @@ -400,7 +398,7 @@ update_font (GlyphPaintable *self) } static void -update_glyph (GlyphPaintable *self) +guess_default_glyph (GtkGlyphPaintable *self) { hb_codepoint_t glyph; @@ -413,10 +411,10 @@ update_glyph (GlyphPaintable *self) } void -glyph_paintable_set_face (GlyphPaintable *self, +gtk_glyph_paintable_set_face (GtkGlyphPaintable *self, hb_face_t *face) { - g_return_if_fail (GLYPH_IS_PAINTABLE (self)); + g_return_if_fail (GTK_IS_GLYPH_PAINTABLE (self)); g_clear_pointer (&self->face, hb_face_destroy); @@ -424,7 +422,7 @@ glyph_paintable_set_face (GlyphPaintable *self, self->face = hb_face_reference (face); update_font (self); - update_glyph (self); + guess_default_glyph (self); gdk_paintable_invalidate_contents (GDK_PAINTABLE (self)); gdk_paintable_invalidate_size (GDK_PAINTABLE (self)); @@ -432,18 +430,18 @@ glyph_paintable_set_face (GlyphPaintable *self, } hb_face_t * -glyph_paintable_get_face (GlyphPaintable *self) +gtk_glyph_paintable_get_face (GtkGlyphPaintable *self) { - g_return_val_if_fail (GLYPH_IS_PAINTABLE (self), NULL); + g_return_val_if_fail (GTK_IS_GLYPH_PAINTABLE (self), NULL); return self->face; } void -glyph_paintable_set_glyph (GlyphPaintable *self, - hb_codepoint_t glyph) +gtk_glyph_paintable_set_glyph (GtkGlyphPaintable *self, + hb_codepoint_t glyph) { - g_return_if_fail (GLYPH_IS_PAINTABLE (self)); + g_return_if_fail (GTK_IS_GLYPH_PAINTABLE (self)); self->glyph = glyph; @@ -453,18 +451,18 @@ glyph_paintable_set_glyph (GlyphPaintable *self, } hb_codepoint_t -glyph_paintable_get_glyph (GlyphPaintable *self) +gtk_glyph_paintable_get_glyph (GtkGlyphPaintable *self) { - g_return_val_if_fail (GLYPH_IS_PAINTABLE (self), 0); + g_return_val_if_fail (GTK_IS_GLYPH_PAINTABLE (self), 0); return self->glyph; } void -glyph_paintable_set_palette_index (GlyphPaintable *self, - unsigned int palette_index) +gtk_glyph_paintable_set_palette_index (GtkGlyphPaintable *self, + unsigned int palette_index) { - g_return_if_fail (GLYPH_IS_PAINTABLE (self)); + g_return_if_fail (GTK_IS_GLYPH_PAINTABLE (self)); self->palette_index = palette_index; @@ -473,18 +471,18 @@ glyph_paintable_set_palette_index (GlyphPaintable *self, } unsigned int -glyph_paintable_get_palette_index (GlyphPaintable *self) +gtk_glyph_paintable_get_palette_index (GtkGlyphPaintable *self) { - g_return_val_if_fail (GLYPH_IS_PAINTABLE (self), 0); + g_return_val_if_fail (GTK_IS_GLYPH_PAINTABLE (self), 0); return self->palette_index; } void -glyph_paintable_set_variations (GlyphPaintable *self, - const char *variations) +gtk_glyph_paintable_set_variations (GtkGlyphPaintable *self, + const char *variations) { - g_return_if_fail (GLYPH_IS_PAINTABLE (self)); + g_return_if_fail (GTK_IS_GLYPH_PAINTABLE (self)); g_free (self->variations); self->variations = g_strdup (variations); @@ -497,18 +495,18 @@ glyph_paintable_set_variations (GlyphPaintable *self, } const char * -glyph_paintable_get_variations (GlyphPaintable *self) +gtk_glyph_paintable_get_variations (GtkGlyphPaintable *self) { - g_return_val_if_fail (GLYPH_IS_PAINTABLE (self), NULL); + g_return_val_if_fail (GTK_IS_GLYPH_PAINTABLE (self), NULL); return self->variations; } void -glyph_paintable_set_custom_colors (GlyphPaintable *self, - const char *custom_colors) +gtk_glyph_paintable_set_custom_colors (GtkGlyphPaintable *self, + const char *custom_colors) { - g_return_if_fail (GLYPH_IS_PAINTABLE (self)); + g_return_if_fail (GTK_IS_GLYPH_PAINTABLE (self)); g_free (self->custom_colors); self->custom_colors = g_strdup (custom_colors); @@ -518,18 +516,18 @@ glyph_paintable_set_custom_colors (GlyphPaintable *self, } const char * -glyph_paintable_get_custom_colors (GlyphPaintable *self) +gtk_glyph_paintable_get_custom_colors (GtkGlyphPaintable *self) { - g_return_val_if_fail (GLYPH_IS_PAINTABLE (self), NULL); + g_return_val_if_fail (GTK_IS_GLYPH_PAINTABLE (self), NULL); return self->custom_colors; } void -glyph_paintable_set_color (GlyphPaintable *self, - const GdkRGBA *color) +gtk_glyph_paintable_set_color (GtkGlyphPaintable *self, + const GdkRGBA *color) { - g_return_if_fail (GLYPH_IS_PAINTABLE (self)); + g_return_if_fail (GTK_IS_GLYPH_PAINTABLE (self)); if (gdk_rgba_equal (&self->color, color)) return; @@ -541,9 +539,9 @@ glyph_paintable_set_color (GlyphPaintable *self, } const GdkRGBA * -glyph_paintable_get_color (GlyphPaintable *self) +gtk_glyph_paintable_get_color (GtkGlyphPaintable *self) { - g_return_val_if_fail (GLYPH_IS_PAINTABLE (self), NULL); + g_return_val_if_fail (GTK_IS_GLYPH_PAINTABLE (self), NULL); return &self->color; } diff --git a/gtk/gtkglyphpaintable.h b/gtk/gtkglyphpaintable.h new file mode 100644 index 0000000000..7064f86259 --- /dev/null +++ b/gtk/gtkglyphpaintable.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_GLYPH_PAINTABLE (gtk_glyph_paintable_get_type ()) + +GDK_AVAILABLE_IN_4_10 +G_DECLARE_FINAL_TYPE (GtkGlyphPaintable, gtk_glyph_paintable, GTK, GLYPH_PAINTABLE, GObject) + +GDK_AVAILABLE_IN_4_10 +GdkPaintable * gtk_glyph_paintable_new (hb_face_t *face); + +GDK_AVAILABLE_IN_4_10 +void gtk_glyph_paintable_set_face (GtkGlyphPaintable *self, + hb_face_t *face); + +GDK_AVAILABLE_IN_4_10 +hb_face_t * gtk_glyph_paintable_get_face (GtkGlyphPaintable *self); + +GDK_AVAILABLE_IN_4_10 +void gtk_glyph_paintable_set_glyph (GtkGlyphPaintable *self, + hb_codepoint_t glyph); + +GDK_AVAILABLE_IN_4_10 +hb_codepoint_t gtk_glyph_paintable_get_glyph (GtkGlyphPaintable *self); + +GDK_AVAILABLE_IN_4_10 +void gtk_glyph_paintable_set_variations (GtkGlyphPaintable *self, + const char *variations); + +GDK_AVAILABLE_IN_4_10 +const char * gtk_glyph_paintable_get_variations (GtkGlyphPaintable *self); + +GDK_AVAILABLE_IN_4_10 +void gtk_glyph_paintable_set_color (GtkGlyphPaintable *self, + const GdkRGBA *color); + +GDK_AVAILABLE_IN_4_10 +const GdkRGBA * gtk_glyph_paintable_get_color (GtkGlyphPaintable *self); + +GDK_AVAILABLE_IN_4_10 +void gtk_glyph_paintable_set_palette_index (GtkGlyphPaintable *self, + unsigned int palette_index); + +GDK_AVAILABLE_IN_4_10 +unsigned int gtk_glyph_paintable_get_palette_index (GtkGlyphPaintable *self); + +GDK_AVAILABLE_IN_4_10 +void gtk_glyph_paintable_set_custom_colors (GtkGlyphPaintable *self, + const char *palette); + +GDK_AVAILABLE_IN_4_10 +const char * gtk_glyph_paintable_get_custom_colors (GtkGlyphPaintable *self); + +G_END_DECLS diff --git a/gtk/meson.build b/gtk/meson.build index 13d2404630..1ed865caa1 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -251,6 +251,7 @@ gtk_public_sources = files([ 'gtkgestureswipe.c', 'gtkgesturezoom.c', 'gtkglarea.c', + 'gtkglyphpaintable.c', 'gtkgrid.c', 'gtkgridlayout.c', 'gtkgridview.c', @@ -500,6 +501,7 @@ gtk_public_headers = files([ 'gtkgestureswipe.h', 'gtkgesturezoom.h', 'gtkglarea.h', + 'gtkglyphpaintable.h', 'gtkgrid.h', 'gtkgridlayout.h', 'gtkgridview.h', @@ -1050,6 +1052,8 @@ gtk_deps = [ platform_gio_dep, pangocairo_dep, harfbuzz_dep, + hbcairo_dep, + hbgobj_dep, fribidi_dep, cairogobj_dep, fontconfig_dep,