[gtk/path-ops: 2/4] glyphs: Test boolean ops
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/path-ops: 2/4] glyphs: Test boolean ops
- Date: Fri, 25 Mar 2022 16:43:55 +0000 (UTC)
commit 2ea06be26894a8c37065e90549591532e4b53a24
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Mar 22 23:21:58 2022 -0400
glyphs: Test boolean ops
tests/glyphs.c | 177 +++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 134 insertions(+), 43 deletions(-)
---
diff --git a/tests/glyphs.c b/tests/glyphs.c
index 03d87cbaa1..af5b6fcf21 100644
--- a/tests/glyphs.c
+++ b/tests/glyphs.c
@@ -1,4 +1,5 @@
#include <gtk/gtk.h>
+#include <gsk/gskcurveprivate.h>
#define DEMO_TYPE_WIDGET (demo_widget_get_type ())
G_DECLARE_FINAL_TYPE (DemoWidget, demo_widget, DEMO, WIDGET, GtkWidget)
@@ -6,7 +7,8 @@ G_DECLARE_FINAL_TYPE (DemoWidget, demo_widget, DEMO, WIDGET, GtkWidget)
struct _DemoWidget
{
GtkWidget parent_instance;
- GskPath *orig_path;
+ GskPath *orig_path1;
+ GskPath *orig_path2;
GskPath *path;
GskPath *control_path;
graphene_point_t point;
@@ -20,6 +22,7 @@ struct _DemoWidget
GskFillRule fill_rule;
gboolean do_fill;
gboolean do_outline;
+ int operation;
gboolean show_points;
gboolean show_controls;
gboolean show_bounding_box;
@@ -29,7 +32,10 @@ struct _DemoWidget
double zoom;
char *font_file;
- gunichar ch;
+ char *text;
+
+ GskPath *boundary;
+ GskPath *interior;
};
struct _DemoWidgetClass
@@ -48,22 +54,30 @@ demo_widget_init (DemoWidget *self)
gtk_widget_set_valign (self->label, GTK_ALIGN_START);
self->do_outline = TRUE;
self->font_file = g_strdup ("/usr/share/fonts/cantarell/Cantarell-VF.otf");
- self->ch = 'e';
+ self->text = g_strdup ("KP");
}
static void
-draw_point (GtkSnapshot *snapshot,
- const graphene_point_t *pt)
+draw_point2 (GtkSnapshot *snapshot,
+ const graphene_point_t *pt,
+ GdkRGBA *color,
+ float size)
{
graphene_rect_t bounds;
- GdkRGBA color = { 1, 0, 0, 1 };
- bounds.origin.x = pt->x - 2;
- bounds.origin.y = pt->y - 2;
- bounds.size.width = 4;
- bounds.size.height = 4;
+ bounds.origin.x = pt->x - size / 2;
+ bounds.origin.y = pt->y - size / 2;
+ bounds.size.width = size;
+ bounds.size.height = size;
+
+ gtk_snapshot_append_color (snapshot, color, &bounds);
+}
- gtk_snapshot_append_color (snapshot, &color, &bounds);
+static void
+draw_point (GtkSnapshot *snapshot,
+ const graphene_point_t *pt)
+{
+ draw_point2 (snapshot, pt, &(GdkRGBA) { 1, 0, 0, 1 }, 4);
}
static gboolean
@@ -114,10 +128,11 @@ point_cb (GskPathOperation op,
switch (op)
{
case GSK_PATH_MOVE:
+ draw_point2 (snapshot, &pts[0], &(GdkRGBA) { 0, 0, 1, 1 }, 8);
break;
case GSK_PATH_CLOSE:
- draw_point (snapshot, &pts[0]);
+ draw_point (snapshot, &pts[1]);
break;
case GSK_PATH_LINE:
@@ -198,6 +213,18 @@ 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)
@@ -274,9 +301,12 @@ demo_widget_dispose (GObject *object)
{
DemoWidget *self = DEMO_WIDGET (object);
+ g_clear_pointer (&self->orig_path1, gsk_path_unref);
+ 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->label, gtk_widget_unparent);
+ g_free (self->text);
g_free (self->font_file);
G_OBJECT_CLASS (demo_widget_parent_class)->dispose (object);
@@ -336,14 +366,46 @@ control_cb (GskPathOperation op,
static void
demo_widget_set_path (DemoWidget *self,
- GskPath *path)
+ GskPath *path1,
+ GskPath *path2)
{
GskPathBuilder *builder;
+ g_clear_pointer (&self->orig_path1, gsk_path_unref);
+ 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);
- self->path = gsk_path_simplify (path);
+ self->orig_path1 = gsk_path_ref (path1);
+ self->orig_path2 = gsk_path_ref (path2);
+ switch (self->operation)
+ {
+ case 0:
+ builder = gsk_path_builder_new ();
+ gsk_path_builder_add_path (builder, path1);
+ gsk_path_builder_add_path (builder, path2);
+ self->path = gsk_path_builder_free_to_path (builder);
+ break;
+ case 1:
+ self->path = gsk_path_simplify (path1);
+ break;
+ case 2:
+ self->path = gsk_path_op (1, path1, path2, &self->boundary, &self->interior);
+ break;
+ case 3:
+ self->path = gsk_path_op (2, path1, path2, &self->boundary, &self->interior);
+ break;
+ case 4:
+ self->path = gsk_path_difference (path1, path2);
+ break;
+ case 5:
+ self->path = gsk_path_symmetric_difference (path1, path2);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
builder = gsk_path_builder_new ();
gsk_path_foreach (self->path, GSK_PATH_FOREACH_ALLOW_CURVE, control_cb, builder);
@@ -406,23 +468,24 @@ close_path (hb_draw_funcs_t *dfuncs,
gsk_path_builder_close (builder);
}
-static void
-init_demo (DemoWidget *demo)
+static GskPath *
+char_to_path (hb_font_t *font,
+ gunichar ch)
{
- hb_blob_t *blob;
- hb_face_t *face;
- hb_font_t *font;
- hb_draw_funcs_t *funcs;
hb_codepoint_t glyph;
- GskPathBuilder *builder;
- GskPath *path;
hb_glyph_extents_t extents;
+ GskPathBuilder *builder;
+ hb_draw_funcs_t *funcs;
builder = gsk_path_builder_new ();
- blob = hb_blob_create_from_file (demo->font_file);
- face = hb_face_create (blob, 0);
- font = hb_font_create (face);
+ hb_font_get_nominal_glyph (font, ch, &glyph);
+ hb_font_get_glyph_extents (font, glyph, &extents);
+
+ glyph_x0 = 10 + extents.x_bearing;
+ glyph_y0 = 10 + extents.y_bearing;
+
+ gsk_path_builder_move_to (builder, extents.x_bearing, - extents.height);
funcs = hb_draw_funcs_create ();
@@ -431,28 +494,36 @@ init_demo (DemoWidget *demo)
hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL);
hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, NULL, NULL);
- hb_font_get_nominal_glyph (font, demo->ch, &glyph);
-
- hb_font_get_glyph_extents (font, glyph, &extents);
+ hb_font_get_glyph_shape (font, glyph, funcs, builder);
- glyph_x0 = 10 + extents.x_bearing;
- glyph_y0 = 10 + extents.y_bearing;
+ hb_draw_funcs_destroy (funcs);
- gsk_path_builder_move_to (builder, extents.x_bearing, - extents.height);
+ return gsk_path_builder_free_to_path (builder);
+}
- hb_font_get_glyph_shape (font, glyph, funcs, builder);
+static void
+init_demo (DemoWidget *demo)
+{
+ hb_blob_t *blob;
+ hb_face_t *face;
+ hb_font_t *font;
+ GskPath *path1, *path2;
- hb_draw_funcs_destroy (funcs);
+ blob = hb_blob_create_from_file (demo->font_file);
+ face = hb_face_create (blob, 0);
+ font = hb_font_create (face);
- hb_font_destroy (font);
- hb_face_destroy (face);
- hb_blob_destroy (blob);
+ path1 = char_to_path (font, g_utf8_get_char (demo->text));
- path = gsk_path_builder_free_to_path (builder);
+ if (g_utf8_next_char (demo->text))
+ path2 = char_to_path (font, g_utf8_get_char (g_utf8_next_char (demo->text)));
+ else
+ path2 = gsk_path_ref (path1);
- demo_widget_set_path (demo, path);
+ demo_widget_set_path (demo, path1, path2);
- gsk_path_unref (path);
+ gsk_path_unref (path1);
+ gsk_path_unref (path2);
demo->zoom = 1;
}
@@ -467,10 +538,10 @@ demo_widget_set_font_file (DemoWidget *demo,
}
static void
-demo_widget_set_char (DemoWidget *demo,
+demo_widget_set_text (DemoWidget *demo,
const char *text)
{
- demo->ch = g_utf8_get_char (text);
+ demo->text = g_strdup (text);
init_demo (demo);
}
@@ -514,6 +585,21 @@ controls_toggled (GtkCheckButton *button,
gtk_widget_queue_draw (GTK_WIDGET (self));
}
+static void
+operation_changed (GtkDropDown *combo,
+ GParamSpec *pspec,
+ DemoWidget *self)
+{
+ GskPath *path1, *path2;
+
+ self->operation = (int)gtk_drop_down_get_selected (combo);
+ path1 = gsk_path_ref (self->orig_path1);
+ path2 = gsk_path_ref (self->orig_path2);
+ demo_widget_set_path (self, path1, path2);
+ gsk_path_unref (path1);
+ gsk_path_unref (path2);
+}
+
static void
outline_toggled (GtkCheckButton *button,
DemoWidget *self)
@@ -577,7 +663,7 @@ static void
activate_entry (GtkEntry *entry,
DemoWidget *demo)
{
- demo_widget_set_char (demo, gtk_editable_get_text (GTK_EDITABLE (entry)));
+ demo_widget_set_text (demo, gtk_editable_get_text (GTK_EDITABLE (entry)));
}
int
@@ -611,10 +697,15 @@ main (int argc, char *argv[])
g_signal_connect (button, "clicked", G_CALLBACK (filechooser_cb), demo);
entry = gtk_entry_new ();
- gtk_editable_set_text (GTK_EDITABLE (entry), "e");
+ gtk_editable_set_text (GTK_EDITABLE (entry), "KP");
+ gtk_editable_set_width_chars (GTK_EDITABLE (entry), 2);
gtk_box_append (GTK_BOX (hbox), entry);
g_signal_connect (entry, "activate", G_CALLBACK (activate_entry), demo);
+ combo = gtk_drop_down_new_from_strings ((const char *[]){ "Original", "Simplified", "Union",
"Intersection", "Difference", "Symmetric Difference", NULL });
+ g_signal_connect (combo, "notify::selected", G_CALLBACK (operation_changed), demo);
+ gtk_box_append (GTK_BOX (hbox), combo);
+
toggle = gtk_check_button_new_with_label ("Outline");
gtk_check_button_set_active (GTK_CHECK_BUTTON (toggle), TRUE);
g_signal_connect (toggle, "toggled", G_CALLBACK (outline_toggled), demo);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]