84b323a050165b3f3818c859de9ef5f04e71b9d9
[platform/core/graphics/cairo.git] / test / in-fill-trapezoid.c
1 /*
2  * Copyright © 2008 Chris Wilson
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * Author: Chris Wilson <chris@chris-wilson.co.uk>
25  */
26
27 #include "cairo-test.h"
28
29 static cairo_test_status_t
30 preamble (cairo_test_context_t *ctx)
31 {
32     cairo_test_status_t ret = CAIRO_TEST_SUCCESS;
33     cairo_surface_t *surface;
34     cairo_t *cr;
35
36     surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
37     cr = cairo_create (surface);
38     cairo_surface_destroy (surface);
39
40     cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
41
42     /* simple rectangle */
43     cairo_new_path (cr);
44     cairo_rectangle (cr, -10, -10, 20, 20);
45     if (! cairo_in_fill (cr, 0, 0)) {
46         cairo_test_log (ctx, "Error: Failed to find point inside rectangle\n");
47         ret = CAIRO_TEST_FAILURE;
48     }
49
50     /* rectangular boundary tests */
51     if (! cairo_in_fill (cr, -10, -10)) {
52         cairo_test_log (ctx, "Error: Failed to find top-left vertex inside rectangle\n");
53         ret = CAIRO_TEST_FAILURE;
54     }
55     if (! cairo_in_fill (cr, -10, 10)) {
56         cairo_test_log (ctx, "Error: Failed to find bottom-left vertex inside rectangle\n");
57         ret = CAIRO_TEST_FAILURE;
58     }
59     if (! cairo_in_fill (cr, 10, -10)) {
60         cairo_test_log (ctx, "Error: Failed to find top-right vertex inside rectangle\n");
61         ret = CAIRO_TEST_FAILURE;
62     }
63     if (! cairo_in_fill (cr, 10, 10)) {
64         cairo_test_log (ctx, "Error: Failed to find bottom-right vertex inside rectangle\n");
65         ret = CAIRO_TEST_FAILURE;
66     }
67     if (! cairo_in_fill (cr, -10, 0)) {
68         cairo_test_log (ctx, "Error: Failed to find left edge inside rectangle\n");
69         ret = CAIRO_TEST_FAILURE;
70     }
71     if (! cairo_in_fill (cr, 0, -10)) {
72         cairo_test_log (ctx, "Error: Failed to find top edge inside rectangle\n");
73         ret = CAIRO_TEST_FAILURE;
74     }
75     if (! cairo_in_fill (cr, 10, 0)) {
76         cairo_test_log (ctx, "Error: Failed to find right edge inside rectangle\n");
77         ret = CAIRO_TEST_FAILURE;
78     }
79     if (! cairo_in_fill (cr, 0, 10)) {
80         cairo_test_log (ctx, "Error: Failed to find bottom edge inside rectangle\n");
81         ret = CAIRO_TEST_FAILURE;
82     }
83
84     /* simple circle */
85     cairo_new_path (cr);
86     cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
87     if (! cairo_in_fill (cr, 0, 0)) {
88         cairo_test_log (ctx, "Error: Failed to find point inside circle [even-odd]\n");
89         ret = CAIRO_TEST_FAILURE;
90     }
91
92     /* holey rectangle */
93     cairo_new_path (cr);
94     cairo_rectangle (cr, -10, -10, 20, 20);
95     cairo_rectangle (cr, -5, -5, 10, 10);
96     if (cairo_in_fill (cr, 0, 0)) {
97         cairo_test_log (ctx, "Error: Found an unexpected point inside rectangular eo-hole\n");
98         ret = CAIRO_TEST_FAILURE;
99     }
100
101     /* holey circle */
102     cairo_new_path (cr);
103     cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
104     cairo_arc (cr, 0, 0, 5, 0, 2 * M_PI);
105     if (cairo_in_fill (cr, 0, 0)) {
106         cairo_test_log (ctx, "Error: Found an unexpected point inside circular eo-hole\n");
107         ret = CAIRO_TEST_FAILURE;
108     }
109
110
111     cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
112
113     /* simple rectangle */
114     cairo_new_path (cr);
115     cairo_rectangle (cr, -10, -10, 20, 20);
116     if (! cairo_in_fill (cr, 0, 0)) {
117         cairo_test_log (ctx, "Error: Failed to find point inside rectangle\n");
118         ret = CAIRO_TEST_FAILURE;
119     }
120
121     /* simple circle */
122     cairo_new_path (cr);
123     cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
124     if (! cairo_in_fill (cr, 0, 0)) {
125         cairo_test_log (ctx, "Error: Failed to find point inside circle [nonzero]\n");
126         ret = CAIRO_TEST_FAILURE;
127     }
128
129     /* overlapping circle/rectangle */
130     cairo_new_path (cr);
131     cairo_rectangle (cr, -10, -10, 20, 20);
132     cairo_new_sub_path (cr);
133     cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
134     if (! cairo_in_fill (cr, 0, 0)) {
135         cairo_test_log (ctx, "Error: Failed to find point inside circle+rectangle\n");
136         ret = CAIRO_TEST_FAILURE;
137     }
138
139     /* holey rectangle */
140     cairo_new_path (cr);
141     cairo_rectangle (cr, -10, -10, 20, 20);
142     cairo_rectangle (cr, 5, -5, -10, 10);
143     if (cairo_in_fill (cr, 0, 0)) {
144         cairo_test_log (ctx, "Error: Found an unexpected point inside rectangular non-zero-hole\n");
145         ret = CAIRO_TEST_FAILURE;
146     }
147
148     /* holey circle */
149     cairo_new_path (cr);
150     cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
151     cairo_arc_negative (cr, 0, 0, 5, 0, -2 * M_PI);
152     if (cairo_in_fill (cr, 0, 0)) {
153         cairo_test_log (ctx, "Error: Found an unexpected point inside circular non-zero-hole\n");
154         ret = CAIRO_TEST_FAILURE;
155     }
156
157     /* not a holey circle */
158     cairo_new_path (cr);
159     cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
160     cairo_arc (cr, 0, 0, 5, 0, 2 * M_PI);
161     if (! cairo_in_fill (cr, 0, 0)) {
162         cairo_test_log (ctx, "Error: Failed to find point inside two circles\n");
163         ret = CAIRO_TEST_FAILURE;
164     }
165
166     /* check off-centre */
167     cairo_new_path (cr);
168     cairo_arc (cr, 7.5, 0, 10, 0, 2 * M_PI);
169     cairo_arc_negative (cr, 7.5, 0, 5, 0, -2 * M_PI);
170     if (cairo_in_fill (cr, 7.5, 0)) {
171         cairo_test_log (ctx, "Error: Found an unexpected point inside off-centre-x circular non-zero-hole\n");
172         ret = CAIRO_TEST_FAILURE;
173     }
174     cairo_new_path (cr);
175     cairo_arc (cr, 0, 7.5, 10, 0, 2 * M_PI);
176     cairo_arc_negative (cr, 0, 7.5, 5, 0, -2 * M_PI);
177     if (cairo_in_fill (cr, 0, 7.5)) {
178         cairo_test_log (ctx, "Error: Found an unexpected point inside off-centre-y circular non-zero-hole\n");
179         ret = CAIRO_TEST_FAILURE;
180     }
181     cairo_new_path (cr);
182     cairo_arc (cr, 15, 0, 10, 0, 2 * M_PI);
183     if (! cairo_in_fill (cr, 15, 0)) {
184         cairo_test_log (ctx, "Error: Failed to find point inside off-centre-x circle\n");
185         ret = CAIRO_TEST_FAILURE;
186     }
187     cairo_new_path (cr);
188     cairo_arc (cr, 0, 15, 10, 0, 2 * M_PI);
189     if (! cairo_in_fill (cr, 0, 15)) {
190         cairo_test_log (ctx, "Error: Failed to find point inside off-centre-y circle\n");
191         ret = CAIRO_TEST_FAILURE;
192     }
193
194     /* simple rectangle */
195     cairo_new_path (cr);
196     cairo_rectangle (cr, 10, 0, 5, 5);
197     if (cairo_in_fill (cr, 0, 0)) {
198         cairo_test_log (ctx, "Error: Found an unexpected point outside rectangle\n");
199         ret = CAIRO_TEST_FAILURE;
200     }
201     if (cairo_in_fill (cr, 20, 20)) {
202         cairo_test_log (ctx, "Error: Found an unexpected point outside rectangle\n");
203         ret = CAIRO_TEST_FAILURE;
204     }
205     if (! cairo_in_fill (cr, 12.5, 2.5)) {
206         cairo_test_log (ctx, "Error: Failed to find point inside rectangle\n");
207         ret = CAIRO_TEST_FAILURE;
208     }
209
210     /* off-centre triangle */
211     cairo_new_path (cr);
212     cairo_move_to (cr, 10, 0);
213     cairo_line_to (cr, 15, 5);
214     cairo_line_to (cr, 5, 5);
215     cairo_close_path (cr);
216     if (cairo_in_fill (cr, 0, 0) ||
217         cairo_in_fill (cr, 5, 0) ||
218         cairo_in_fill (cr, 15, 0) ||
219         cairo_in_fill (cr, 20, 0) ||
220         cairo_in_fill (cr, 0, 10) ||
221         cairo_in_fill (cr, 10, 10) ||
222         cairo_in_fill (cr, 20, 10) ||
223         cairo_in_fill (cr, 7, 2.5) ||
224         cairo_in_fill (cr, 13, 2.5))
225     {
226         cairo_test_log (ctx,
227                         "Error: Found an unexpected point outside triangle\n"
228                         "\t(0, 0) -> %s\n"
229                         "\t(5, 0) -> %s\n"
230                         "\t(15, 0) -> %s\n"
231                         "\t(20, 0) -> %s\n"
232                         "\t(0, 10) -> %s\n"
233                         "\t(10, 10) -> %s\n"
234                         "\t(20, 10) -> %s\n"
235                         "\t(7, 2.5) -> %s\n"
236                         "\t(13, 2.5) -> %s\n",
237                         cairo_in_fill (cr, 0, 0) ? "inside" : "outside",
238                         cairo_in_fill (cr, 5, 0) ? "inside" : "outside",
239                         cairo_in_fill (cr, 15, 0) ? "inside" : "outside",
240                         cairo_in_fill (cr, 20, 0) ? "inside" : "outside",
241                         cairo_in_fill (cr, 0, 10) ? "inside" : "outside",
242                         cairo_in_fill (cr, 10, 10) ? "inside" : "outside",
243                         cairo_in_fill (cr, 20, 10) ? "inside" : "outside",
244                         cairo_in_fill (cr, 7, 2.5) ? "inside" : "outside",
245                         cairo_in_fill (cr, 13, 2.5) ? "inside" : "outside");
246         ret = CAIRO_TEST_FAILURE;
247     }
248     if (! cairo_in_fill (cr, 7.5, 2.5) ||
249         ! cairo_in_fill (cr, 12.5, 2.5) ||
250         ! cairo_in_fill (cr, 10, 5))
251     {
252         cairo_test_log (ctx,
253                         "Error: Failed to find point on triangle edge\n"
254                         "\t(7.5, 2.5) -> %s\n"
255                         "\t(12.5, 2.5) -> %s\n"
256                         "\t(10, 5) -> %s\n",
257                         cairo_in_fill (cr, 7.5, 2.5) ? "inside" : "outside",
258                         cairo_in_fill (cr, 12.5, 2.5) ? "inside" : "outside",
259                         cairo_in_fill (cr, 10, 5) ? "inside" : "outside");
260         ret = CAIRO_TEST_FAILURE;
261     }
262     if (! cairo_in_fill (cr, 8, 2.5) ||
263         ! cairo_in_fill (cr, 12, 2.5))
264     {
265         cairo_test_log (ctx, "Error: Failed to find point inside triangle\n");
266         ret = CAIRO_TEST_FAILURE;
267     }
268
269     cairo_destroy (cr);
270
271     return ret;
272 }
273
274 CAIRO_TEST (in_fill_trapezoid,
275             "Test cairo_in_fill",
276             "in, trap", /* keywords */
277             NULL, /* requirements */
278             0, 0,
279             preamble, NULL)