Opensource Compliance Issue.
[platform/core/graphics/cairo.git] / test / extended-blend.c
1 /*
2  * Copyright © 2005 Red Hat, Inc.
3  * Copyright © 2007 Emmanuel Pacaud
4  * Copyright © 2008 Benjamin Otte
5  *
6  * Permission to use, copy, modify, distribute, and sell this software
7  * and its documentation for any purpose is hereby granted without
8  * fee, provided that the above copyright notice appear in all copies
9  * and that both that copyright notice and this permission notice
10  * appear in supporting documentation, and that the name of
11  * Red Hat, Inc. not be used in advertising or publicity pertaining to
12  * distribution of the software without specific, written prior
13  * permission. Red Hat, Inc. makes no representations about the
14  * suitability of this software for any purpose.  It is provided "as
15  * is" without express or implied warranty.
16  *
17  * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
19  * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
20  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
21  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
23  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24  *
25  * Authors: Owen Taylor <otaylor@redhat.com>
26  *          Kristian Høgsberg <krh@redhat.com>
27  *          Emmanuel Pacaud <emmanuel.pacaud@lapp.in2p3.fr>
28  */
29
30 #include "cairo-test.h"
31 #include <math.h>
32 #include <stdio.h>
33
34 #define STEPS 16
35 #define START_OPERATOR  CAIRO_OPERATOR_MULTIPLY
36 #define STOP_OPERATOR   CAIRO_OPERATOR_HSL_LUMINOSITY
37
38 #define SIZE 5
39 #define COUNT 4
40 #define FULL_WIDTH  ((STEPS + 1) * COUNT - 1)
41 #define FULL_HEIGHT ((COUNT + STOP_OPERATOR - START_OPERATOR) / COUNT) * (STEPS + 1)
42
43 static void
44 set_solid_pattern (cairo_t *cr,
45                    int step,
46                    cairo_bool_t bg,
47                    cairo_bool_t alpha)
48 {
49     double c, a;
50
51     a = ((double) step) / (STEPS - 1);
52     if (alpha) {
53         c = 1;
54     } else {
55         c = a;
56         a = 1;
57     }
58
59     if (bg) /* draw a yellow background fading in using discrete steps */
60         cairo_set_source_rgba (cr, c, c, 0, a);
61     else /* draw a teal foreground pattern fading in using discrete steps */
62         cairo_set_source_rgba (cr, 0, c, c, a);
63 }
64
65 /* expects a STEP*STEP pixel rectangle */
66 static void
67 do_blend_solid (cairo_t *cr, cairo_operator_t op, cairo_bool_t alpha)
68 {
69     int x;
70
71     cairo_save (cr);
72     cairo_scale (cr, SIZE, SIZE);
73
74     /* not using CAIRO_OPERATOR_SOURCE here, it triggers a librsvg bug */
75     cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
76     for (x = 0; x < STEPS; x++) {
77         /* draw the background using discrete steps */
78         set_solid_pattern (cr, x, TRUE, alpha);
79         cairo_rectangle (cr, x, 0, 1, STEPS);
80         cairo_fill (cr);
81     }
82
83     cairo_set_operator (cr, op);
84     for (x = 0; x < STEPS; x++) {
85         /* draw an orthogonal foreground pattern using discrete steps */
86         set_solid_pattern (cr, x, FALSE, alpha);
87         cairo_rectangle (cr, 0, x, STEPS, 1);
88         cairo_fill (cr);
89     }
90
91     cairo_restore (cr);
92 }
93
94 static void
95 create_patterns (cairo_t *cr,
96                  cairo_surface_t **bg,
97                  cairo_surface_t **fg,
98                  cairo_bool_t alpha)
99 {
100     cairo_t *bgcr, *fgcr;
101
102     *bg = cairo_surface_create_similar (cairo_get_target (cr),
103                                         CAIRO_CONTENT_COLOR_ALPHA,
104                                         SIZE * STEPS,
105                                         SIZE * STEPS);
106     *fg = cairo_surface_create_similar (cairo_get_target (cr),
107                                         CAIRO_CONTENT_COLOR_ALPHA,
108                                         SIZE * STEPS,
109                                         SIZE * STEPS);
110
111     bgcr = cairo_create (*bg);
112     fgcr = cairo_create (*fg);
113
114     do_blend_solid (bgcr, CAIRO_OPERATOR_DEST, alpha);
115     do_blend_solid (fgcr, CAIRO_OPERATOR_SOURCE, alpha);
116
117     cairo_destroy (bgcr);
118     cairo_destroy (fgcr);
119 }
120
121 /* expects a STEP*STEP pixel rectangle */
122 static void
123 do_blend (cairo_t *cr, cairo_operator_t op, cairo_bool_t alpha)
124 {
125     cairo_surface_t *bg, *fg;
126
127     create_patterns (cr, &bg, &fg, alpha);
128
129     /* not using CAIRO_OPERATOR_SOURCE here, it triggers a librsvg bug */
130     cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
131     cairo_set_source_surface (cr, bg, 0, 0);
132     cairo_paint (cr);
133
134     cairo_set_operator (cr, op);
135     cairo_set_source_surface (cr, fg, 0, 0);
136     cairo_paint (cr);
137
138     cairo_surface_destroy (fg);
139     cairo_surface_destroy (bg);
140 }
141
142 static void
143 do_blend_mask (cairo_t *cr, cairo_operator_t op, cairo_bool_t alpha)
144 {
145     cairo_surface_t *bg, *fg;
146
147     create_patterns (cr, &bg, &fg, alpha);
148
149     /* not using CAIRO_OPERATOR_SOURCE here, it triggers a librsvg bug */
150     cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
151     cairo_set_source_surface (cr, bg, 0, 0);
152     cairo_paint (cr);
153
154     cairo_set_operator (cr, op);
155     cairo_set_source_surface (cr, fg, 0, 0);
156     cairo_paint_with_alpha (cr, .5);
157
158     cairo_surface_destroy (fg);
159     cairo_surface_destroy (bg);
160 }
161
162 static cairo_test_status_t
163 draw (cairo_t *cr, cairo_bool_t alpha,
164       void (*blend)(cairo_t *, cairo_operator_t, cairo_bool_t))
165 {
166     size_t i = 0;
167     cairo_operator_t op;
168
169     for (op = START_OPERATOR; op <= STOP_OPERATOR; op++, i++) {
170         cairo_save (cr);
171         cairo_translate (cr,
172                 SIZE * (STEPS + 1) * (i % COUNT),
173                 SIZE * (STEPS + 1) * (i / COUNT));
174         blend (cr, op, alpha);
175         cairo_restore (cr);
176     }
177
178     return CAIRO_TEST_SUCCESS;
179 }
180
181 static cairo_test_status_t
182 draw_extended_blend (cairo_t *cr, int width, int height)
183 {
184     return draw (cr, FALSE, do_blend);
185 }
186
187 static cairo_test_status_t
188 draw_extended_blend_alpha (cairo_t *cr, int width, int height)
189 {
190     return draw (cr, TRUE, do_blend);
191 }
192
193 static cairo_test_status_t
194 draw_extended_blend_solid (cairo_t *cr, int width, int height)
195 {
196     return draw (cr, FALSE, do_blend_solid);
197 }
198
199 static cairo_test_status_t
200 draw_extended_blend_solid_alpha (cairo_t *cr, int width, int height)
201 {
202     return draw (cr, TRUE, do_blend_solid);
203 }
204
205 static cairo_test_status_t
206 draw_extended_blend_mask (cairo_t *cr, int width, int height)
207 {
208     return draw (cr, FALSE, do_blend_mask);
209 }
210 static cairo_test_status_t
211 draw_extended_blend_alpha_mask (cairo_t *cr, int width, int height)
212 {
213     return draw (cr, TRUE, do_blend_mask);
214 }
215
216 CAIRO_TEST (extended_blend,
217             "Tests extended blend modes without alpha",
218             "operator", /* keywords */
219             NULL, /* requirements */
220             FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
221             NULL, draw_extended_blend)
222
223 CAIRO_TEST (extended_blend_alpha,
224             "Tests extended blend modes with alpha",
225             "operator", /* keywords */
226             NULL, /* requirements */
227             FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
228             NULL, draw_extended_blend_alpha)
229
230 CAIRO_TEST (extended_blend_mask,
231             "Tests extended blend modes with an alpha mask",
232             "operator,mask", /* keywords */
233             NULL, /* requirements */
234             FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
235             NULL, draw_extended_blend_mask)
236 CAIRO_TEST (extended_blend_alpha_mask,
237             "Tests extended blend modes with an alpha mask",
238             "operator,mask", /* keywords */
239             NULL, /* requirements */
240             FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
241             NULL, draw_extended_blend_alpha_mask)
242
243
244 CAIRO_TEST (extended_blend_solid,
245             "Tests extended blend modes on solid patterns without alpha",
246             "operator", /* keywords */
247             NULL, /* requirements */
248             FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
249             NULL, draw_extended_blend_solid)
250
251 CAIRO_TEST (extended_blend_solid_alpha,
252             "Tests extended blend modes on solid patterns with alpha",
253             "operator", /* keywords */
254             NULL, /* requirements */
255             FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
256             NULL, draw_extended_blend_solid_alpha)