ec708121ea0e9adb5cf10d02af1605e761e2ea81
[platform/core/graphics/cairo.git] / test / a8-mask.c
1 /*
2  * Copyright © Jeff Muizelaar
3  *
4  * Permission to use, copy, modify, distribute, and sell this software
5  * and its documentation for any purpose is hereby granted without
6  * fee, provided that the above copyright notice appear in all copies
7  * and that both that copyright notice and this permission notice
8  * appear in supporting documentation, and that the name of
9  * Red Hat, Inc. not be used in advertising or publicity pertaining to
10  * distribution of the software without specific, written prior
11  * permission. Red Hat, Inc. makes no representations about the
12  * suitability of this software for any purpose.  It is provided "as
13  * is" without express or implied warranty.
14  *
15  * JEFF MUIZELAAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
18  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
21  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Authors: Jeff Muizelaar <jeff@infidigm.net>
24  *          Carl Worth <cworth@cworth.org>
25  */
26
27 #include "cairo-test.h"
28
29 #define MASK_WIDTH 8
30 #define MASK_HEIGHT 8
31
32 static unsigned char mask[MASK_WIDTH * MASK_HEIGHT] = {
33     0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
34     0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
35     0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
36     0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
37     0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
38     0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
39     0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
40     0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0,
41 };
42
43 static cairo_test_status_t
44 check_status (const cairo_test_context_t *ctx,
45               cairo_status_t status,
46               cairo_status_t expected)
47 {
48     if (status == expected)
49         return CAIRO_TEST_SUCCESS;
50
51     cairo_test_log (ctx,
52                     "Error: Expected status value %d (%s), received %d (%s)\n",
53                     expected,
54                     cairo_status_to_string (expected),
55                     status,
56                     cairo_status_to_string (status));
57     return CAIRO_TEST_FAILURE;
58 }
59
60 static cairo_test_status_t
61 test_surface_with_width_and_stride (const cairo_test_context_t *ctx,
62                                     int width, int stride,
63                                     cairo_status_t expected)
64 {
65     cairo_test_status_t status;
66     cairo_surface_t *surface;
67     cairo_t *cr;
68     int len;
69     unsigned char *data;
70
71     cairo_test_log (ctx,
72                     "Creating surface with width %d and stride %d\n",
73                     width, stride);
74
75     len = stride;
76     if (len < 0)
77         len = -len;
78     data = xmalloc (len);
79
80     surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_A8,
81                                                    width, 1, stride);
82     cr = cairo_create (surface);
83
84     cairo_paint (cr);
85
86     status = check_status (ctx, cairo_surface_status (surface), expected);
87     if (status)
88         goto BAIL;
89
90     status = check_status (ctx, cairo_status (cr), expected);
91     if (status)
92         goto BAIL;
93
94   BAIL:
95     cairo_destroy (cr);
96     cairo_surface_destroy (surface);
97     free (data);
98     return status;
99 }
100
101 static cairo_test_status_t
102 draw (cairo_t *cr, int dst_width, int dst_height)
103 {
104     int stride, row;
105     unsigned char *src, *dst, *mask_aligned;
106     cairo_surface_t *surface;
107
108     /* Now test actually drawing through our mask data, allocating and
109      * copying with the proper stride. */
110     stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8,
111                                             MASK_WIDTH);
112
113     mask_aligned = xmalloc (stride * MASK_HEIGHT);
114
115     src = mask;
116     dst = mask_aligned;
117     for (row = 0; row < MASK_HEIGHT; row++) {
118         memcpy (dst, src, MASK_WIDTH);
119         src += MASK_WIDTH;
120         dst += stride;
121     }
122
123     surface = cairo_image_surface_create_for_data (mask_aligned,
124                                                    CAIRO_FORMAT_A8,
125                                                    MASK_WIDTH,
126                                                    MASK_HEIGHT,
127                                                    stride);
128
129     /* Paint background blue */
130     cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
131     cairo_paint (cr);
132
133     /* Then paint red through our mask */
134     cairo_set_source_rgb (cr, 1, 0, 0); /* red */
135     cairo_mask_surface (cr, surface, 0, 0);
136     cairo_surface_destroy (surface);
137
138     free (mask_aligned);
139
140     return CAIRO_TEST_SUCCESS;
141 }
142
143 static cairo_test_status_t
144 preamble (cairo_test_context_t *ctx)
145 {
146     cairo_test_status_t status = CAIRO_TEST_SUCCESS;
147     int test_width;
148
149     for (test_width = 0; test_width < 40; test_width++) {
150         int stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8,
151                                                 test_width);
152         cairo_status_t expected;
153
154         /* First create a surface using the width as the stride,
155          * (most of these should fail).
156          */
157         expected = (stride == test_width) ?
158             CAIRO_STATUS_SUCCESS : CAIRO_STATUS_INVALID_STRIDE;
159
160         status = test_surface_with_width_and_stride (ctx,
161                                                      test_width,
162                                                      test_width,
163                                                      expected);
164         if (status)
165             return status;
166
167         status = test_surface_with_width_and_stride (ctx,
168                                                      test_width,
169                                                      -test_width,
170                                                      expected);
171         if (status)
172             return status;
173
174
175         /* Then create a surface using the correct stride,
176          * (should always succeed).
177          */
178         status = test_surface_with_width_and_stride (ctx,
179                                                      test_width,
180                                                      stride,
181                                                      CAIRO_STATUS_SUCCESS);
182         if (status)
183             return status;
184
185         status = test_surface_with_width_and_stride (ctx,
186                                                      test_width,
187                                                      -stride,
188                                                      CAIRO_STATUS_SUCCESS);
189         if (status)
190             return status;
191     }
192
193     return status;
194 }
195
196 CAIRO_TEST (a8_mask,
197             "test masks of CAIRO_FORMAT_A8",
198             "alpha, mask", /* keywords */
199             NULL, /* requirements */
200             8, 8,
201             preamble, draw)