1
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
2
/*
3
 * Copyright 2009 Chris Wilson
4
 * Copyright 2010 Andrea Canciani
5
 *
6
 * Permission is hereby granted, free of charge, to any person
7
 * obtaining a copy of this software and associated documentation
8
 * files (the "Software"), to deal in the Software without
9
 * restriction, including without limitation the rights to use, copy,
10
 * modify, merge, publish, distribute, sublicense, and/or sell copies
11
 * of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be
15
 * included in all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
 * SOFTWARE.
25
 *
26
 * Author: Chris Wilson <chris@chris-wilson.co.uk>
27
 */
28

            
29
#include "cairo-test.h"
30

            
31
#define WIDTH 60
32
#define HEIGHT 60
33

            
34
static void
35
12
stroke (cairo_t *cr)
36
{
37
12
    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
38
12
    cairo_set_source_rgb (cr, 1, 0, 0);
39
12
    cairo_paint (cr);
40

            
41
12
    cairo_set_operator (cr, CAIRO_OPERATOR_IN);
42
12
    cairo_set_source_rgb (cr, 0, 0.7, 0);
43
12
    cairo_arc (cr, 10, 10, 7.5, 0, 2 * M_PI);
44
12
    cairo_move_to (cr, 0, 20);
45
12
    cairo_line_to (cr, 20, 0);
46
12
    cairo_stroke (cr);
47
12
}
48

            
49
static void
50
24
fill (cairo_t *cr)
51
{
52
24
    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
53
24
    cairo_set_source_rgb (cr, 1, 0, 0);
54
24
    cairo_paint (cr);
55

            
56
24
    cairo_set_operator (cr, CAIRO_OPERATOR_IN);
57
24
    cairo_set_source_rgb (cr, 0, 0.7, 0);
58
24
    cairo_new_sub_path (cr);
59
24
    cairo_arc (cr, 10, 10, 8.5, 0, 2 * M_PI);
60
24
    cairo_new_sub_path (cr);
61
24
    cairo_arc_negative (cr, 10, 10, 6.5, 2 * M_PI, 0);
62

            
63
24
    cairo_move_to (cr, -1, 19);
64
24
    cairo_line_to (cr,  1, 21);
65
24
    cairo_line_to (cr, 21,  1);
66
24
    cairo_line_to (cr, 19, -1);
67
24
    cairo_line_to (cr, -1, 19);
68

            
69
24
    cairo_fill (cr);
70
24
}
71

            
72
static void
73
9
clip_simple (cairo_t *cr)
74
{
75
9
    cairo_rectangle (cr, 0, 0, 20, 20);
76
9
    cairo_clip (cr);
77
9
}
78

            
79
static void
80
9
clip_unaligned (cairo_t *cr)
81
{
82
9
    cairo_rectangle (cr, 0.5, 0.5, 20, 20);
83
9
    cairo_clip (cr);
84
9
}
85

            
86
static void
87
9
clip_aligned (cairo_t *cr)
88
{
89
    cairo_fill_rule_t orig_rule;
90

            
91
9
    orig_rule = cairo_get_fill_rule (cr);
92
9
    cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
93
9
    cairo_rectangle (cr, 0, 0, 20, 20);
94
9
    cairo_rectangle (cr, 3, 3, 10, 10);
95
9
    cairo_rectangle (cr, 7, 7, 10, 10);
96
9
    cairo_clip (cr);
97
9
    cairo_set_fill_rule (cr, orig_rule);
98
9
}
99

            
100
static void
101
9
clip_mask (cairo_t *cr)
102
{
103
9
    cairo_arc (cr, 10, 10, 10, 0, 2 * M_PI);
104
9
    cairo_new_sub_path (cr);
105
9
    cairo_arc_negative (cr, 10, 10, 5, 2 * M_PI, 0);
106
9
    cairo_new_sub_path (cr);
107
9
    cairo_arc (cr, 10, 10, 2, 0, 2 * M_PI);
108
9
    cairo_clip (cr);
109
9
}
110

            
111
static void (* const clip_funcs[])(cairo_t *cr) = {
112
    clip_simple,
113
    clip_unaligned,
114
    clip_aligned,
115
    clip_mask
116
};
117

            
118
static double translations[][2] = {
119
    { 10, 10 },
120
    { WIDTH, 0 },
121
    { -WIDTH, HEIGHT },
122
    { WIDTH, 0 }
123
};
124

            
125
static cairo_test_status_t
126
9
draw (cairo_t *cr, void (*shapes)(cairo_t *))
127
{
128
    unsigned int i;
129
9
    cairo_set_source_rgb (cr, 1, 1, 1);
130
9
    cairo_paint (cr);
131

            
132
45
    for (i = 0; i < ARRAY_LENGTH (clip_funcs); i++) {
133
36
	cairo_translate (cr, translations[i][0], translations[i][1]);
134

            
135
36
	cairo_save (cr);
136
36
	cairo_scale (cr, 2, 2);
137
36
	clip_funcs[i] (cr);
138
36
	shapes (cr);
139
36
	cairo_restore (cr);
140
    }
141

            
142
9
    return CAIRO_TEST_SUCCESS;
143
}
144

            
145
static cairo_test_status_t
146
3
draw_stroke (cairo_t *cr, int width, int height)
147
{
148
3
    return draw (cr, stroke);
149
}
150

            
151
static cairo_test_status_t
152
3
draw_fill_nz (cairo_t *cr, int width, int height)
153
{
154
3
    cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
155
3
    return draw (cr, fill);
156
}
157

            
158
static cairo_test_status_t
159
3
draw_fill_eo (cairo_t *cr, int width, int height)
160
{
161
3
    cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
162
3
    return draw (cr, fill);
163
}
164

            
165
1
CAIRO_TEST (clip_stroke_unbounded,
166
	    "Tests unbounded stroke through complex clips.",
167
	    "clip, stroke, unbounded", /* keywords */
168
	    NULL, /* requirements */
169
	    2 * WIDTH, 2 * HEIGHT,
170
	    NULL, draw_stroke)
171

            
172
1
CAIRO_TEST (clip_fill_nz_unbounded,
173
	    "Tests unbounded fill through complex clips (with winding fill rule).",
174
	    "clip, fill, unbounded", /* keywords */
175
	    NULL, /* requirements */
176
	    2 * WIDTH, 2 * HEIGHT,
177
	    NULL, draw_fill_nz)
178

            
179
1
CAIRO_TEST (clip_fill_eo_unbounded,
180
	    "Tests unbounded fill through complex clips (with even-odd fill rule).",
181
	    "clip, fill, unbounded", /* keywords */
182
	    NULL, /* requirements */
183
	    2 * WIDTH, 2 * HEIGHT,
184
	    NULL, draw_fill_eo)