[gtk/wip/otte/lottie: 81/86] gtk-demo: Rewrite the text mask demo




commit 43e777d6a4d84e7eecc7da3df297aa0f45eada4d
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Dec 27 01:55:00 2020 -0500

    gtk-demo: Rewrite the text mask demo
    
    Use GtkSnapshot and GskPath instead of cairo for this.

 demos/gtk-demo/textmask.c | 188 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 153 insertions(+), 35 deletions(-)
---
diff --git a/demos/gtk-demo/textmask.c b/demos/gtk-demo/textmask.c
index 60a81dc270..3678203006 100644
--- a/demos/gtk-demo/textmask.c
+++ b/demos/gtk-demo/textmask.c
@@ -7,68 +7,186 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
+#define TEXT_TYPE_MASK_DEMO (text_mask_demo_get_type ())
+G_DECLARE_FINAL_TYPE (TextMaskDemo, text_mask_demo, TEXT, MASK_DEMO, GtkWidget)
+
+struct _TextMaskDemo
+{
+  GtkWidget parent_instance;
+
+  char *text;
+  PangoFontDescription *desc;
+  GskPath *path;
+};
+
+struct _TextMaskDemoClass
+{
+  GtkWidgetClass parent_class;
+};
+
+G_DEFINE_TYPE (TextMaskDemo, text_mask_demo, GTK_TYPE_WIDGET)
+
 static void
-draw_text (GtkDrawingArea *da,
-           cairo_t        *cr,
-           int             width,
-           int             height,
-           gpointer        data)
+update_path (TextMaskDemo *demo)
 {
-  cairo_pattern_t *pattern;
   PangoLayout *layout;
-  PangoFontDescription *desc;
+  GskPathBuilder *builder;
 
-  cairo_save (cr);
+  g_clear_pointer (&demo->path, gsk_path_unref);
 
-  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);
+  layout = gtk_widget_create_pango_layout (GTK_WIDGET (demo), demo->text);
+  pango_layout_set_font_description (layout, demo->desc);
 
-  cairo_move_to (cr, 30, 20);
-  pango_cairo_layout_path (cr, layout);
-  g_object_unref (layout);
+  builder = gsk_path_builder_new ();
+  gsk_path_builder_add_layout (builder, layout);
+  demo->path = gsk_path_builder_free_to_path (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);
+  gtk_widget_queue_draw (GTK_WIDGET (demo));
+}
 
-  cairo_set_source (cr, pattern);
-  cairo_fill_preserve (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);
+}
 
-  cairo_pattern_destroy (pattern);
+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;
 
-  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
-  cairo_set_line_width (cr, 0.5);
-  cairo_stroke (cr);
+  gsk_path_get_bounds (demo->path, &rect);
 
-  cairo_restore (cr);
+  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))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]