Tizen 2.0 Release
[framework/graphics/cairo.git] / test / surface-source.c
1 /*
2  * Copyright © 2008 Chris Wilson
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  * Chris Wilson not be used in advertising or publicity pertaining to
10  * distribution of the software without specific, written prior
11  * permission. Chris Wilson 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  * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL CHRIS WILSON 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  * Author: Chris Wilson <chris@chris-wilson.co.uk>
24  */
25
26 #include "cairo-test.h"
27
28 static cairo_surface_t *create_source_surface (int size);
29
30 /* We use a relatively large source to exercise bug:
31  *   Bug 7360 painting huge surfaces fails
32  *   [https://bugs.freedesktop.org/show_bug.cgi?id=7360]
33  * but still keep the resultant image small for reasonably quick checking.
34  */
35 #define SOURCE_SIZE 2000
36 #define INTER_SIZE 512
37 #define SIZE 96
38
39 static void
40 draw_pattern (cairo_surface_t **surface_inout, int surface_size)
41 {
42     cairo_t *cr;
43     int mid = surface_size/2;
44
45     cr = cairo_create (*surface_inout);
46     cairo_surface_destroy (*surface_inout);
47
48     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
49     cairo_set_source_rgba (cr, 0, 0, 0, 0);
50     cairo_paint (cr);
51
52     cairo_rectangle (cr, 0, 0, surface_size, surface_size);
53     cairo_rectangle (cr, mid - SIZE/4, mid + SIZE/4, SIZE/2, -SIZE/2);
54     cairo_clip (cr);
55
56     /* outside squares -> opaque */
57     cairo_set_source_rgb (cr, 1, 1, 1);
58     cairo_rectangle (cr,
59                      0, 0,
60                      surface_size / 2, surface_size / 2);
61     cairo_fill (cr);
62     cairo_set_source_rgb (cr, 1, 0, 0);
63     cairo_rectangle (cr,
64                      surface_size / 2, 0,
65                      surface_size / 2, surface_size / 2);
66     cairo_fill (cr);
67     cairo_set_source_rgb (cr, 0, 1, 0);
68     cairo_rectangle (cr,
69                      0, surface_size / 2,
70                      surface_size / 2, surface_size / 2);
71     cairo_fill (cr);
72     cairo_set_source_rgb (cr, 0, 0, 1);
73     cairo_rectangle (cr,
74                      surface_size / 2, surface_size / 2,
75                      surface_size / 2, surface_size / 2);
76     cairo_fill (cr);
77
78     cairo_reset_clip (cr);
79     cairo_rectangle (cr, mid - SIZE/4, mid - SIZE/4, SIZE/2, SIZE/2);
80     cairo_clip (cr);
81
82     /* inside squares -> translucent */
83     cairo_set_source_rgba (cr, 0, 0, 1, .5);
84     cairo_rectangle (cr,
85                      0, 0,
86                      surface_size / 2, surface_size / 2);
87     cairo_fill (cr);
88     cairo_set_source_rgba (cr, 0, 1, 0, .5);
89     cairo_rectangle (cr,
90                      surface_size / 2, 0,
91                      surface_size / 2, surface_size / 2);
92     cairo_fill (cr);
93     cairo_set_source_rgba (cr, 1, 0, 0, .5);
94     cairo_rectangle (cr,
95                      0, surface_size / 2,
96                      surface_size / 2, surface_size / 2);
97     cairo_fill (cr);
98     cairo_set_source_rgba (cr, 1, 1, 1, .5);
99     cairo_rectangle (cr,
100                      surface_size / 2, surface_size / 2,
101                      surface_size / 2, surface_size / 2);
102     cairo_fill (cr);
103
104
105     *surface_inout = cairo_surface_reference (cairo_get_target (cr));
106     cairo_destroy (cr);
107 }
108
109 static cairo_test_status_t
110 draw (cairo_t *cr, int width, int height)
111 {
112     cairo_surface_t *surface;
113     cairo_surface_t *similar;
114     cairo_status_t status;
115     cairo_t *cr2;
116
117     cairo_set_source_rgb (cr, 0, 0, 0);
118     cairo_paint (cr);
119
120     surface = create_source_surface (SOURCE_SIZE);
121     if (surface == NULL) /* can't create the source so skip the test */
122         return CAIRO_TEST_UNTESTED;
123
124     draw_pattern (&surface, SOURCE_SIZE);
125
126     /* copy a subregion to a smaller intermediate surface */
127     similar = cairo_surface_create_similar (surface,
128                                             CAIRO_CONTENT_COLOR_ALPHA,
129                                             INTER_SIZE, INTER_SIZE);
130     cr2 = cairo_create (similar);
131     cairo_surface_destroy (similar);
132     cairo_set_source_surface (cr2, surface,
133                               (INTER_SIZE - SOURCE_SIZE)/2,
134                               (INTER_SIZE - SOURCE_SIZE)/2);
135     cairo_paint (cr2);
136
137     /* and then paint onto a small surface for checking */
138     cairo_set_source_surface (cr, cairo_get_target (cr2),
139                               (width - INTER_SIZE)/2,
140                               (height - INTER_SIZE)/2);
141     cairo_destroy (cr2);
142     cairo_rectangle (cr, 16, 16, 64, 64);
143     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
144     cairo_fill (cr);
145
146     /* destroy the surface last, as this triggers XCloseDisplay */
147     cairo_surface_finish (surface);
148     status = cairo_surface_status (surface);
149     cairo_surface_destroy (surface);
150
151     return cairo_test_status_from_status (cairo_test_get_context (cr),
152                                           status);
153 }
154
155 static cairo_test_status_t
156 preamble (cairo_test_context_t *ctx)
157 {
158     cairo_surface_t *surface;
159     cairo_status_t status;
160
161     surface = create_source_surface (SOURCE_SIZE);
162     if (surface == NULL) /* can't create the source so skip the test */
163         return CAIRO_TEST_UNTESTED;
164
165     cairo_surface_finish (surface);
166     status = cairo_surface_status (surface);
167     cairo_surface_destroy (surface);
168
169     return cairo_test_status_from_status (ctx, status);
170 }