[gtk/tests-cleanup: 3/3] tests: Move testcairo into gtk4-demo
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/tests-cleanup: 3/3] tests: Move testcairo into gtk4-demo
- Date: Tue, 12 May 2020 19:45:04 +0000 (UTC)
commit e7bf4a3de81b7526499372c15d825de88c57aa41
Author: Matthias Clasen <mclasen redhat com>
Date: Tue May 12 15:42:37 2020 -0400
tests: Move testcairo into gtk4-demo
Replace the boring checkboard pattern with this
exciting drawing, and save one test binary at the
same time!
demos/gtk-demo/drawingarea.c | 192 +++++++++++++++++++++++++++++--------
tests/meson.build | 1 -
tests/testcairo.c | 223 -------------------------------------------
3 files changed, 153 insertions(+), 263 deletions(-)
---
diff --git a/demos/gtk-demo/drawingarea.c b/demos/gtk-demo/drawingarea.c
index 63e4bd6812..d36b6aa6d2 100644
--- a/demos/gtk-demo/drawingarea.c
+++ b/demos/gtk-demo/drawingarea.c
@@ -125,49 +125,164 @@ drag_end (GtkGestureDrag *gesture,
}
static void
-checkerboard_draw (GtkDrawingArea *da,
- cairo_t *cr,
- int width,
- int height,
- gpointer data)
+oval_path (cairo_t *cr,
+ double xc, double yc,
+ double xr, double yr)
{
- gint i, j, xcount, ycount;
+ cairo_save (cr);
+
+ cairo_translate (cr, xc, yc);
+ cairo_scale (cr, 1.0, yr / xr);
+ cairo_move_to (cr, xr, 0.0);
+ cairo_arc (cr,
+ 0, 0,
+ xr,
+ 0, 2 * G_PI);
+ cairo_close_path (cr);
+
+ cairo_restore (cr);
+}
-#define CHECK_SIZE 10
-#define SPACING 2
+/* Fill the given area with checks in the standard style
+ * for showing compositing effects.
+ *
+ * It would make sense to do this as a repeating surface,
+ * but most implementations of RENDER currently have broken
+ * implementations of repeat + transform, even when the
+ * transform is a translation.
+ */
+static void
+fill_checks (cairo_t *cr,
+ int x, int y,
+ int width, int height)
+{
+ int i, j;
- /* At the start of a draw handler, a clip region has been set on
- * the Cairo context, and the contents have been cleared to the
- * widget's background color. The docs for
- * gdk_surface_begin_paint_region() give more details on how this
- * works.
- */
+#define CHECK_SIZE 16
- xcount = 0;
- i = SPACING;
- while (i < width)
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_set_source_rgb (cr, 0.4, 0.4, 0.4);
+ cairo_fill (cr);
+
+ /* Only works for CHECK_SIZE a power of 2 */
+ j = x & (-CHECK_SIZE);
+
+ for (; j < height; j += CHECK_SIZE)
{
- j = SPACING;
- ycount = xcount % 2; /* start with even/odd depending on row */
- while (j < height)
- {
- if (ycount % 2)
- cairo_set_source_rgb (cr, 0.45777, 0, 0.45777);
- else
- cairo_set_source_rgb (cr, 1, 1, 1);
-
- /* If we're outside the clip, this will do nothing.
- */
+ i = y & (-CHECK_SIZE);
+ for (; i < width; i += CHECK_SIZE)
+ if ((i / CHECK_SIZE + j / CHECK_SIZE) % 2 == 0)
cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE);
- cairo_fill (cr);
+ }
- j += CHECK_SIZE + SPACING;
- ++ycount;
- }
+ cairo_set_source_rgb (cr, 0.7, 0.7, 0.7);
+ cairo_fill (cr);
- i += CHECK_SIZE + SPACING;
- ++xcount;
- }
+#undef CHECK_SIZE
+}
+
+/* Draw a red, green, and blue circle equally spaced inside
+ * the larger circle of radius r at (xc, yc)
+ */
+static void
+draw_3circles (cairo_t *cr,
+ double xc, double yc,
+ double radius,
+ double alpha)
+{
+ double subradius = radius * (2 / 3. - 0.1);
+
+ cairo_set_source_rgba (cr, 1., 0., 0., alpha);
+ oval_path (cr,
+ xc + radius / 3. * cos (G_PI * (0.5)),
+ yc - radius / 3. * sin (G_PI * (0.5)),
+ subradius, subradius);
+ cairo_fill (cr);
+
+ cairo_set_source_rgba (cr, 0., 1., 0., alpha);
+ oval_path (cr,
+ xc + radius / 3. * cos (G_PI * (0.5 + 2/.3)),
+ yc - radius / 3. * sin (G_PI * (0.5 + 2/.3)),
+ subradius, subradius);
+ cairo_fill (cr);
+
+ cairo_set_source_rgba (cr, 0., 0., 1., alpha);
+ oval_path (cr,
+ xc + radius / 3. * cos (G_PI * (0.5 + 4/.3)),
+ yc - radius / 3. * sin (G_PI * (0.5 + 4/.3)),
+ subradius, subradius);
+ cairo_fill (cr);
+}
+
+static void
+groups_draw (GtkDrawingArea *darea,
+ cairo_t *cr,
+ int width,
+ int height,
+ gpointer data)
+{
+ cairo_surface_t *overlay, *punch, *circles;
+ cairo_t *overlay_cr, *punch_cr, *circles_cr;
+
+ /* Fill the background */
+ double radius = 0.5 * (width < height ? width : height) - 10;
+ double xc = width / 2.;
+ double yc = height / 2.;
+
+ overlay = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width, height);
+
+ punch = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width, height);
+
+ circles = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width, height);
+
+ fill_checks (cr, 0, 0, width, height);
+
+ /* Draw a black circle on the overlay
+ */
+ overlay_cr = cairo_create (overlay);
+ cairo_set_source_rgb (overlay_cr, 0., 0., 0.);
+ oval_path (overlay_cr, xc, yc, radius, radius);
+ cairo_fill (overlay_cr);
+
+ /* Draw 3 circles to the punch surface, then cut
+ * that out of the main circle in the overlay
+ */
+ punch_cr = cairo_create (punch);
+ draw_3circles (punch_cr, xc, yc, radius, 1.0);
+ cairo_destroy (punch_cr);
+
+ cairo_set_operator (overlay_cr, CAIRO_OPERATOR_DEST_OUT);
+ cairo_set_source_surface (overlay_cr, punch, 0, 0);
+ cairo_paint (overlay_cr);
+
+ /* Now draw the 3 circles in a subgroup again
+ * at half intensity, and use OperatorAdd to join up
+ * without seams.
+ */
+ circles_cr = cairo_create (circles);
+
+ cairo_set_operator (circles_cr, CAIRO_OPERATOR_OVER);
+ draw_3circles (circles_cr, xc, yc, radius, 0.5);
+ cairo_destroy (circles_cr);
+
+ cairo_set_operator (overlay_cr, CAIRO_OPERATOR_ADD);
+ cairo_set_source_surface (overlay_cr, circles, 0, 0);
+ cairo_paint (overlay_cr);
+
+ cairo_destroy (overlay_cr);
+
+ cairo_set_source_surface (cr, overlay, 0, 0);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (overlay);
+ cairo_surface_destroy (punch);
+ cairo_surface_destroy (circles);
}
static void
@@ -207,12 +322,11 @@ do_drawingarea (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), vbox);
/*
- * Create the checkerboard area
+ * Create the groups area
*/
-
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label),
- "<u>Checkerboard pattern</u>");
+ "<u>Knockout groups</u>");
gtk_box_append (GTK_BOX (vbox), label);
frame = gtk_frame_new (NULL);
@@ -222,7 +336,7 @@ do_drawingarea (GtkWidget *do_widget)
da = gtk_drawing_area_new ();
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
- gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), checkerboard_draw, NULL, NULL);
+ gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), groups_draw, NULL, NULL);
gtk_frame_set_child (GTK_FRAME (frame), da);
/*
diff --git a/tests/meson.build b/tests/meson.build
index a797ff2ed8..7b9d76c732 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -19,7 +19,6 @@ gtk_tests = [
['testbaseline'],
['testbox'],
['testbuttons'],
- ['testcairo'],
['testcalendar'],
['testclipboard2'],
['testcolorchooser'],
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]