2 * Copyright © 2006 Red Hat, Inc.
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.
15 * RED HAT, INC. 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.
23 * Author: Kristian Høgsberg <krh@redhat.com>
32 #if CAIRO_HAS_PS_SURFACE
36 #if CAIRO_HAS_PDF_SURFACE
37 #include <cairo-pdf.h>
40 #if CAIRO_HAS_SVG_SURFACE
41 #include <cairo-svg.h>
44 #include "cairo-test.h"
46 /* The main test suite doesn't test the *_create_for_stream
47 * constructors for the PDF, PS and SVG surface, so we do that here.
48 * We draw to an in-memory buffer using the stream constructor and
49 * compare the output to the contents of a file writting using the
53 #define MAX_OUTPUT_SIZE 4096
55 #define WIDTH_IN_INCHES 3
56 #define HEIGHT_IN_INCHES 3
57 #define WIDTH_IN_POINTS (WIDTH_IN_INCHES * 72.0)
58 #define HEIGHT_IN_POINTS (HEIGHT_IN_INCHES * 72.0)
60 static cairo_test_status_t
61 draw (cairo_t
*cr
, int width
, int height
)
63 /* Just draw a rectangle. */
65 cairo_rectangle (cr
, width
/ 10., height
/10.,
66 width
- 2 * width
/ 10.,
67 height
- 2 * height
/10.);
72 return CAIRO_TEST_SUCCESS
;
76 draw_to (cairo_surface_t
*surface
)
80 cr
= cairo_create (surface
);
82 draw (cr
, WIDTH_IN_POINTS
, HEIGHT_IN_POINTS
);
87 typedef struct _write_closure
{
88 const cairo_test_context_t
*ctx
;
89 char buffer
[MAX_OUTPUT_SIZE
];
91 cairo_test_status_t status
;
95 bad_write (void *closure
,
96 const unsigned char *data
,
99 return CAIRO_STATUS_WRITE_ERROR
;
102 static cairo_status_t
103 test_write (void *closure
,
104 const unsigned char *data
,
107 write_closure_t
*wc
= closure
;
109 if (wc
->index
+ length
>= sizeof wc
->buffer
) {
110 cairo_test_log (wc
->ctx
, "Error: out of bounds in write callback\n");
111 wc
->status
= CAIRO_TEST_FAILURE
;
112 return CAIRO_STATUS_SUCCESS
;
115 memcpy (&wc
->buffer
[wc
->index
], data
, length
);
118 return CAIRO_STATUS_SUCCESS
;
122 typedef cairo_surface_t
*
123 (*file_constructor_t
) (const char *filename
,
124 double width_in_points
,
125 double height_in_points
);
127 typedef cairo_surface_t
*
128 (*stream_constructor_t
) (cairo_write_func_t write_func
,
130 double width_in_points
,
131 double height_in_points
);
133 static cairo_test_status_t
134 test_surface (const cairo_test_context_t
*ctx
,
136 const char *filename
,
137 file_constructor_t file_constructor
,
138 stream_constructor_t stream_constructor
)
140 cairo_surface_t
*surface
;
142 char file_contents
[MAX_OUTPUT_SIZE
];
143 cairo_status_t status
;
146 /* test propagation of user errors */
147 surface
= stream_constructor (bad_write
, &wc
,
148 WIDTH_IN_POINTS
, HEIGHT_IN_POINTS
);
150 status
= cairo_surface_status (surface
);
153 "%s: Failed to create surface for stream.\n",
155 return CAIRO_TEST_FAILURE
;
160 cairo_surface_finish (surface
);
161 status
= cairo_surface_status (surface
);
162 cairo_surface_destroy (surface
);
164 if (status
!= CAIRO_STATUS_WRITE_ERROR
) {
166 "%s: Error: expected \"write error\", but received \"%s\".\n",
167 backend
, cairo_status_to_string (status
));
168 return CAIRO_TEST_FAILURE
;
171 /* construct the real surface */
173 wc
.status
= CAIRO_TEST_SUCCESS
;
176 surface
= stream_constructor (test_write
, &wc
,
177 WIDTH_IN_POINTS
, HEIGHT_IN_POINTS
);
179 status
= cairo_surface_status (surface
);
182 "%s: Failed to create surface for stream.\n", backend
);
183 return CAIRO_TEST_FAILURE
;
188 cairo_surface_destroy (surface
);
190 if (wc
.status
!= CAIRO_TEST_SUCCESS
) {
191 /* Error already reported. */
195 surface
= file_constructor (filename
,
196 WIDTH_IN_POINTS
, HEIGHT_IN_POINTS
);
198 status
= cairo_surface_status (surface
);
200 cairo_test_log (ctx
, "%s: Failed to create surface for file %s: %s.\n",
201 backend
, filename
, cairo_status_to_string (status
));
202 return CAIRO_TEST_FAILURE
;
207 cairo_surface_destroy (surface
);
209 fp
= fopen (filename
, "r");
211 cairo_test_log (ctx
, "%s: Failed to open %s for reading: %s.\n",
212 backend
, filename
, strerror (errno
));
213 return CAIRO_TEST_FAILURE
;
216 if (fread (file_contents
, 1, wc
.index
, fp
) != wc
.index
) {
217 cairo_test_log (ctx
, "%s: Failed to read %s: %s.\n",
218 backend
, filename
, strerror (errno
));
220 return CAIRO_TEST_FAILURE
;
223 if (memcmp (file_contents
, wc
.buffer
, wc
.index
) != 0) {
224 cairo_test_log (ctx
, "%s: Stream based output differ from file output for %s.\n",
227 return CAIRO_TEST_FAILURE
;
232 return CAIRO_TEST_SUCCESS
;
238 cairo_test_context_t ctx
;
239 cairo_test_status_t status
= CAIRO_TEST_UNTESTED
;
240 cairo_test_status_t test_status
;
241 const char test_name
[] = "create-for-stream";
243 cairo_test_init (&ctx
, test_name
);
245 #if CAIRO_HAS_PS_SURFACE
246 if (cairo_test_is_target_enabled (&ctx
, "ps2") ||
247 cairo_test_is_target_enabled (&ctx
, "ps3"))
249 if (status
== CAIRO_TEST_UNTESTED
)
250 status
= CAIRO_TEST_SUCCESS
;
252 test_status
= test_surface (&ctx
, "ps", "create-for-stream.ps",
253 cairo_ps_surface_create
,
254 cairo_ps_surface_create_for_stream
);
255 cairo_test_log (&ctx
, "TEST: %s TARGET: %s RESULT: %s\n",
257 test_status
? "FAIL" : "PASS");
258 if (status
== CAIRO_TEST_SUCCESS
)
259 status
= test_status
;
263 #if CAIRO_HAS_PDF_SURFACE
264 if (cairo_test_is_target_enabled (&ctx
, "pdf")) {
265 if (status
== CAIRO_TEST_UNTESTED
)
266 status
= CAIRO_TEST_SUCCESS
;
268 test_status
= test_surface (&ctx
, "pdf", "create-for-stream.pdf",
269 cairo_pdf_surface_create
,
270 cairo_pdf_surface_create_for_stream
);
271 cairo_test_log (&ctx
, "TEST: %s TARGET: %s RESULT: %s\n",
273 test_status
? "FAIL" : "PASS");
274 if (status
== CAIRO_TEST_SUCCESS
)
275 status
= test_status
;
279 #if CAIRO_HAS_SVG_SURFACE
280 if (cairo_test_is_target_enabled (&ctx
, "svg11") ||
281 cairo_test_is_target_enabled (&ctx
, "svg12"))
283 if (status
== CAIRO_TEST_UNTESTED
)
284 status
= CAIRO_TEST_SUCCESS
;
286 test_status
= test_surface (&ctx
, "svg", "create-for-stream.svg",
287 cairo_svg_surface_create
,
288 cairo_svg_surface_create_for_stream
);
289 cairo_test_log (&ctx
, "TEST: %s TARGET: %s RESULT: %s\n",
291 test_status
? "FAIL" : "PASS");
292 if (status
== CAIRO_TEST_SUCCESS
)
293 status
= test_status
;
297 cairo_test_fini (&ctx
);