summaryrefslogtreecommitdiff
path: root/boilerplate/cairo-boilerplate.c
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2009-10-16 08:21:27 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2009-10-16 08:21:27 +0200
commit0b05d5812d0ceaeb5a9db5a50be0d3f7f16b277a (patch)
treec564d4accd135ebbd3c3e66a37c1f223996aed12 /boilerplate/cairo-boilerplate.c
parent0e79096a3831c10cf9735a7f518bfb65d0632923 (diff)
Import upstream version 1.9.4
Diffstat (limited to 'boilerplate/cairo-boilerplate.c')
-rw-r--r--boilerplate/cairo-boilerplate.c824
1 files changed, 283 insertions, 541 deletions
diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index 31df704..1414699 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -26,49 +26,16 @@
#define CAIRO_VERSION_H 1
-#include "cairo-boilerplate.h"
+#include "cairo-boilerplate-private.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_SCRIPT_SURFACE
-#include "cairo-boilerplate-script-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_SURFACE
-#include "cairo-boilerplate-xlib-private.h"
-#endif
-
#include <cairo-types-private.h>
#include <cairo-scaled-font-private.h>
+#if CAIRO_HAS_SCRIPT_SURFACE
+#include <cairo-script.h>
+#endif
+
/* get the "real" version info instead of dummy cairo-version.h */
#undef CAIRO_VERSION_H
#include "../cairo-version.h"
@@ -78,6 +45,10 @@
#include <assert.h>
#include <errno.h>
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
#if HAVE_UNISTD_H && HAVE_FCNTL_H && HAVE_SIGNAL_H && HAVE_SYS_STAT_H && HAVE_SYS_SOCKET_H && HAVE_SYS_UN_H
#include <unistd.h>
#include <fcntl.h>
@@ -117,6 +88,22 @@ cairo_boilerplate_content_name (cairo_content_t content)
}
}
+static const char *
+_cairo_boilerplate_content_visible_name (cairo_content_t content)
+{
+ switch (cairo_boilerplate_content (content)) {
+ case CAIRO_CONTENT_COLOR:
+ return "rgb";
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ return "rgba";
+ case CAIRO_CONTENT_ALPHA:
+ return "a";
+ default:
+ assert (0); /* not reached */
+ return "---";
+ }
+}
+
cairo_format_t
cairo_boilerplate_format_from_content (cairo_content_t content)
{
@@ -138,10 +125,10 @@ cairo_boilerplate_format_from_content (cairo_content_t content)
static cairo_surface_t *
_cairo_boilerplate_image_create_surface (const char *name,
cairo_content_t content,
- int width,
- int height,
- int max_width,
- int max_height,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
cairo_boilerplate_mode_t mode,
int id,
void **closure)
@@ -159,47 +146,75 @@ _cairo_boilerplate_image_create_surface (const char *name,
return NULL;
}
- return cairo_image_surface_create (format, width, height);
+ return cairo_image_surface_create (format, ceil (width), ceil (height));
}
+#if CAIRO_HAS_META_SURFACE
+static cairo_surface_t *
+_cairo_boilerplate_meta_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ int id,
+ void **closure)
+{
+ cairo_rectangle_t extents;
+
+ *closure = NULL;
+
+ extents.x = 0;
+ extents.y = 0;
+ extents.width = width;
+ extents.height = height;
+ return cairo_meta_surface_create (content, &extents);
+}
+#endif
+
+const cairo_user_data_key_t cairo_boilerplate_output_basename_key;
+
cairo_surface_t *
_cairo_boilerplate_get_image_surface (cairo_surface_t *src,
int page,
int width,
int height)
{
- cairo_surface_t *surface;
+ cairo_surface_t *surface, *image;
cairo_t *cr;
+ cairo_status_t status;
if (cairo_surface_status (src))
return cairo_surface_reference (src);
-#if 0
- if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_IMAGE) {
- int ww = cairo_image_surface_get_width (src);
- int hh = cairo_image_surface_get_height (src);
- if (width == ww && hh == height) {
- return cairo_surface_reference (src);
- } else {
- cairo_format_t format = cairo_image_surface_get_format (src);
- unsigned char *data = cairo_image_surface_get_data (src);
- int stride = cairo_image_surface_get_stride (src);
-
- data += stride * (hh - height) + 4 * (ww - width);
- return cairo_image_surface_create_for_data (data,
- format,
- width,
- height,
- stride);
- }
- }
-#endif
-
if (page != 0)
return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
/* extract sub-surface */
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ image = cairo_surface_reference (surface);
+
+ /* open a logging channel (only interesting for meta surfaces) */
+#if CAIRO_HAS_SCRIPT_SURFACE && CAIRO_HAS_META_SURFACE
+ if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_META) {
+ const char *test_name;
+
+ test_name = cairo_surface_get_user_data (src,
+ &cairo_boilerplate_output_basename_key);
+ if (test_name != NULL) {
+ cairo_script_context_t *ctx;
+ char *filename;
+
+ xasprintf (&filename, "%s.out.trace", test_name);
+ ctx = cairo_script_context_create (filename);
+ surface = cairo_script_surface_create_for_target (ctx, image);
+ cairo_script_context_destroy (ctx);
+ free (filename);
+ }
+ }
+#endif
+
cr = cairo_create (surface);
cairo_surface_destroy (surface);
@@ -207,10 +222,14 @@ _cairo_boilerplate_get_image_surface (cairo_surface_t *src,
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
- surface = cairo_surface_reference (cairo_get_target (cr));
+ status = cairo_status (cr);
+ if (status) {
+ cairo_surface_destroy (image);
+ image = cairo_surface_reference (cairo_get_target (cr));
+ }
cairo_destroy (cr);
- return surface;
+ return image;
}
cairo_surface_t *
@@ -222,6 +241,8 @@ cairo_boilerplate_get_image_surface_from_png (const char *filename,
cairo_surface_t *surface;
surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface))
+ return surface;
if (flatten) {
cairo_t *cr;
@@ -270,487 +291,140 @@ cairo_boilerplate_get_image_surface_from_png (const char *filename,
return surface;
}
-static cairo_boilerplate_target_t targets[] =
-{
+static const cairo_boilerplate_target_t builtin_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", "image", NULL,
+ "image", "image", NULL, NULL,
CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_image_create_surface, NULL,
- NULL,
+ NULL, _cairo_boilerplate_image_create_surface,
+ NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png
},
{
- "image", "image", NULL,
+ "image", "image", NULL, NULL,
CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_image_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png
- },
-#ifdef CAIRO_HAS_TEST_SURFACES
- {
- "test-fallback", "image", NULL,
- CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
- CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_test_fallback_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png
- },
- {
- "test-fallback", "image", NULL,
- CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
- CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_test_fallback_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png
- },
- {
- "test-fallback16", "image", NULL,
- CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
- CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_test_fallback16_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png
- },
- {
- "test-fallback16", "image", NULL,
- CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
- CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_test_fallback16_create_surface, NULL,
- NULL,
+ NULL, _cairo_boilerplate_image_create_surface,
+ NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png
},
+#if CAIRO_HAS_META_SURFACE
{
- "test-meta", "image", NULL,
- CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
- CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_test_meta_create_surface, NULL,
- NULL,
+ "meta", "image", NULL, NULL,
+ CAIRO_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "cairo_meta_surface_create",
+ _cairo_boilerplate_meta_create_surface,
+ NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
NULL, NULL,
FALSE, TRUE
},
{
- "test-meta", "image", NULL,
- CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
- CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_test_meta_create_surface, NULL,
- NULL,
+ "meta", "image", NULL, NULL,
+ CAIRO_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
+ "cairo_meta_surface_create",
+ _cairo_boilerplate_meta_create_surface,
+ NULL, NULL,
_cairo_boilerplate_get_image_surface,
cairo_surface_write_to_png,
NULL, NULL,
FALSE, TRUE
},
- {
- "test-paginated", "image", NULL,
- CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
- CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_test_paginated_create_surface, NULL,
- NULL,
- _cairo_boilerplate_test_paginated_get_image_surface,
- _cairo_boilerplate_test_paginated_surface_write_to_png,
- _cairo_boilerplate_test_paginated_cleanup,
- NULL,
- FALSE, TRUE,
- },
- {
- "test-paginated", "image", NULL,
- CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
- CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_test_paginated_create_surface, NULL,
- NULL,
- _cairo_boilerplate_test_paginated_get_image_surface,
- _cairo_boilerplate_test_paginated_surface_write_to_png,
- _cairo_boilerplate_test_paginated_cleanup,
- NULL,
- FALSE, TRUE
- },
-#endif
-#ifdef CAIRO_HAS_GLITZ_SURFACE
-#if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE
- {
- "glitz-glx", "glitz", NULL,
- CAIRO_SURFACE_TYPE_GLITZ,CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_glitz_glx_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_glitz_glx_cleanup
- },
- {
- "glitz-glx", "glitz", NULL,
- CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_glitz_glx_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_glitz_glx_cleanup
- },
-#endif
-#if CAIRO_CAN_TEST_GLITZ_AGL_SURFACE
- {
- "glitz-agl", "glitz", NULL,
- CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_glitz_agl_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_glitz_agl_cleanup
- },
- {
- "glitz-agl", "glitz", NULL,
- CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_glitz_agl_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_glitz_agl_cleanup
- },
-#endif
-#if CAIRO_CAN_TEST_GLITZ_WGL_SURFACE
- {
- "glitz-wgl", "glitz", NULL,
- CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_glitz_wgl_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_glitz_wgl_cleanup
- },
- {
- "glitz-wgl", "glitz", NULL,
- CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_glitz_wgl_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_glitz_wgl_cleanup
- },
-#endif
-#endif /* CAIRO_HAS_GLITZ_SURFACE */
-#if CAIRO_HAS_QUARTZ_SURFACE
- {
- "quartz", "quartz", NULL,
- CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_quartz_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_quartz_cleanup
- },
- {
- "quartz", "quartz", NULL,
- CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_quartz_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_quartz_cleanup
- },
-#endif
-#if CAIRO_HAS_WIN32_SURFACE
- {
- "win32", "win32", NULL,
- CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_win32_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_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", "win32", NULL,
- CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_win32_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png
- },
-#if CAIRO_CAN_TEST_WIN32_PRINTING_SURFACE
- {
- "win32-printing", "win32", ".ps",
- CAIRO_SURFACE_TYPE_WIN32_PRINTING,
- CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
- _cairo_boilerplate_win32_printing_create_surface, NULL,
- NULL,
- _cairo_boilerplate_win32_printing_get_image_surface,
- _cairo_boilerplate_win32_printing_surface_write_to_png,
- _cairo_boilerplate_win32_printing_cleanup,
- NULL, TRUE, TRUE
- },
- {
- "win32-printing", "win32", ".ps",
- CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_win32_printing_create_surface, NULL,
- NULL,
- _cairo_boilerplate_win32_printing_get_image_surface,
- _cairo_boilerplate_win32_printing_surface_write_to_png,
- _cairo_boilerplate_win32_printing_cleanup,
- NULL, TRUE, TRUE
- },
-#endif
-#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", "xcb", NULL,
- CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
- _cairo_boilerplate_xcb_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_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", "xlib", NULL,
- CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1,
- _cairo_boilerplate_xlib_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_xlib_cleanup,
- _cairo_boilerplate_xlib_synchronize
- },
- {
- "xlib", "xlib", NULL, CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
- _cairo_boilerplate_xlib_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_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", "image", NULL,
- CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
- _cairo_boilerplate_xlib_fallback_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_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
- {
- "ps2", "ps", ".ps",
- CAIRO_SURFACE_TYPE_PS,
- CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
- _cairo_boilerplate_ps2_create_surface,
- _cairo_boilerplate_ps_force_fallbacks,
- _cairo_boilerplate_ps_finish_surface,
- _cairo_boilerplate_ps_get_image_surface,
- _cairo_boilerplate_ps_surface_write_to_png,
- _cairo_boilerplate_ps_cleanup,
- NULL, TRUE, TRUE
- },
- {
- "ps2", "ps", ".ps",
- CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_ps2_create_surface,
- _cairo_boilerplate_ps_force_fallbacks,
- _cairo_boilerplate_ps_finish_surface,
- _cairo_boilerplate_ps_get_image_surface,
- _cairo_boilerplate_ps_surface_write_to_png,
- _cairo_boilerplate_ps_cleanup,
- NULL, TRUE, TRUE
- },
- {
- "ps3", "ps", ".ps",
- CAIRO_SURFACE_TYPE_PS,
- CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
- _cairo_boilerplate_ps3_create_surface,
- _cairo_boilerplate_ps_force_fallbacks,
- _cairo_boilerplate_ps_finish_surface,
- _cairo_boilerplate_ps_get_image_surface,
- _cairo_boilerplate_ps_surface_write_to_png,
- _cairo_boilerplate_ps_cleanup,
- NULL, TRUE, TRUE
- },
- {
- "ps3", "ps", ".ps",
- CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_ps3_create_surface,
- _cairo_boilerplate_ps_force_fallbacks,
- _cairo_boilerplate_ps_finish_surface,
- _cairo_boilerplate_ps_get_image_surface,
- _cairo_boilerplate_ps_surface_write_to_png,
- _cairo_boilerplate_ps_cleanup,
- NULL, TRUE, TRUE
- },
-#endif
-#if CAIRO_HAS_PDF_SURFACE && CAIRO_CAN_TEST_PDF_SURFACE
- {
- "pdf", "pdf", ".pdf",
- CAIRO_SURFACE_TYPE_PDF,
- CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
- _cairo_boilerplate_pdf_create_surface,
- _cairo_boilerplate_pdf_force_fallbacks,
- _cairo_boilerplate_pdf_finish_surface,
- _cairo_boilerplate_pdf_get_image_surface,
- _cairo_boilerplate_pdf_surface_write_to_png,
- _cairo_boilerplate_pdf_cleanup,
- NULL, TRUE, TRUE
- },
- {
- "pdf", "pdf", ".pdf",
- CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_pdf_create_surface,
- _cairo_boilerplate_pdf_force_fallbacks,
- _cairo_boilerplate_pdf_finish_surface,
- _cairo_boilerplate_pdf_get_image_surface,
- _cairo_boilerplate_pdf_surface_write_to_png,
- _cairo_boilerplate_pdf_cleanup,
- NULL, TRUE, TRUE
- },
-#endif
-#if CAIRO_HAS_SCRIPT_SURFACE
- {
- "script", "script", ".cs",
- CAIRO_SURFACE_TYPE_SCRIPT, CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_script_create_surface,
- NULL,
- _cairo_boilerplate_script_finish_surface,
- _cairo_boilerplate_script_get_image_surface,
- _cairo_boilerplate_script_surface_write_to_png,
- _cairo_boilerplate_script_cleanup,
- NULL, FALSE
- },
-#endif
-#if CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE
- /* It seems we should be able to round-trip SVG content perfectly
- * 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. */
- {
- "svg11", "svg", NULL,
- CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1,
- _cairo_boilerplate_svg11_create_surface,
- _cairo_boilerplate_svg_force_fallbacks,
- _cairo_boilerplate_svg_finish_surface,
- _cairo_boilerplate_svg_get_image_surface,
- _cairo_boilerplate_svg_surface_write_to_png,
- _cairo_boilerplate_svg_cleanup,
- NULL, TRUE, TRUE
- },
- {
- "svg11", "svg", NULL,
- CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 1,
- _cairo_boilerplate_svg11_create_surface,
- _cairo_boilerplate_svg_force_fallbacks,
- _cairo_boilerplate_svg_finish_surface,
- _cairo_boilerplate_svg_get_image_surface,
- _cairo_boilerplate_svg_surface_write_to_png,
- _cairo_boilerplate_svg_cleanup,
- NULL, TRUE, TRUE
- },
- {
- "svg12", "svg", NULL,
- CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1,
- _cairo_boilerplate_svg12_create_surface,
- _cairo_boilerplate_svg_force_fallbacks,
- _cairo_boilerplate_svg_finish_surface,
- _cairo_boilerplate_svg_get_image_surface,
- _cairo_boilerplate_svg_surface_write_to_png,
- _cairo_boilerplate_svg_cleanup,
- NULL, TRUE, TRUE
- },
- {
- "svg12", "svg", NULL,
- CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 1,
- _cairo_boilerplate_svg12_create_surface,
- _cairo_boilerplate_svg_force_fallbacks,
- _cairo_boilerplate_svg_finish_surface,
- _cairo_boilerplate_svg_get_image_surface,
- _cairo_boilerplate_svg_surface_write_to_png,
- _cairo_boilerplate_svg_cleanup,
- NULL, TRUE, 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", "beos", NULL,
- CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR, 1,
- _cairo_boilerplate_beos_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_beos_cleanup
- },
- {
- "beos-bitmap", "beos", NULL,
- CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR, 1,
- _cairo_boilerplate_beos_create_surface_for_bitmap, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_beos_cleanup_bitmap
- },
- {
- "beos-bitmap", "beos", NULL,
- CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR_ALPHA, 1,
- _cairo_boilerplate_beos_create_surface_for_bitmap, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_beos_cleanup_bitmap
- },
#endif
+};
+CAIRO_BOILERPLATE (builtin, builtin_targets)
-#if CAIRO_HAS_DIRECTFB_SURFACE
- {
- "directfb", "directfb", NULL,
- CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR, 0,
- _cairo_boilerplate_directfb_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_directfb_cleanup
- },
- {
- "directfb-bitmap", "directfb", NULL,
- CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR_ALPHA, 0,
- _cairo_boilerplate_directfb_create_surface, NULL,
- NULL,
- _cairo_boilerplate_get_image_surface,
- cairo_surface_write_to_png,
- _cairo_boilerplate_directfb_cleanup
- },
+static struct cairo_boilerplate_target_list {
+ struct cairo_boilerplate_target_list *next;
+ const cairo_boilerplate_target_t *target;
+} *cairo_boilerplate_targets;
+
+static cairo_bool_t
+probe_target (const cairo_boilerplate_target_t *target)
+{
+ if (target->probe == NULL)
+ return TRUE;
+
+#if HAVE_DLSYM
+ return dlsym (NULL, target->probe) != NULL;
+#else
+ return TRUE;
#endif
-};
+}
+
+void
+_cairo_boilerplate_register_backend (const cairo_boilerplate_target_t *targets,
+ unsigned int count)
+{
+ targets += count;
+ while (count--) {
+ struct cairo_boilerplate_target_list *list;
+
+ --targets;
+ if (! probe_target (targets))
+ continue;
+
+ list = xmalloc (sizeof (*list));
+ list->next = cairo_boilerplate_targets;
+ list->target = targets;
+ cairo_boilerplate_targets = list;
+ }
+}
+
+static cairo_bool_t
+_cairo_boilerplate_target_matches_name (const cairo_boilerplate_target_t *target,
+ const char *tname,
+ const char *end)
+{
+ char const *content_name;
+ const char *content_start = strpbrk (tname, ".");
+ const char *content_end = end;
+ size_t name_len;
+ size_t content_len;
+
+ if (content_start != NULL)
+ end = content_start++;
+
+ name_len = end - tname;
+
+ /* Check name. */
+ if (! (name_len == 1 && 0 == strncmp (tname, "?", 1))) { /* wildcard? */
+ if (0 != strncmp (target->name, tname, name_len)) /* exact match? */
+ return FALSE;
+ if (isalnum (target->name[name_len]))
+ return FALSE;
+ }
+
+ /* Check optional content. */
+ if (content_start == NULL) /* none given? */
+ return TRUE;
-cairo_boilerplate_target_t **
+ /* Exact content match? */
+ content_name = _cairo_boilerplate_content_visible_name (target->content);
+ content_len = content_end - content_start;
+ if (strlen(content_name) != content_len)
+ return FALSE;
+ if (0 == strncmp (content_name, content_start, content_len))
+ return TRUE;
+
+ return FALSE;
+}
+
+const 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;
+ const cairo_boilerplate_target_t **targets_to_test;
+ struct cairo_boilerplate_target_list *list;
+
+ if (cairo_boilerplate_targets == NULL)
+ _cairo_boilerplate_register_all ();
if ((tname = getenv ("CAIRO_TEST_TARGET")) != NULL && *tname) {
/* check the list of targets specified by the user */
@@ -770,29 +444,39 @@ cairo_boilerplate_get_targets (int *pnum_targets, cairo_bool_t *plimited_targets
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])) {
+ for (list = cairo_boilerplate_targets;
+ list != NULL;
+ list = list->next)
+ {
+ const cairo_boilerplate_target_t *target = list->target;
+ if (_cairo_boilerplate_target_matches_name (target, tname, end)) {
/* 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];
+ targets_to_test[num_targets++] = target;
found = 1;
}
}
if (!found) {
+ const char *last_name = NULL;
+
fprintf (stderr, "Cannot find target '%.*s'.\n",
(int)(end - tname), tname);
fprintf (stderr, "Known targets:");
- for (i = 0; i < sizeof (targets) / sizeof (targets[0]); i++) {
- if (i != 0) {
- if (strcmp (targets[i].name, targets[i-1].name) == 0) {
+ for (list = cairo_boilerplate_targets;
+ list != NULL;
+ list = list->next)
+ {
+ const cairo_boilerplate_target_t *target = list->target;
+ if (last_name != NULL) {
+ if (strcmp (target->name, last_name) == 0) {
/* filter out repeats that differ in content */
continue;
}
fprintf (stderr, ",");
}
- fprintf (stderr, " %s", targets[i].name);
+ fprintf (stderr, " %s", target->name);
+ last_name = target->name;
}
fprintf (stderr, "\n");
exit(-1);
@@ -804,10 +488,18 @@ cairo_boilerplate_get_targets (int *pnum_targets, cairo_bool_t *plimited_targets
}
} else {
/* check all compiled in targets */
- num_targets = sizeof (targets) / sizeof (targets[0]);
+ num_targets = 0;
+ for (list = cairo_boilerplate_targets; list != NULL; list = list->next)
+ num_targets++;
+
targets_to_test = xmalloc (sizeof(cairo_boilerplate_target_t*) * num_targets);
- for (i = 0; i < num_targets; i++) {
- targets_to_test[i] = &targets[i];
+ num_targets = 0;
+ for (list = cairo_boilerplate_targets;
+ list != NULL;
+ list = list->next)
+ {
+ const cairo_boilerplate_target_t *target = list->target;
+ targets_to_test[num_targets++] = target;
}
}
@@ -827,8 +519,9 @@ cairo_boilerplate_get_targets (int *pnum_targets, cairo_bool_t *plimited_targets
}
for (i = j = 0; i < num_targets; i++) {
- if (strncmp (targets_to_test[i]->name, tname, end - tname) ||
- isalnum (targets_to_test[i]->name[end - tname]))
+ const cairo_boilerplate_target_t *target = targets_to_test[i];
+ if (! _cairo_boilerplate_target_matches_name (target,
+ tname, end))
{
targets_to_test[j++] = targets_to_test[i];
}
@@ -850,8 +543,57 @@ cairo_boilerplate_get_targets (int *pnum_targets, cairo_bool_t *plimited_targets
return targets_to_test;
}
+const cairo_boilerplate_target_t *
+cairo_boilerplate_get_image_target (cairo_content_t content)
+{
+ struct cairo_boilerplate_target_list *list;
+
+ if (cairo_boilerplate_targets == NULL)
+ _cairo_boilerplate_register_all ();
+
+ for (list = cairo_boilerplate_targets; list != NULL; list = list->next) {
+ const cairo_boilerplate_target_t *target = list->target;
+ if (target->expected_type == CAIRO_SURFACE_TYPE_IMAGE &&
+ target->content == content)
+ {
+ return target;
+ }
+ }
+
+ return NULL;
+}
+
+const cairo_boilerplate_target_t *
+cairo_boilerplate_get_target_by_name (const char *name,
+ cairo_content_t content)
+{
+ struct cairo_boilerplate_target_list *list;
+
+ if (cairo_boilerplate_targets == NULL)
+ _cairo_boilerplate_register_all ();
+
+ /* first return an exact match */
+ for (list = cairo_boilerplate_targets; list != NULL; list = list->next) {
+ const cairo_boilerplate_target_t *target = list->target;
+ if (strcmp (target->name, name) == 0 &&
+ target->content == content)
+ {
+ return target;
+ }
+ }
+
+ /* otherwise just return a match that may differ in content */
+ for (list = cairo_boilerplate_targets; list != NULL; list = list->next) {
+ const cairo_boilerplate_target_t *target = list->target;
+ if (strcmp (target->name, name) == 0)
+ return target;
+ }
+
+ return NULL;
+}
+
void
-cairo_boilerplate_free_targets (cairo_boilerplate_target_t **targets)
+cairo_boilerplate_free_targets (const cairo_boilerplate_target_t **targets)
{
free (targets);
}
@@ -1013,19 +755,20 @@ cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file)
data = cairo_image_surface_get_data (image);
stride = cairo_image_surface_get_stride (image);
for (y = 0; y < height; y++) {
- unsigned char *buf = data + y *stride;
+ unsigned char *buf = data + y*stride;
switch (format) {
case '7':
if (! freadn (buf, 4 * width, file))
goto FAIL;
break;
case '6':
- for (x = 0; x < width; x++) {
- if (! freadn (buf, 3, file))
- goto FAIL;
- *(uint32_t *) buf =
+ if (! freadn (buf, 3*width, file))
+ goto FAIL;
+ buf += 3*width;
+ for (x = width; x--; ) {
+ buf -= 3;
+ ((uint32_t *) (data + y*stride))[x] =
(buf[0] << 16) | (buf[1] << 8) | (buf[2] << 0);
- buf += 4;
}
break;
case '5':
@@ -1063,8 +806,13 @@ cairo_boilerplate_convert_to_image (const char *filename, int page)
image = cairo_boilerplate_image_surface_create_from_ppm_stream (file);
ret = pclose (file);
+ /* check for fatal errors from the interpreter */
+ if (ret) { /* any2pmm should never die... */
+ cairo_surface_destroy (image);
+ return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_INVALID_STATUS);
+ }
- if (cairo_surface_status (image) == CAIRO_STATUS_READ_ERROR) {
+ if (ret == 0 && cairo_surface_status (image) == CAIRO_STATUS_READ_ERROR) {
if (flags == 0) {
/* Try again in a standalone process. */
cairo_surface_destroy (image);
@@ -1073,12 +821,6 @@ cairo_boilerplate_convert_to_image (const char *filename, int page)
}
}
- if (cairo_surface_status (image) == CAIRO_STATUS_SUCCESS && ret != 0) {
- cairo_surface_destroy (image);
- image =
- cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
- };
-
return image;
}