[gtk/path-ops: 7/8] glyphs: Add a way to debug path reassembly
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/path-ops: 7/8] glyphs: Add a way to debug path reassembly
- Date: Fri, 25 Mar 2022 16:57:19 +0000 (UTC)
commit cdd4a5ac8ace3159c2afc702105621b7a4919d5a
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Mar 25 09:14:17 2022 -0400
glyphs: Add a way to debug path reassembly
Make it possible to step through the reassembled path.
To use it, focus the demo widget, then hit backspace to
remove the outline rendering, then hit space to bring it
back, one segment at ta time.
tests/glyphs.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 168 insertions(+), 22 deletions(-)
---
diff --git a/tests/glyphs.c b/tests/glyphs.c
index af5b6fcf21..10a8c6286c 100644
--- a/tests/glyphs.c
+++ b/tests/glyphs.c
@@ -34,8 +34,8 @@ struct _DemoWidget
char *font_file;
char *text;
- GskPath *boundary;
- GskPath *interior;
+ GskPath *short_path;
+ int short_count;
};
struct _DemoWidgetClass
@@ -45,9 +45,87 @@ struct _DemoWidgetClass
G_DEFINE_TYPE (DemoWidget, demo_widget, GTK_TYPE_WIDGET)
+static int short_count;
+
+static gboolean
+short_cb (GskPathOperation op,
+ const graphene_point_t *pts,
+ gsize n_pts,
+ float weight,
+ gpointer user_data)
+{
+ GskPathBuilder *builder = user_data;
+
+ if (short_count <= 0)
+ return FALSE;
+
+ short_count--;
+
+ switch (op)
+ {
+ case GSK_PATH_MOVE:
+ gsk_path_builder_move_to (builder, pts[0].x, pts[0].y);
+ break;
+ case GSK_PATH_CLOSE:
+ gsk_path_builder_close (builder);
+ break;
+ case GSK_PATH_LINE:
+ gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
+ break;
+ case GSK_PATH_CURVE:
+ gsk_path_builder_curve_to (builder,
+ pts[1].x, pts[1].y,
+ pts[2].x, pts[2].y,
+ pts[3].x, pts[3].y);
+ break;
+ case GSK_PATH_CONIC:
+ default:
+ g_assert_not_reached ();
+ }
+
+ return TRUE;
+}
+
+static void
+update_short_path (DemoWidget *self)
+{
+ GskPathBuilder *builder;
+
+ g_clear_pointer (&self->short_path, gsk_path_unref);
+
+ builder = gsk_path_builder_new ();
+
+ short_count = self->short_count;
+ gsk_path_foreach (self->path, GSK_PATH_FOREACH_ALLOW_CURVE, short_cb, builder);
+ self->short_path = gsk_path_builder_free_to_path (builder);
+
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+static void
+pressed_cb (GtkEventController *controller,
+ guint keyval,
+ guint keycode,
+ GdkModifierType state,
+ gpointer data)
+{
+ DemoWidget *self = (DemoWidget *)gtk_event_controller_get_widget (controller);
+
+ if (keyval == GDK_KEY_BackSpace)
+ self->short_count = 0;
+ else
+ self->short_count++;
+
+ update_short_path (self);
+}
+
static void
demo_widget_init (DemoWidget *self)
{
+ GtkEventController *controller;
+
+ gtk_widget_set_focusable (GTK_WIDGET (self), TRUE);
+
self->label = gtk_label_new ("");
gtk_widget_set_parent (self->label, GTK_WIDGET (self));
gtk_widget_set_halign (self->label, GTK_ALIGN_END);
@@ -55,6 +133,10 @@ demo_widget_init (DemoWidget *self)
self->do_outline = TRUE;
self->font_file = g_strdup ("/usr/share/fonts/cantarell/Cantarell-VF.otf");
self->text = g_strdup ("KP");
+
+ controller = gtk_event_controller_key_new ();
+ g_signal_connect (controller, "key-pressed", G_CALLBACK (pressed_cb), NULL);
+ gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
static void
@@ -184,14 +266,25 @@ demo_widget_snapshot (GtkWidget *widget,
GskStroke *stroke;
stroke = gsk_stroke_new (1.0);
- gtk_snapshot_push_stroke (snapshot, self->path, stroke);
+ gtk_snapshot_push_stroke (snapshot, self->orig_path1, stroke);
+ gtk_snapshot_append_color (snapshot,
+ &(GdkRGBA){ 0, 0, 0, 0.3 },
+ &GRAPHENE_RECT_INIT (0, 0, width, height ));
+ gtk_snapshot_pop (snapshot);
+ gtk_snapshot_push_stroke (snapshot, self->orig_path2, stroke);
+ gtk_snapshot_append_color (snapshot,
+ &(GdkRGBA){ 0, 0, 0, 0.3 },
+ &GRAPHENE_RECT_INIT (0, 0, width, height ));
+ gtk_snapshot_pop (snapshot);
gsk_stroke_free (stroke);
+ stroke = gsk_stroke_new (2.0);
+ gtk_snapshot_push_stroke (snapshot, self->short_path, stroke);
gtk_snapshot_append_color (snapshot,
- &(GdkRGBA){ 0, 0, 0, 1},
+ &(GdkRGBA){ 0, 0, 0, 1.0 },
&GRAPHENE_RECT_INIT (0, 0, width, height ));
-
gtk_snapshot_pop (snapshot);
+ gsk_stroke_free (stroke);
}
if (self->show_controls)
@@ -213,18 +306,6 @@ demo_widget_snapshot (GtkWidget *widget,
else if (self->show_points)
{
gsk_path_foreach (self->path, GSK_PATH_FOREACH_ALLOW_CURVE, point_cb, snapshot);
-
- if (self->boundary && self->interior)
- {
- GskStroke *stroke;
- stroke = gsk_stroke_new (1.0);
- gtk_snapshot_push_stroke (snapshot, self->interior, stroke);
- gtk_snapshot_append_color (snapshot,
- &(GdkRGBA){ 1, 0, 0, 1},
- &GRAPHENE_RECT_INIT (0, 0, width, height ));
- gtk_snapshot_pop (snapshot);
- gsk_stroke_free (stroke);
- }
}
if (self->show_bounding_box)
@@ -375,8 +456,7 @@ demo_widget_set_path (DemoWidget *self,
g_clear_pointer (&self->orig_path2, gsk_path_unref);
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->control_path, gsk_path_unref);
- g_clear_pointer (&self->boundary, gsk_path_unref);
- g_clear_pointer (&self->interior, gsk_path_unref);
+ g_clear_pointer (&self->short_path, gsk_path_unref);
self->orig_path1 = gsk_path_ref (path1);
self->orig_path2 = gsk_path_ref (path2);
@@ -392,10 +472,10 @@ demo_widget_set_path (DemoWidget *self,
self->path = gsk_path_simplify (path1);
break;
case 2:
- self->path = gsk_path_op (1, path1, path2, &self->boundary, &self->interior);
+ self->path = gsk_path_union (path1, path2);
break;
case 3:
- self->path = gsk_path_op (2, path1, path2, &self->boundary, &self->interior);
+ self->path = gsk_path_intersection (path1, path2);
break;
case 4:
self->path = gsk_path_difference (path1, path2);
@@ -413,6 +493,9 @@ demo_widget_set_path (DemoWidget *self,
gsk_path_get_bounds (self->path, &self->bounds);
+ self->short_count = 10000;
+ update_short_path (self);
+
gtk_widget_queue_draw (GTK_WIDGET (self));
}
@@ -666,6 +749,56 @@ activate_entry (GtkEntry *entry,
demo_widget_set_text (demo, gtk_editable_get_text (GTK_EDITABLE (entry)));
}
+static void
+text_changed (GtkTextBuffer *buffer,
+ DemoWidget *demo)
+{
+ GtkTextIter start, end;
+ char *text;
+ char *p;
+ GskPath *path1, *path2;
+
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+
+ p = strstr (text, "\n\n");
+ if (p)
+ {
+ char *text1, *text2;
+
+ g_print ("got two paragraphs\n");
+
+ text1 = g_strndup (text, p - text);
+ text2 = g_strdup (p + 2);
+
+ path1 = gsk_path_parse (text1);
+ path2 = gsk_path_parse (text2);
+
+ if (path1 && path2)
+ g_print ("got two paths\n");
+
+ g_free (text1);
+ g_free (text2);
+ }
+ else
+ {
+ path1 = gsk_path_parse (text);
+ path2 = NULL;
+ }
+
+ g_free (text);
+
+ if (!path1)
+ path1 = gsk_path_parse ("");
+ if (!path2)
+ path2 = gsk_path_ref (path1);
+
+ demo_widget_set_path (demo, path1, path2);
+
+ gsk_path_unref (path1);
+ gsk_path_unref (path2);
+}
+
int
main (int argc, char *argv[])
{
@@ -675,6 +808,9 @@ main (int argc, char *argv[])
GtkWidget *combo, *sw;
GtkWidget *zoom_scale;
GtkWidget *hbox, *entry;
+ GtkWidget *text;
+ GtkWidget *paned;
+ GtkTextBuffer *buffer;
gtk_init ();
@@ -687,9 +823,12 @@ main (int argc, char *argv[])
gtk_widget_set_hexpand (demo, TRUE);
gtk_widget_set_vexpand (demo, TRUE);
sw = gtk_scrolled_window_new ();
- gtk_box_append (GTK_BOX (box), sw);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), demo);
+ paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_paned_set_start_child (GTK_PANED (paned), sw);
+ gtk_box_append (GTK_BOX (box), paned);
+
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
gtk_box_append (GTK_BOX (box), hbox);
button = gtk_button_new_with_label ("Cantarell-VF.otf");
@@ -731,6 +870,13 @@ main (int argc, char *argv[])
g_signal_connect (combo, "notify::selected", G_CALLBACK (fill_rule_changed), demo);
gtk_box_append (GTK_BOX (hbox), combo);
+ sw = gtk_scrolled_window_new ();
+ text = gtk_text_view_new ();
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+ g_signal_connect (buffer, "changed", G_CALLBACK (text_changed), demo);
+ gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), text);
+ gtk_paned_set_end_child (GTK_PANED (paned), sw);
+
init_demo (DEMO_WIDGET (demo));
header = gtk_header_bar_new ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]