2 * Copyright © 2006 Red Hat, Inc.
3 * Copyright © 2009 Adrian Johnson
4 * Copyright © 2008 Chris Wilson
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.
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.
25 * Author: Carl D. Worth <cworth@cworth.org>
26 * Adrian Johnson <ajohnson@redneon.com>
27 * Chris Wilson <chris@chris-wilson.co.uk>
48 #include "cairo-test.h"
49 #include "buffer-diff.h"
57 /* Reference Bounding Box */
64 _xunlink (const cairo_test_context_t *ctx, const char *pathname)
66 if (unlink (pathname) < 0 && errno != ENOENT) {
67 cairo_test_log (ctx, "Error: Cannot remove %s: %s\n",
68 pathname, strerror (errno));
74 check_result (cairo_test_context_t *ctx,
75 const cairo_boilerplate_target_t *target,
76 const char *test_name,
77 const char *base_name,
78 cairo_surface_t *surface)
84 cairo_surface_t *test_image, *ref_image, *diff_image;
85 buffer_diff_result_t result;
86 cairo_status_t status;
89 /* XXX log target, OUTPUT, REFERENCE, DIFFERENCE for index.html */
91 if (target->finish_surface != NULL) {
92 status = target->finish_surface (surface);
94 cairo_test_log (ctx, "Error: Failed to finish surface: %s\n",
95 cairo_status_to_string (status));
96 cairo_surface_destroy (surface);
101 xasprintf (&png_name, "%s.out.png", base_name);
102 xasprintf (&diff_name, "%s.diff.png", base_name);
104 test_image = target->get_image_surface (surface, 0, WIDTH, HEIGHT);
105 if (cairo_surface_status (test_image)) {
106 cairo_test_log (ctx, "Error: Failed to extract page: %s\n",
107 cairo_status_to_string (cairo_surface_status (test_image)));
108 cairo_surface_destroy (test_image);
114 _xunlink (ctx, png_name);
115 status = cairo_surface_write_to_png (test_image, png_name);
117 cairo_test_log (ctx, "Error: Failed to write output image: %s\n",
118 cairo_status_to_string (status));
119 cairo_surface_destroy (test_image);
125 format = cairo_boilerplate_content_name (target->content);
126 ref_name = cairo_test_reference_filename (ctx,
132 CAIRO_TEST_REF_SUFFIX,
133 CAIRO_TEST_PNG_EXTENSION);
134 if (ref_name == NULL) {
135 cairo_test_log (ctx, "Error: Cannot find reference image for %s\n",
137 cairo_surface_destroy (test_image);
143 ref_image = cairo_test_get_reference_image (ctx, ref_name,
144 target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED);
145 if (cairo_surface_status (ref_image)) {
146 cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n",
148 cairo_status_to_string (cairo_surface_status (ref_image)));
149 cairo_surface_destroy (ref_image);
150 cairo_surface_destroy (test_image);
157 diff_image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
161 status = image_diff (ctx,
162 test_image, ref_image, diff_image,
164 _xunlink (ctx, diff_name);
166 cairo_test_log (ctx, "Error: Failed to compare images: %s\n",
167 cairo_status_to_string (status));
169 } else if (image_diff_is_failure (&result, target->error_tolerance))
173 status = cairo_surface_write_to_png (diff_image, diff_name);
175 cairo_test_log (ctx, "Error: Failed to write differences image: %s\n",
176 cairo_status_to_string (status));
180 cairo_surface_destroy (test_image);
181 cairo_surface_destroy (diff_image);
190 #define DOCUMENT_BBOX "%%BoundingBox:"
191 #define PAGE_BBOX "%%PageBoundingBox:"
194 check_bbox (cairo_test_context_t *ctx,
195 const char *base_name)
200 cairo_bool_t bbox_pass, page_bbox_pass;
201 int llx, lly, urx, ury;
204 xasprintf (&filename, "%s.out.ps", base_name);
205 f = fopen (filename, "r");
207 cairo_test_log (ctx, "Error: Cannot open EPS output: %s\n",
214 page_bbox_pass = FALSE;
216 if (fgets (buf, sizeof(buf), f) == (char *)EOF) {
217 cairo_test_log (ctx, "Error: Unexpected EOF in %s\n",
222 if (strncmp (buf, DOCUMENT_BBOX, strlen (DOCUMENT_BBOX)) == 0) {
223 ret = sscanf (buf+strlen (DOCUMENT_BBOX), "%d %d %d %d", &llx, &lly, &urx, &ury);
224 if (ret == 4 && llx == LLX && lly == LLY && urx == URX && ury == URY)
228 if (strncmp (buf, PAGE_BBOX, strlen (PAGE_BBOX)) == 0) {
229 ret = sscanf (buf+strlen (PAGE_BBOX), "%d %d %d %d", &llx, &lly, &urx, &ury);
230 if (ret == 4 && llx == LLX && lly == LLY && urx == URX && ury == URY)
231 page_bbox_pass = TRUE;
236 if (!bbox_pass || !page_bbox_pass) {
237 cairo_test_log (ctx, "Error: EPS Bounding Box does not match reference Bounding Box\n");
246 static cairo_test_status_t
247 preamble (cairo_test_context_t *ctx)
250 cairo_test_status_t ret = CAIRO_TEST_UNTESTED;
252 const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";
254 for (i = 0; i < ctx->num_targets; i++) {
255 const cairo_boilerplate_target_t *target = ctx->targets_to_test[i];
256 cairo_surface_t *surface = NULL;
260 cairo_status_t status;
264 if (! cairo_test_is_target_enabled (ctx, target->name))
267 format = cairo_boilerplate_content_name (target->content);
268 xasprintf (&test_name, "ps-eps");
269 xasprintf (&base_name, "%s/ps-eps.%s.%s",
270 path, target->name, format);
272 surface = (target->create_surface) (base_name,
276 CAIRO_BOILERPLATE_MODE_TEST,
279 if (surface == NULL) {
285 cairo_ps_surface_set_eps (surface, TRUE);
286 if (!cairo_ps_surface_get_eps (surface)) {
287 cairo_surface_destroy (surface);
289 target->cleanup (closure);
297 "Testing ps-eps with %s target\n",
299 printf ("%s:\t", base_name);
302 cairo_surface_set_device_offset (surface, 25, 25);
303 cr = cairo_create (surface);
305 cairo_new_sub_path (cr);
306 cairo_arc (cr, 100, 100, 25, 0, 2*M_PI);
307 cairo_set_line_width (cr, 10);
310 cairo_show_page (cr);
312 status = cairo_status (cr);
316 cairo_test_log (ctx, "Error: Failed to create target surface: %s\n",
317 cairo_status_to_string (status));
321 /* extract the image and compare it to our reference */
322 if (! check_result (ctx, target, test_name, base_name, surface))
325 /* check the bounding box of the EPS file and compare it to our reference */
326 if (! check_bbox (ctx, base_name))
329 cairo_surface_destroy (surface);
331 target->cleanup (closure);
338 ret = CAIRO_TEST_SUCCESS;
341 ret = CAIRO_TEST_FAILURE;
350 "Check EPS output from PS surface",
351 "ps, api", /* keywords */
352 NULL, /* requirements */