summaryrefslogtreecommitdiff
path: root/test/mask.c
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2005-05-02 11:01:18 +0000
committerOwen Taylor <otaylor@redhat.com>2005-05-02 11:01:18 +0000
commit79b2a79f2d9ba8dbef44d04656fa84d83836ac6c (patch)
tree4e905226d89f28bfe18bcef83c365e73ff5dcd8d /test/mask.c
parent0c40f66c04bffa1847d37cf9c64e48db9e76f51f (diff)
src/cairo.[ch] src/cairo-gstate.c: Add cairo_mask() and cairo_mask_surface().
test/maks.c tests/Makefile.am tests/mask-ref.png: Add a comprehensive tests for cairo_mask(). Updated
Diffstat (limited to 'test/mask.c')
-rw-r--r--test/mask.c241
1 files changed, 241 insertions, 0 deletions
diff --git a/test/mask.c b/test/mask.c
new file mode 100644
index 00000000..20547b02
--- /dev/null
+++ b/test/mask.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Owen Taylor <otaylor@redhat.com>
+ * Kristian Høgsberg <krh@redhat.com>
+ */
+
+#include <math.h>
+#include "cairo-test.h"
+#include <stdio.h>
+
+#define WIDTH 64
+#define HEIGHT 64
+#define PAD 10
+
+const char png_filename[] = "romedalen.png";
+
+static void
+set_solid_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_set_source_rgb (cr, 0, 0, 0.6);
+}
+
+static void
+set_translucent_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_set_source_rgba (cr, 0, 0, 0.6, 0.5);
+}
+
+static void
+set_gradient_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern =
+ cairo_pattern_create_linear (x, y, x + WIDTH, y + HEIGHT);
+ cairo_pattern_add_color_stop (pattern, 0, 1, 1, 1, 1);
+ cairo_pattern_add_color_stop (pattern, 1, 0, 0, 0.4, 1);
+ cairo_set_pattern (cr, pattern);
+}
+
+static void
+set_image_pattern (cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern = cairo_test_create_png_pattern (cr, png_filename);
+ cairo_set_pattern (cr, pattern);
+}
+
+static void
+mask_polygon (cairo_t *cr, int x, int y)
+{
+ cairo_surface_t *mask_surface;
+ cairo_t *cr2;
+
+ mask_surface = cairo_surface_create_similar (cairo_get_target_surface (cr),
+ CAIRO_FORMAT_A8,
+ WIDTH, HEIGHT);
+ cr2 = cairo_create ();
+ cairo_set_target_surface (cr2, mask_surface);
+
+ cairo_save (cr2);
+ cairo_set_source_rgba (cr2, 0, 0, 0, 0); /* transparent */
+ cairo_set_operator (cr2, CAIRO_OPERATOR_SRC);
+ cairo_paint (cr2);
+ cairo_restore (cr2);
+
+ cairo_set_source_rgb (cr2, 1, 1, 1); /* white */
+
+ cairo_new_path (cr2);
+ cairo_move_to (cr2, 0, 0);
+ cairo_line_to (cr2, 0, HEIGHT);
+ cairo_line_to (cr2, WIDTH / 2, 3 * HEIGHT / 4);
+ cairo_line_to (cr2, WIDTH, HEIGHT);
+ cairo_line_to (cr2, WIDTH, 0);
+ cairo_line_to (cr2, WIDTH / 2, HEIGHT / 4);
+ cairo_close_path (cr2);
+ cairo_fill (cr2);
+
+ cairo_destroy (cr2);
+
+ cairo_mask_surface (cr, mask_surface, x, y);
+
+ cairo_surface_destroy (mask_surface);
+}
+
+static void
+mask_gradient (cairo_t *cr, int x, int y)
+{
+ cairo_pattern_t *pattern;
+
+ pattern = cairo_pattern_create_linear (x, y,
+ x + WIDTH, y + HEIGHT);
+
+ cairo_pattern_add_color_stop_rgba (pattern,
+ 0,
+ 1, 1, 1, 1);
+ cairo_pattern_add_color_stop_rgba (pattern,
+ 1,
+ 1, 1, 1, 0);
+
+ cairo_mask (cr, pattern);
+
+ cairo_pattern_destroy (pattern);
+}
+
+static void
+clip_none (cairo_t *cr, int x, int y)
+{
+}
+
+static void
+clip_rects (cairo_t *cr, int x, int y)
+{
+ int height = HEIGHT / 3;
+
+ cairo_new_path (cr);
+ cairo_rectangle (cr, x, y, WIDTH, height);
+ cairo_rectangle (cr, x, y + 2 * height, WIDTH, height);
+ cairo_clip (cr);
+}
+
+static void
+clip_circle (cairo_t *cr, int x, int y)
+{
+ cairo_new_path (cr);
+ cairo_arc (cr, x + WIDTH / 2, y + HEIGHT / 2,
+ WIDTH / 2, 0, 2 * M_PI);
+ cairo_clip (cr);
+ cairo_new_path (cr);
+}
+
+static void (*pattern_funcs[])(cairo_t *cr, int x, int y) = {
+ set_solid_pattern,
+ set_translucent_pattern,
+ set_gradient_pattern,
+ set_image_pattern,
+};
+
+static void (*mask_funcs[])(cairo_t *cr, int x, int y) = {
+ mask_gradient,
+ mask_polygon,
+};
+
+static void (*clip_funcs[])(cairo_t *cr, int x, int y) = {
+ clip_none,
+ clip_rects,
+ clip_circle,
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+#define IMAGE_WIDTH (ARRAY_SIZE (pattern_funcs) * (WIDTH + PAD) + PAD)
+#define IMAGE_HEIGHT (ARRAY_SIZE (mask_funcs) * ARRAY_SIZE (clip_funcs) * (HEIGHT + PAD) + PAD)
+
+static cairo_test_t test = {
+ "mask",
+ "Tests of cairo_mask",
+ IMAGE_WIDTH, IMAGE_HEIGHT
+};
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *tmp_surface;
+ cairo_pattern_t *tmp_pattern;
+ int i, j, k;
+ cairo_t *cr2;
+
+ /* Some of our drawing is unbounded, so we draw each test to
+ * a temporary surface and copy over.
+ */
+ tmp_surface = cairo_surface_create_similar (cairo_get_target_surface (cr),
+ CAIRO_FORMAT_ARGB32,
+ IMAGE_WIDTH, IMAGE_HEIGHT);
+ cr2 = cairo_create ();
+ cairo_set_target_surface (cr2, tmp_surface);
+
+ tmp_pattern = cairo_pattern_create_for_surface (tmp_surface);
+ cairo_set_source (cr, tmp_pattern);
+
+ for (k = 0; k < ARRAY_SIZE (clip_funcs); k++) {
+ for (j = 0; j < ARRAY_SIZE (mask_funcs); j++) {
+ for (i = 0; i < ARRAY_SIZE (pattern_funcs); i++) {
+ int x = i * (WIDTH + PAD) + PAD;
+ int y = (ARRAY_SIZE (mask_funcs) * k + j) * (HEIGHT + PAD) + PAD;
+
+ /* Clear area we are going to be drawing onto */
+ cairo_save (cr2);
+ cairo_set_source_rgba (cr2, 0, 0, 0, 0); /* transparent */
+ cairo_set_operator (cr2, CAIRO_OPERATOR_SRC);
+ cairo_rectangle (cr2, x, y, WIDTH, HEIGHT);
+ cairo_fill (cr2);
+ cairo_restore (cr2);
+
+ /* draw */
+ cairo_save (cr2);
+
+ clip_funcs[k] (cr2, x, y);
+ pattern_funcs[i] (cr2, x, y);
+ mask_funcs[j] (cr2, x, y);
+
+ cairo_restore (cr2);
+
+ /* Copy back to the main pixmap */
+ cairo_rectangle (cr, x, y, WIDTH, HEIGHT);
+ cairo_fill (cr);
+ }
+ }
+ }
+
+ cairo_destroy (cr2);
+ cairo_surface_destroy (tmp_surface);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+int
+main (void)
+{
+ return cairo_test (&test, draw);
+}