gtk-demo: Rewrite the text mask demo

Use GtkSnapshot and GskPath instead of cairo for this.
This commit is contained in:
Matthias Clasen
2020-12-27 01:55:00 -05:00
committed by Benjamin Otte
parent 367a4cf800
commit 43e777d6a4

View File

@@ -7,68 +7,186 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
static void
draw_text (GtkDrawingArea *da,
cairo_t *cr,
int width,
int height,
gpointer data)
#define TEXT_TYPE_MASK_DEMO (text_mask_demo_get_type ())
G_DECLARE_FINAL_TYPE (TextMaskDemo, text_mask_demo, TEXT, MASK_DEMO, GtkWidget)
struct _TextMaskDemo
{
cairo_pattern_t *pattern;
PangoLayout *layout;
GtkWidget parent_instance;
char *text;
PangoFontDescription *desc;
GskPath *path;
};
cairo_save (cr);
struct _TextMaskDemoClass
{
GtkWidgetClass parent_class;
};
layout = gtk_widget_create_pango_layout (GTK_WIDGET (da), "Pango power!\nPango power!\nPango power!");
desc = pango_font_description_from_string ("sans bold 34");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
G_DEFINE_TYPE (TextMaskDemo, text_mask_demo, GTK_TYPE_WIDGET)
cairo_move_to (cr, 30, 20);
pango_cairo_layout_path (cr, layout);
g_object_unref (layout);
static void
update_path (TextMaskDemo *demo)
{
PangoLayout *layout;
GskPathBuilder *builder;
pattern = cairo_pattern_create_linear (0.0, 0.0, width, height);
cairo_pattern_add_color_stop_rgb (pattern, 0.0, 1.0, 0.0, 0.0);
cairo_pattern_add_color_stop_rgb (pattern, 0.2, 1.0, 0.0, 0.0);
cairo_pattern_add_color_stop_rgb (pattern, 0.3, 1.0, 1.0, 0.0);
cairo_pattern_add_color_stop_rgb (pattern, 0.4, 0.0, 1.0, 0.0);
cairo_pattern_add_color_stop_rgb (pattern, 0.6, 0.0, 1.0, 1.0);
cairo_pattern_add_color_stop_rgb (pattern, 0.7, 0.0, 0.0, 1.0);
cairo_pattern_add_color_stop_rgb (pattern, 0.8, 1.0, 0.0, 1.0);
cairo_pattern_add_color_stop_rgb (pattern, 1.0, 1.0, 0.0, 1.0);
g_clear_pointer (&demo->path, gsk_path_unref);
cairo_set_source (cr, pattern);
cairo_fill_preserve (cr);
layout = gtk_widget_create_pango_layout (GTK_WIDGET (demo), demo->text);
pango_layout_set_font_description (layout, demo->desc);
cairo_pattern_destroy (pattern);
builder = gsk_path_builder_new ();
gsk_path_builder_add_layout (builder, layout);
demo->path = gsk_path_builder_free_to_path (builder);
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
cairo_set_line_width (cr, 0.5);
cairo_stroke (cr);
gtk_widget_queue_draw (GTK_WIDGET (demo));
}
cairo_restore (cr);
static void
text_mask_demo_init (TextMaskDemo *demo)
{
demo->text = g_strdup ("No text. No fun");
demo->desc = pango_font_description_from_string ("Cantarell 20");
update_path (demo);
}
static void
text_mask_demo_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
TextMaskDemo *demo = TEXT_MASK_DEMO (widget);
float width, height;
GskColorStop stops[4];
GskStroke *stroke;
gdk_rgba_parse (&stops[0].color, "red");
gdk_rgba_parse (&stops[1].color, "green");
gdk_rgba_parse (&stops[2].color, "yellow");
gdk_rgba_parse (&stops[3].color, "blue");
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
stops[0].offset = 0;
stops[1].offset = 0.25;
stops[2].offset = 0.50;
stops[3].offset = 0.75;
gtk_snapshot_push_fill (snapshot, demo->path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, height),
stops, 4);
gtk_snapshot_pop (snapshot);
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, demo->path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot,
&(GdkRGBA){ 0, 0, 0, 1 },
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
void
text_mask_demo_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum_size,
int *natural_size,
int *minimum_baseline,
int *natural_baseline)
{
TextMaskDemo *demo = TEXT_MASK_DEMO (widget);
graphene_rect_t rect;
gsk_path_get_bounds (demo->path, &rect);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum_size = *natural_size = rect.size.width;
else
*minimum_size = *natural_size = rect.size.height;
}
static void
text_mask_demo_finalize (GObject *object)
{
TextMaskDemo *demo = TEXT_MASK_DEMO (object);
g_free (demo->text);
pango_font_description_free (demo->desc);
gsk_path_unref (demo->path);
G_OBJECT_CLASS (text_mask_demo_parent_class)->finalize (object);
}
static void
text_mask_demo_class_init (TextMaskDemoClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->finalize = text_mask_demo_finalize;
widget_class->snapshot = text_mask_demo_snapshot;
widget_class->measure = text_mask_demo_measure;
}
static GtkWidget *
text_mask_demo_new (void)
{
return g_object_new (text_mask_demo_get_type (), NULL);
}
static void
text_mask_demo_set_text (TextMaskDemo *demo,
const char *text)
{
g_free (demo->text);
demo->text = g_strdup (text);
update_path (demo);
}
static void
text_mask_demo_set_font (TextMaskDemo *demo,
PangoFontDescription *desc)
{
pango_font_description_free (demo->desc);
demo->desc = pango_font_description_copy (desc);
update_path (demo);
}
GtkWidget *
do_textmask (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
static GtkWidget *da;
static GtkWidget *demo;
if (!window)
{
PangoFontDescription *desc;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_widget_set_size_request (window, 400, 240);
gtk_window_set_title (GTK_WINDOW (window), "Text Mask");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
da = gtk_drawing_area_new ();
demo = text_mask_demo_new ();
text_mask_demo_set_text (TEXT_MASK_DEMO (demo), "Pango power!\nPango power!\nPango power!");
desc = pango_font_description_from_string ("Sans Bold 34");
text_mask_demo_set_font (TEXT_MASK_DEMO (demo), desc);
pango_font_description_free (desc);
gtk_window_set_child (GTK_WINDOW (window), da);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_text, NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), demo);
}
if (!gtk_widget_get_visible (window))