/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ /* * Copyright © 2004,2006 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that the above copyright notice appear in all copies * and that both that copyright notice and this permission notice * appear in supporting documentation, and that the name of * Red Hat, Inc. not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. Red Hat, Inc. makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Carl D. Worth */ #include "cairo-boilerplate.h" #include "cairo-boilerplate-scaled-font.h" #if CAIRO_HAS_BEOS_SURFACE #include "cairo-boilerplate-beos-private.h" #endif #if CAIRO_HAS_DIRECTFB_SURFACE #include "cairo-boilerplate-directfb-private.h" #endif #if CAIRO_HAS_GLITZ_SURFACE #include "cairo-boilerplate-glitz-private.h" #endif #if CAIRO_HAS_PDF_SURFACE #include "cairo-boilerplate-pdf-private.h" #endif #if CAIRO_HAS_PS_SURFACE #include "cairo-boilerplate-ps-private.h" #endif #if CAIRO_HAS_QUARTZ_SURFACE #include "cairo-boilerplate-quartz-private.h" #endif #if CAIRO_HAS_SVG_SURFACE #include "cairo-boilerplate-svg-private.h" #endif #ifdef CAIRO_HAS_TEST_SURFACES #include "cairo-boilerplate-test-surfaces-private.h" #endif #if CAIRO_HAS_WIN32_SURFACE #include "cairo-boilerplate-win32-private.h" #endif #if CAIRO_HAS_XCB_SURFACE #include "cairo-boilerplate-xcb-private.h" #endif #if CAIRO_HAS_XLIB_XRENDER_SURFACE #include "cairo-boilerplate-xlib-private.h" #endif #include #include #include #include #include const char * cairo_boilerplate_content_name (cairo_content_t content) { /* For the purpose of the content name, we don't distinguish the * flattened content value. */ if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) content = CAIRO_CONTENT_COLOR_ALPHA; switch (content) { case CAIRO_CONTENT_COLOR: return "rgb24"; case CAIRO_CONTENT_COLOR_ALPHA: return "argb32"; case CAIRO_CONTENT_ALPHA: default: assert (0); /* not reached */ return "---"; } } cairo_format_t cairo_boilerplate_format_from_content (cairo_content_t content) { cairo_format_t format; switch (content) { case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break; case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break; case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break; default: assert (0); /* not reached */ format = (cairo_format_t) -1; break; } return format; } static cairo_surface_t * _cairo_boilerplate_image_create_surface (const char *name, cairo_content_t content, int width, int height, cairo_boilerplate_mode_t mode, void **closure) { cairo_format_t format; *closure = NULL; if (content == CAIRO_CONTENT_COLOR_ALPHA) { format = CAIRO_FORMAT_ARGB32; } else if (content == CAIRO_CONTENT_COLOR) { format = CAIRO_FORMAT_RGB24; } else { assert (0); /* not reached */ return NULL; } return cairo_image_surface_create (format, width, height); } static cairo_boilerplate_target_t targets[] = { /* I'm uncompromising about leaving the image backend as 0 * for tolerance. There shouldn't ever be anything that is out of * our control here. */ { "image", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA, 0, _cairo_boilerplate_image_create_surface, cairo_surface_write_to_png }, { "image", CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_image_create_surface, cairo_surface_write_to_png }, #ifdef CAIRO_HAS_TEST_SURFACES { "test-fallback", CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK, CAIRO_CONTENT_COLOR_ALPHA, 0, _cairo_boilerplate_test_fallback_create_surface, cairo_surface_write_to_png }, { "test-fallback", CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_test_fallback_create_surface, cairo_surface_write_to_png }, { "test-meta", CAIRO_INTERNAL_SURFACE_TYPE_TEST_META, CAIRO_CONTENT_COLOR_ALPHA, 0, _cairo_boilerplate_test_meta_create_surface, cairo_surface_write_to_png }, { "test-meta", CAIRO_INTERNAL_SURFACE_TYPE_TEST_META, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_test_meta_create_surface, cairo_surface_write_to_png }, { "test-paginated", CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED, CAIRO_CONTENT_COLOR_ALPHA, 0, _cairo_boilerplate_test_paginated_create_surface, _cairo_boilerplate_test_paginated_surface_write_to_png, _cairo_boilerplate_test_paginated_cleanup }, { "test-paginated", CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_test_paginated_create_surface, _cairo_boilerplate_test_paginated_surface_write_to_png, _cairo_boilerplate_test_paginated_cleanup }, #endif #ifdef CAIRO_HAS_GLITZ_SURFACE #if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE { "glitz-glx", CAIRO_SURFACE_TYPE_GLITZ,CAIRO_CONTENT_COLOR_ALPHA, 0, _cairo_boilerplate_glitz_glx_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_glitz_glx_cleanup }, { "glitz-glx", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_glitz_glx_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_glitz_glx_cleanup }, #endif #if CAIRO_CAN_TEST_GLITZ_AGL_SURFACE { "glitz-agl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA, 0, _cairo_boilerplate_glitz_agl_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_glitz_agl_cleanup }, { "glitz-agl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_glitz_agl_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_glitz_agl_cleanup }, #endif #if CAIRO_CAN_TEST_GLITZ_WGL_SURFACE { "glitz-wgl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA, 0, _cairo_boilerplate_glitz_wgl_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_glitz_wgl_cleanup }, { "glitz-wgl", CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_glitz_wgl_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_glitz_wgl_cleanup }, #endif #endif /* CAIRO_HAS_GLITZ_SURFACE */ #if CAIRO_HAS_QUARTZ_SURFACE { "quartz", CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR_ALPHA, 0, _cairo_boilerplate_quartz_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_quartz_cleanup }, { "quartz", CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_quartz_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_quartz_cleanup }, #endif #if CAIRO_HAS_WIN32_SURFACE { "win32", CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_win32_create_surface, cairo_surface_write_to_png }, /* Testing the win32 surface isn't interesting, since for * ARGB images it just chains to the image backend */ { "win32", CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR_ALPHA, 0, _cairo_boilerplate_win32_create_surface, cairo_surface_write_to_png }, { "win32-printing", CAIRO_SURFACE_TYPE_WIN32_PRINTING, CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0, _cairo_boilerplate_win32_printing_create_surface, _cairo_boilerplate_win32_printing_surface_write_to_png, _cairo_boilerplate_win32_printing_cleanup, NULL, TRUE }, { "win32-printing", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_win32_printing_create_surface, _cairo_boilerplate_win32_printing_surface_write_to_png, _cairo_boilerplate_win32_printing_cleanup, NULL, TRUE }, #endif #if CAIRO_HAS_XCB_SURFACE /* Acceleration architectures may make the results differ by a * bit, so we set the error tolerance to 1. */ { "xcb", CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1, _cairo_boilerplate_xcb_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_xcb_cleanup, _cairo_boilerplate_xcb_synchronize}, #endif #if CAIRO_HAS_XLIB_XRENDER_SURFACE /* Acceleration architectures may make the results differ by a * bit, so we set the error tolerance to 1. */ { "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1, _cairo_boilerplate_xlib_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_xlib_cleanup, _cairo_boilerplate_xlib_synchronize}, { "xlib", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, _cairo_boilerplate_xlib_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_xlib_cleanup, _cairo_boilerplate_xlib_synchronize}, #endif #if CAIRO_HAS_XLIB_SURFACE /* This is a fallback surface which uses xlib fallbacks instead of * the Render extension. */ { "xlib-fallback", CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, _cairo_boilerplate_xlib_fallback_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_xlib_cleanup, _cairo_boilerplate_xlib_synchronize}, #endif #if CAIRO_HAS_PS_SURFACE && CAIRO_CAN_TEST_PS_SURFACE { "ps", CAIRO_SURFACE_TYPE_PS, CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0, _cairo_boilerplate_ps_create_surface, _cairo_boilerplate_ps_surface_write_to_png, _cairo_boilerplate_ps_cleanup, NULL, TRUE }, { "ps", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_ps_create_surface, _cairo_boilerplate_ps_surface_write_to_png, _cairo_boilerplate_ps_cleanup, NULL, TRUE }, #endif #if CAIRO_HAS_PDF_SURFACE && CAIRO_CAN_TEST_PDF_SURFACE { "pdf", CAIRO_SURFACE_TYPE_PDF, CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0, _cairo_boilerplate_pdf_create_surface, _cairo_boilerplate_pdf_surface_write_to_png, _cairo_boilerplate_pdf_cleanup, NULL, TRUE }, { "pdf", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_pdf_create_surface, _cairo_boilerplate_pdf_surface_write_to_png, _cairo_boilerplate_pdf_cleanup, NULL, TRUE }, #endif #if CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE /* It seems we should be able to round-trip SVG content perfrectly * through librsvg and cairo, but for some mysterious reason, some * systems get an error of 1 for some pixels on some of the text * tests. XXX: I'd still like to chase these down at some point. * For now just set the svg error tolerance to 1. */ { "svg", CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1, _cairo_boilerplate_svg_create_surface, _cairo_boilerplate_svg_surface_write_to_png, _cairo_boilerplate_svg_cleanup, NULL, TRUE }, { "svg", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 1, _cairo_boilerplate_svg_create_surface, _cairo_boilerplate_svg_surface_write_to_png, _cairo_boilerplate_svg_cleanup, NULL, TRUE }, #endif #if CAIRO_HAS_BEOS_SURFACE /* BeOS sometimes produces a slightly different image. Perhaps this * is related to the fact that it doesn't use premultiplied alpha... * Just ignore the small difference. */ { "beos", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR, 1, _cairo_boilerplate_beos_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_beos_cleanup}, { "beos-bitmap", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR, 1, _cairo_boilerplate_beos_create_surface_for_bitmap, cairo_surface_write_to_png, _cairo_boilerplate_beos_cleanup_bitmap}, { "beos-bitmap", CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR_ALPHA, 1, _cairo_boilerplate_beos_create_surface_for_bitmap, cairo_surface_write_to_png, _cairo_boilerplate_beos_cleanup_bitmap}, #endif #if CAIRO_HAS_DIRECTFB_SURFACE { "directfb", CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR, 0, _cairo_boilerplate_directfb_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_directfb_cleanup}, { "directfb-bitmap", CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR_ALPHA, 0, _cairo_boilerplate_directfb_create_surface, cairo_surface_write_to_png, _cairo_boilerplate_directfb_cleanup}, #endif }; cairo_boilerplate_target_t ** cairo_boilerplate_get_targets (int *pnum_targets, cairo_bool_t *plimited_targets) { size_t i, num_targets; cairo_bool_t limited_targets = FALSE; const char *tname; cairo_boilerplate_target_t **targets_to_test; if ((tname = getenv ("CAIRO_TEST_TARGET")) != NULL && *tname) { /* check the list of targets specified by the user */ limited_targets = TRUE; num_targets = 0; targets_to_test = NULL; while (*tname) { int found = 0; const char *end = strpbrk (tname, " \t\r\n;:,"); if (!end) end = tname + strlen (tname); if (end == tname) { tname = end + 1; continue; } for (i = 0; i < sizeof (targets) / sizeof (targets[0]); i++) { if (0 == strncmp (targets[i].name, tname, end - tname) && !isalnum (targets[i].name[end - tname])) { /* realloc isn't exactly the best thing here, but meh. */ targets_to_test = xrealloc (targets_to_test, sizeof(cairo_boilerplate_target_t *) * (num_targets+1)); targets_to_test[num_targets++] = &targets[i]; found = 1; } } if (!found) { fprintf (stderr, "Cannot find target '%.*s'\n", (int)(end - tname), tname); exit(-1); } if (*end) end++; tname = end; } } else { /* check all compiled in targets */ num_targets = sizeof (targets) / sizeof (targets[0]); targets_to_test = xmalloc (sizeof(cairo_boilerplate_target_t*) * num_targets); for (i = 0; i < num_targets; i++) { targets_to_test[i] = &targets[i]; } } /* exclude targets as specified by the user */ if ((tname = getenv ("CAIRO_TEST_TARGET_EXCLUDE")) != NULL && *tname) { limited_targets = TRUE; while (*tname) { int j, found = 0; const char *end = strpbrk (tname, " \t\r\n;:,"); if (!end) end = tname + strlen (tname); if (end == tname) { tname = end + 1; continue; } for (i = j = 0; i < num_targets; i++) { if (0 == strncmp (targets_to_test[i]->name, tname, end - tname) && !isalnum (targets_to_test[i]->name[end - tname])) { found = 1; } else { targets_to_test[j++] = targets_to_test[i]; } } num_targets = j; if (*end) end++; tname = end; } } if (pnum_targets) *pnum_targets = num_targets; if (plimited_targets) *plimited_targets = limited_targets; return targets_to_test; } void cairo_boilerplate_free_targets (cairo_boilerplate_target_t **targets) { free (targets); } void cairo_boilerplate_surface_set_user_data (cairo_surface_t *surface, const cairo_user_data_key_t *key, void *user_data, cairo_destroy_func_t destroy) { cairo_status_t status; status = cairo_surface_set_user_data (surface, key, user_data, destroy); if (status) { CAIRO_BOILERPLATE_LOG ("Error: %s. Exiting\n", cairo_status_to_string (status)); exit (1); } } void cairo_boilerplate_scaled_font_set_max_glyphs_cached (cairo_scaled_font_t *scaled_font, int max_glyphs) { if (cairo_scaled_font_status (scaled_font)) return; scaled_font->glyphs->max_size = max_glyphs; }