added MouseWheel event support for Silverlight 3.0
[moon.git] / cairo / boilerplate / cairo-boilerplate.c
blob13b14eb9a172ed32f26ec3f35b0e40426eccda66
1 /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
2 /*
3 * Copyright © 2004,2006 Red Hat, Inc.
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without
7 * fee, provided that the above copyright notice appear in all copies
8 * and that both that copyright notice and this permission notice
9 * appear in supporting documentation, and that the name of
10 * Red Hat, Inc. not be used in advertising or publicity pertaining to
11 * distribution of the software without specific, written prior
12 * permission. Red Hat, Inc. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as
14 * is" without express or implied warranty.
16 * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
19 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
22 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * Author: Carl D. Worth <cworth@cworth.org>
27 #define CAIRO_VERSION_H 1
29 #include "cairo-boilerplate.h"
30 #include "cairo-boilerplate-scaled-font.h"
32 #if CAIRO_HAS_BEOS_SURFACE
33 #include "cairo-boilerplate-beos-private.h"
34 #endif
35 #if CAIRO_HAS_DIRECTFB_SURFACE
36 #include "cairo-boilerplate-directfb-private.h"
37 #endif
38 #if CAIRO_HAS_GLITZ_SURFACE
39 #include "cairo-boilerplate-glitz-private.h"
40 #endif
41 #if CAIRO_HAS_PDF_SURFACE
42 #include "cairo-boilerplate-pdf-private.h"
43 #endif
44 #if CAIRO_HAS_PS_SURFACE
45 #include "cairo-boilerplate-ps-private.h"
46 #endif
47 #if CAIRO_HAS_QUARTZ_SURFACE
48 #include "cairo-boilerplate-quartz-private.h"
49 #endif
50 #if CAIRO_HAS_SVG_SURFACE
51 #include "cairo-boilerplate-svg-private.h"
52 #endif
53 #ifdef CAIRO_HAS_TEST_SURFACES
54 #include "cairo-boilerplate-test-surfaces-private.h"
55 #endif
56 #if CAIRO_HAS_WIN32_SURFACE
57 #include "cairo-boilerplate-win32-private.h"
58 #endif
59 #if CAIRO_HAS_XCB_SURFACE
60 #include "cairo-boilerplate-xcb-private.h"
61 #endif
62 #if CAIRO_HAS_XLIB_SURFACE
63 #include "cairo-boilerplate-xlib-private.h"
64 #endif
66 #include <cairo-types-private.h>
67 #include <cairo-scaled-font-private.h>
69 /* get the "real" version info instead of dummy cairo-version.h */
70 #undef CAIRO_VERSION_H
71 #include "../cairo-version.h"
73 #include <stdlib.h>
74 #include <ctype.h>
75 #include <assert.h>
77 #if HAVE_UNISTD_H && HAVE_FCNTL_H && HAVE_SIGNAL_H && HAVE_SYS_STAT_H && HAVE_SYS_SOCKET_H && HAVE_SYS_UN_H
78 #include <unistd.h>
79 #include <fcntl.h>
80 #include <signal.h>
81 #include <sys/stat.h>
82 #include <sys/socket.h>
83 #include <sys/un.h>
85 #define HAS_DAEMON 1
86 #define SOCKET_PATH "./.any2ppm"
87 #endif
89 cairo_content_t
90 cairo_boilerplate_content (cairo_content_t content)
92 if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
93 content = CAIRO_CONTENT_COLOR_ALPHA;
95 return content;
98 const char *
99 cairo_boilerplate_content_name (cairo_content_t content)
101 /* For the purpose of the content name, we don't distinguish the
102 * flattened content value.
104 switch (cairo_boilerplate_content (content)) {
105 case CAIRO_CONTENT_COLOR:
106 return "rgb24";
107 case CAIRO_CONTENT_COLOR_ALPHA:
108 return "argb32";
109 case CAIRO_CONTENT_ALPHA:
110 default:
111 assert (0); /* not reached */
112 return "---";
116 cairo_format_t
117 cairo_boilerplate_format_from_content (cairo_content_t content)
119 cairo_format_t format;
121 switch (content) {
122 case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break;
123 case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
124 case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
125 default:
126 assert (0); /* not reached */
127 format = (cairo_format_t) -1;
128 break;
131 return format;
134 static cairo_surface_t *
135 _cairo_boilerplate_image_create_surface (const char *name,
136 cairo_content_t content,
137 int width,
138 int height,
139 int max_width,
140 int max_height,
141 cairo_boilerplate_mode_t mode,
142 int id,
143 void **closure)
145 cairo_format_t format;
147 *closure = NULL;
149 if (content == CAIRO_CONTENT_COLOR_ALPHA) {
150 format = CAIRO_FORMAT_ARGB32;
151 } else if (content == CAIRO_CONTENT_COLOR) {
152 format = CAIRO_FORMAT_RGB24;
153 } else {
154 assert (0); /* not reached */
155 return NULL;
158 return cairo_image_surface_create (format, width, height);
161 cairo_surface_t *
162 _cairo_boilerplate_get_image_surface (cairo_surface_t *src,
163 int page,
164 int width,
165 int height)
167 cairo_surface_t *surface;
168 cairo_t *cr;
170 #if 0
171 if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_IMAGE) {
172 int ww = cairo_image_surface_get_width (src);
173 int hh = cairo_image_surface_get_height (src);
174 if (width == ww && hh == height) {
175 return cairo_surface_reference (src);
176 } else {
177 cairo_format_t format = cairo_image_surface_get_format (src);
178 unsigned char *data = cairo_image_surface_get_data (src);
179 int stride = cairo_image_surface_get_stride (src);
181 data += stride * (hh - height) + 4 * (ww - width);
182 return cairo_image_surface_create_for_data (data,
183 format,
184 width,
185 height,
186 stride);
189 #endif
191 if (page != 0)
192 return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
194 /* extract sub-surface */
195 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
196 cr = cairo_create (surface);
197 cairo_surface_destroy (surface);
199 cairo_set_source_surface (cr, src, 0, 0);
200 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
201 cairo_paint (cr);
203 surface = cairo_surface_reference (cairo_get_target (cr));
204 cairo_destroy (cr);
206 return surface;
209 cairo_surface_t *
210 cairo_boilerplate_get_image_surface_from_png (const char *filename,
211 int width,
212 int height,
213 cairo_bool_t flatten)
215 cairo_surface_t *surface;
217 surface = cairo_image_surface_create_from_png (filename);
219 if (flatten) {
220 cairo_t *cr;
221 cairo_surface_t *flattened;
223 flattened = cairo_image_surface_create (cairo_image_surface_get_format (surface),
224 width,
225 height);
226 cr = cairo_create (flattened);
227 cairo_surface_destroy (flattened);
229 cairo_set_source_rgb (cr, 1, 1, 1);
230 cairo_paint (cr);
232 cairo_set_source_surface (cr, surface,
233 width - cairo_image_surface_get_width (surface),
234 height - cairo_image_surface_get_height (surface));
235 cairo_paint (cr);
237 cairo_surface_destroy (surface);
238 surface = cairo_surface_reference (cairo_get_target (cr));
239 cairo_destroy (cr);
240 } else if (cairo_image_surface_get_width (surface) != width ||
241 cairo_image_surface_get_height (surface) != height)
243 cairo_t *cr;
244 cairo_surface_t *sub;
246 sub = cairo_image_surface_create (cairo_image_surface_get_format (surface),
247 width,
248 height);
249 cr = cairo_create (sub);
250 cairo_surface_destroy (sub);
252 cairo_set_source_surface (cr, surface,
253 width - cairo_image_surface_get_width (surface),
254 height - cairo_image_surface_get_height (surface));
255 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
256 cairo_paint (cr);
258 cairo_surface_destroy (surface);
259 surface = cairo_surface_reference (cairo_get_target (cr));
260 cairo_destroy (cr);
263 return surface;
266 static cairo_boilerplate_target_t targets[] =
268 /* I'm uncompromising about leaving the image backend as 0
269 * for tolerance. There shouldn't ever be anything that is out of
270 * our control here. */
271 { "image", NULL, CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA, 0,
272 _cairo_boilerplate_image_create_surface, NULL,
273 NULL,
274 _cairo_boilerplate_get_image_surface,
275 cairo_surface_write_to_png },
276 { "image", NULL, CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
277 _cairo_boilerplate_image_create_surface, NULL,
278 NULL,
279 _cairo_boilerplate_get_image_surface,
280 cairo_surface_write_to_png },
281 #ifdef CAIRO_HAS_TEST_SURFACES
282 { "test-fallback", NULL, CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
283 CAIRO_CONTENT_COLOR_ALPHA, 0,
284 _cairo_boilerplate_test_fallback_create_surface, NULL,
285 NULL,
286 _cairo_boilerplate_get_image_surface,
287 cairo_surface_write_to_png },
288 { "test-fallback", NULL, CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
289 CAIRO_CONTENT_COLOR, 0,
290 _cairo_boilerplate_test_fallback_create_surface, NULL,
291 NULL,
292 _cairo_boilerplate_get_image_surface,
293 cairo_surface_write_to_png },
294 { "test-meta", NULL, CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
295 CAIRO_CONTENT_COLOR_ALPHA, 0,
296 _cairo_boilerplate_test_meta_create_surface, NULL,
297 NULL,
298 _cairo_boilerplate_get_image_surface,
299 cairo_surface_write_to_png },
300 { "test-meta", NULL, CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
301 CAIRO_CONTENT_COLOR, 0,
302 _cairo_boilerplate_test_meta_create_surface, NULL,
303 NULL,
304 _cairo_boilerplate_get_image_surface,
305 cairo_surface_write_to_png },
306 { "test-paginated", NULL, CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
307 CAIRO_CONTENT_COLOR_ALPHA, 0,
308 _cairo_boilerplate_test_paginated_create_surface, NULL,
309 NULL,
310 _cairo_boilerplate_test_paginated_get_image_surface,
311 _cairo_boilerplate_test_paginated_surface_write_to_png,
312 _cairo_boilerplate_test_paginated_cleanup },
313 { "test-paginated", NULL, CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
314 CAIRO_CONTENT_COLOR, 0,
315 _cairo_boilerplate_test_paginated_create_surface, NULL,
316 NULL,
317 _cairo_boilerplate_test_paginated_get_image_surface,
318 _cairo_boilerplate_test_paginated_surface_write_to_png,
319 _cairo_boilerplate_test_paginated_cleanup },
320 #endif
321 #ifdef CAIRO_HAS_GLITZ_SURFACE
322 #if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE
323 { "glitz-glx", NULL, CAIRO_SURFACE_TYPE_GLITZ,CAIRO_CONTENT_COLOR_ALPHA, 0,
324 _cairo_boilerplate_glitz_glx_create_surface, NULL,
325 NULL,
326 _cairo_boilerplate_get_image_surface,
327 cairo_surface_write_to_png,
328 _cairo_boilerplate_glitz_glx_cleanup },
329 { "glitz-glx", NULL, CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
330 _cairo_boilerplate_glitz_glx_create_surface, NULL,
331 NULL,
332 _cairo_boilerplate_get_image_surface,
333 cairo_surface_write_to_png,
334 _cairo_boilerplate_glitz_glx_cleanup },
335 #endif
336 #if CAIRO_CAN_TEST_GLITZ_AGL_SURFACE
337 { "glitz-agl", NULL, CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
338 _cairo_boilerplate_glitz_agl_create_surface, NULL,
339 NULL,
340 _cairo_boilerplate_get_image_surface,
341 cairo_surface_write_to_png,
342 _cairo_boilerplate_glitz_agl_cleanup },
343 { "glitz-agl", NULL, CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
344 _cairo_boilerplate_glitz_agl_create_surface, NULL,
345 NULL,
346 _cairo_boilerplate_get_image_surface,
347 cairo_surface_write_to_png,
348 _cairo_boilerplate_glitz_agl_cleanup },
349 #endif
350 #if CAIRO_CAN_TEST_GLITZ_WGL_SURFACE
351 { "glitz-wgl", NULL, CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
352 _cairo_boilerplate_glitz_wgl_create_surface, NULL,
353 NULL,
354 _cairo_boilerplate_get_image_surface,
355 cairo_surface_write_to_png,
356 _cairo_boilerplate_glitz_wgl_cleanup },
357 { "glitz-wgl", NULL, CAIRO_SURFACE_TYPE_GLITZ, CAIRO_CONTENT_COLOR, 0,
358 _cairo_boilerplate_glitz_wgl_create_surface, NULL,
359 NULL,
360 _cairo_boilerplate_get_image_surface,
361 cairo_surface_write_to_png,
362 _cairo_boilerplate_glitz_wgl_cleanup },
363 #endif
364 #endif /* CAIRO_HAS_GLITZ_SURFACE */
365 #if CAIRO_HAS_QUARTZ_SURFACE
366 { "quartz", NULL, CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
367 _cairo_boilerplate_quartz_create_surface, NULL,
368 NULL,
369 _cairo_boilerplate_get_image_surface,
370 cairo_surface_write_to_png,
371 _cairo_boilerplate_quartz_cleanup },
372 { "quartz", NULL, CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR, 0,
373 _cairo_boilerplate_quartz_create_surface, NULL,
374 NULL,
375 _cairo_boilerplate_get_image_surface,
376 cairo_surface_write_to_png,
377 _cairo_boilerplate_quartz_cleanup },
378 #endif
379 #if CAIRO_HAS_WIN32_SURFACE
380 { "win32", NULL, CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR, 0,
381 _cairo_boilerplate_win32_create_surface, NULL,
382 NULL,
383 _cairo_boilerplate_get_image_surface,
384 cairo_surface_write_to_png },
385 /* Testing the win32 surface isn't interesting, since for
386 * ARGB images it just chains to the image backend
388 { "win32", NULL, CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR_ALPHA, 0,
389 _cairo_boilerplate_win32_create_surface, NULL,
390 NULL,
391 _cairo_boilerplate_get_image_surface,
392 cairo_surface_write_to_png },
393 #if CAIRO_CAN_TEST_WIN32_PRINTING_SURFACE
394 { "win32-printing", ".ps", CAIRO_SURFACE_TYPE_WIN32_PRINTING,
395 CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
396 _cairo_boilerplate_win32_printing_create_surface, NULL,
397 NULL,
398 _cairo_boilerplate_win32_printing_get_image_surface,
399 _cairo_boilerplate_win32_printing_surface_write_to_png,
400 _cairo_boilerplate_win32_printing_cleanup,
401 NULL, TRUE },
402 { "win32-printing", ".ps", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
403 _cairo_boilerplate_win32_printing_create_surface, NULL,
404 NULL,
405 _cairo_boilerplate_win32_printing_get_image_surface,
406 _cairo_boilerplate_win32_printing_surface_write_to_png,
407 _cairo_boilerplate_win32_printing_cleanup,
408 NULL, TRUE },
409 #endif
410 #endif
411 #if CAIRO_HAS_XCB_SURFACE
412 /* Acceleration architectures may make the results differ by a
413 * bit, so we set the error tolerance to 1. */
414 { "xcb", NULL, CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
415 _cairo_boilerplate_xcb_create_surface, NULL,
416 NULL,
417 _cairo_boilerplate_get_image_surface,
418 cairo_surface_write_to_png,
419 _cairo_boilerplate_xcb_cleanup,
420 _cairo_boilerplate_xcb_synchronize},
421 #endif
422 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
423 /* Acceleration architectures may make the results differ by a
424 * bit, so we set the error tolerance to 1. */
425 { "xlib", NULL, CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1,
426 _cairo_boilerplate_xlib_create_surface, NULL,
427 NULL,
428 _cairo_boilerplate_get_image_surface,
429 cairo_surface_write_to_png,
430 _cairo_boilerplate_xlib_cleanup,
431 _cairo_boilerplate_xlib_synchronize},
432 { "xlib", NULL, CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
433 _cairo_boilerplate_xlib_create_surface, NULL,
434 NULL,
435 _cairo_boilerplate_get_image_surface,
436 cairo_surface_write_to_png,
437 _cairo_boilerplate_xlib_cleanup,
438 _cairo_boilerplate_xlib_synchronize},
439 #endif
440 #if CAIRO_HAS_XLIB_SURFACE
441 /* This is a fallback surface which uses xlib fallbacks instead of
442 * the Render extension. */
443 { "xlib-fallback", NULL, CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
444 _cairo_boilerplate_xlib_fallback_create_surface, NULL,
445 NULL,
446 _cairo_boilerplate_get_image_surface,
447 cairo_surface_write_to_png,
448 _cairo_boilerplate_xlib_cleanup,
449 _cairo_boilerplate_xlib_synchronize},
450 #endif
451 #if CAIRO_HAS_PS_SURFACE && CAIRO_CAN_TEST_PS_SURFACE
452 { "ps2", ".ps", CAIRO_SURFACE_TYPE_PS,
453 CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
454 _cairo_boilerplate_ps2_create_surface,
455 _cairo_boilerplate_ps_force_fallbacks,
456 _cairo_boilerplate_ps_finish_surface,
457 _cairo_boilerplate_ps_get_image_surface,
458 _cairo_boilerplate_ps_surface_write_to_png,
459 _cairo_boilerplate_ps_cleanup,
460 NULL, TRUE },
461 { "ps2", ".ps", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
462 _cairo_boilerplate_ps2_create_surface,
463 _cairo_boilerplate_ps_force_fallbacks,
464 _cairo_boilerplate_ps_finish_surface,
465 _cairo_boilerplate_ps_get_image_surface,
466 _cairo_boilerplate_ps_surface_write_to_png,
467 _cairo_boilerplate_ps_cleanup,
468 NULL, TRUE },
469 { "ps3", ".ps", CAIRO_SURFACE_TYPE_PS,
470 CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
471 _cairo_boilerplate_ps3_create_surface,
472 _cairo_boilerplate_ps_force_fallbacks,
473 _cairo_boilerplate_ps_finish_surface,
474 _cairo_boilerplate_ps_get_image_surface,
475 _cairo_boilerplate_ps_surface_write_to_png,
476 _cairo_boilerplate_ps_cleanup,
477 NULL, TRUE },
478 { "ps3", ".ps", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
479 _cairo_boilerplate_ps3_create_surface,
480 _cairo_boilerplate_ps_force_fallbacks,
481 _cairo_boilerplate_ps_finish_surface,
482 _cairo_boilerplate_ps_get_image_surface,
483 _cairo_boilerplate_ps_surface_write_to_png,
484 _cairo_boilerplate_ps_cleanup,
485 NULL, TRUE },
486 #endif
487 #if CAIRO_HAS_PDF_SURFACE && CAIRO_CAN_TEST_PDF_SURFACE
488 { "pdf", ".pdf", CAIRO_SURFACE_TYPE_PDF,
489 CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
490 _cairo_boilerplate_pdf_create_surface,
491 _cairo_boilerplate_pdf_force_fallbacks,
492 _cairo_boilerplate_pdf_finish_surface,
493 _cairo_boilerplate_pdf_get_image_surface,
494 _cairo_boilerplate_pdf_surface_write_to_png,
495 _cairo_boilerplate_pdf_cleanup,
496 NULL, TRUE },
497 { "pdf", ".pdf", CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 0,
498 _cairo_boilerplate_pdf_create_surface,
499 _cairo_boilerplate_pdf_force_fallbacks,
500 _cairo_boilerplate_pdf_finish_surface,
501 _cairo_boilerplate_pdf_get_image_surface,
502 _cairo_boilerplate_pdf_surface_write_to_png,
503 _cairo_boilerplate_pdf_cleanup,
504 NULL, TRUE },
505 #endif
506 #if CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE
507 /* It seems we should be able to round-trip SVG content perfectly
508 * through librsvg and cairo, but for some mysterious reason, some
509 * systems get an error of 1 for some pixels on some of the text
510 * tests. XXX: I'd still like to chase these down at some point.
511 * For now just set the svg error tolerance to 1. */
512 { "svg11", NULL, CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1,
513 _cairo_boilerplate_svg11_create_surface,
514 _cairo_boilerplate_svg_force_fallbacks,
515 _cairo_boilerplate_svg_finish_surface,
516 _cairo_boilerplate_svg_get_image_surface,
517 _cairo_boilerplate_svg_surface_write_to_png,
518 _cairo_boilerplate_svg_cleanup,
519 NULL, TRUE },
520 { "svg11", NULL, CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 1,
521 _cairo_boilerplate_svg11_create_surface,
522 _cairo_boilerplate_svg_force_fallbacks,
523 _cairo_boilerplate_svg_finish_surface,
524 _cairo_boilerplate_svg_get_image_surface,
525 _cairo_boilerplate_svg_surface_write_to_png,
526 _cairo_boilerplate_svg_cleanup,
527 NULL, TRUE },
528 /* Disable the svg12 testing for the 1.8.2 release, but in a way that it
529 * will come back on immediately afterward even if we forget to remove
530 * this condition. */
531 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 0)
532 { "svg12", NULL, CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1,
533 _cairo_boilerplate_svg12_create_surface,
534 _cairo_boilerplate_svg_force_fallbacks,
535 _cairo_boilerplate_svg_finish_surface,
536 _cairo_boilerplate_svg_get_image_surface,
537 _cairo_boilerplate_svg_surface_write_to_png,
538 _cairo_boilerplate_svg_cleanup,
539 NULL, TRUE },
540 { "svg12", NULL, CAIRO_INTERNAL_SURFACE_TYPE_META, CAIRO_CONTENT_COLOR, 1,
541 _cairo_boilerplate_svg12_create_surface,
542 _cairo_boilerplate_svg_force_fallbacks,
543 _cairo_boilerplate_svg_finish_surface,
544 _cairo_boilerplate_svg_get_image_surface,
545 _cairo_boilerplate_svg_surface_write_to_png,
546 _cairo_boilerplate_svg_cleanup,
547 NULL, TRUE },
548 #endif
549 #endif
550 #if CAIRO_HAS_BEOS_SURFACE
551 /* BeOS sometimes produces a slightly different image. Perhaps this
552 * is related to the fact that it doesn't use premultiplied alpha...
553 * Just ignore the small difference. */
554 { "beos", NULL, CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR, 1,
555 _cairo_boilerplate_beos_create_surface, NULL,
556 NULL,
557 _cairo_boilerplate_get_image_surface,
558 cairo_surface_write_to_png,
559 _cairo_boilerplate_beos_cleanup},
560 { "beos-bitmap", NULL, CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR, 1,
561 _cairo_boilerplate_beos_create_surface_for_bitmap, NULL,
562 NULL,
563 _cairo_boilerplate_get_image_surface,
564 cairo_surface_write_to_png,
565 _cairo_boilerplate_beos_cleanup_bitmap},
566 { "beos-bitmap", NULL, CAIRO_SURFACE_TYPE_BEOS, CAIRO_CONTENT_COLOR_ALPHA, 1,
567 _cairo_boilerplate_beos_create_surface_for_bitmap, NULL,
568 NULL,
569 _cairo_boilerplate_get_image_surface,
570 cairo_surface_write_to_png,
571 _cairo_boilerplate_beos_cleanup_bitmap},
572 #endif
575 #if CAIRO_HAS_DIRECTFB_SURFACE
576 { "directfb", NULL, CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR, 0,
577 _cairo_boilerplate_directfb_create_surface, NULL,
578 NULL,
579 _cairo_boilerplate_get_image_surface,
580 cairo_surface_write_to_png,
581 _cairo_boilerplate_directfb_cleanup},
582 { "directfb-bitmap", NULL, CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR_ALPHA, 0,
583 _cairo_boilerplate_directfb_create_surface, NULL,
584 NULL,
585 _cairo_boilerplate_get_image_surface,
586 cairo_surface_write_to_png,
587 _cairo_boilerplate_directfb_cleanup},
588 #endif
591 cairo_boilerplate_target_t **
592 cairo_boilerplate_get_targets (int *pnum_targets, cairo_bool_t *plimited_targets)
594 size_t i, num_targets;
595 cairo_bool_t limited_targets = FALSE;
596 const char *tname;
597 cairo_boilerplate_target_t **targets_to_test;
599 if ((tname = getenv ("CAIRO_TEST_TARGET")) != NULL && *tname) {
600 /* check the list of targets specified by the user */
601 limited_targets = TRUE;
603 num_targets = 0;
604 targets_to_test = NULL;
606 while (*tname) {
607 int found = 0;
608 const char *end = strpbrk (tname, " \t\r\n;:,");
609 if (!end)
610 end = tname + strlen (tname);
612 if (end == tname) {
613 tname = end + 1;
614 continue;
617 for (i = 0; i < sizeof (targets) / sizeof (targets[0]); i++) {
618 if (0 == strncmp (targets[i].name, tname, end - tname) &&
619 !isalnum (targets[i].name[end - tname])) {
620 /* realloc isn't exactly the best thing here, but meh. */
621 targets_to_test = xrealloc (targets_to_test, sizeof(cairo_boilerplate_target_t *) * (num_targets+1));
622 targets_to_test[num_targets++] = &targets[i];
623 found = 1;
627 if (!found) {
628 fprintf (stderr, "Cannot find target '%.*s'\n", (int)(end - tname), tname);
629 exit(-1);
632 if (*end)
633 end++;
634 tname = end;
636 } else {
637 /* check all compiled in targets */
638 num_targets = sizeof (targets) / sizeof (targets[0]);
639 targets_to_test = xmalloc (sizeof(cairo_boilerplate_target_t*) * num_targets);
640 for (i = 0; i < num_targets; i++) {
641 targets_to_test[i] = &targets[i];
645 /* exclude targets as specified by the user */
646 if ((tname = getenv ("CAIRO_TEST_TARGET_EXCLUDE")) != NULL && *tname) {
647 limited_targets = TRUE;
649 while (*tname) {
650 int j;
651 const char *end = strpbrk (tname, " \t\r\n;:,");
652 if (!end)
653 end = tname + strlen (tname);
655 if (end == tname) {
656 tname = end + 1;
657 continue;
660 for (i = j = 0; i < num_targets; i++) {
661 if (strncmp (targets_to_test[i]->name, tname, end - tname) ||
662 isalnum (targets_to_test[i]->name[end - tname]))
664 targets_to_test[j++] = targets_to_test[i];
667 num_targets = j;
669 if (*end)
670 end++;
671 tname = end;
675 if (pnum_targets)
676 *pnum_targets = num_targets;
678 if (plimited_targets)
679 *plimited_targets = limited_targets;
681 return targets_to_test;
684 void
685 cairo_boilerplate_free_targets (cairo_boilerplate_target_t **targets)
687 free (targets);
690 cairo_surface_t *
691 cairo_boilerplate_surface_create_in_error (cairo_status_t status)
693 cairo_surface_t *surface = NULL;
694 int loop = 5;
696 do {
697 cairo_surface_t *intermediate;
698 cairo_t *cr;
699 cairo_path_t path;
701 intermediate = cairo_image_surface_create (CAIRO_FORMAT_A8, 0, 0);
702 cr = cairo_create (intermediate);
703 cairo_surface_destroy (intermediate);
705 path.status = status;
706 cairo_append_path (cr, &path);
708 cairo_surface_destroy (surface);
709 surface = cairo_surface_reference (cairo_get_target (cr));
710 cairo_destroy (cr);
711 } while (cairo_surface_status (surface) != status && --loop);
713 return surface;
716 void
717 cairo_boilerplate_scaled_font_set_max_glyphs_cached (cairo_scaled_font_t *scaled_font,
718 int max_glyphs)
720 if (cairo_scaled_font_status (scaled_font))
721 return;
723 scaled_font->glyphs->max_size = max_glyphs;
726 #if HAS_DAEMON
727 static int
728 any2ppm_daemon_exists (void)
730 struct stat st;
731 int fd;
732 char buf[80];
733 int pid;
734 int ret;
736 if (stat (SOCKET_PATH, &st) < 0)
737 return 0;
739 fd = open (SOCKET_PATH ".pid", O_RDONLY);
740 if (fd < 0)
741 return 0;
743 pid = 0;
744 ret = read (fd, buf, sizeof (buf) - 1);
745 if (ret > 0) {
746 buf[ret] = '\0';
747 pid = atoi (buf);
749 close (fd);
751 return pid > 0 && kill (pid, 0) != -1;
753 #endif
755 FILE *
756 cairo_boilerplate_open_any2ppm (const char *filename,
757 int page,
758 unsigned int flags)
760 char command[4096];
761 #if HAS_DAEMON
762 int sk;
763 struct sockaddr_un addr;
764 int len;
766 if (flags & CAIRO_BOILERPLATE_OPEN_NO_DAEMON)
767 goto POPEN;
769 if (! any2ppm_daemon_exists ()) {
770 if (system ("./any2ppm") != 0)
771 goto POPEN;
774 sk = socket (PF_UNIX, SOCK_STREAM, 0);
775 if (sk == -1)
776 goto POPEN;
778 memset (&addr, 0, sizeof (addr));
779 addr.sun_family = AF_UNIX;
780 strcpy (addr.sun_path, SOCKET_PATH);
782 if (connect (sk, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
783 close (sk);
784 goto POPEN;
787 len = sprintf (command, "%s %d\n", filename, page);
788 if (write (sk, command, len) != len) {
789 close (sk);
790 goto POPEN;
793 return fdopen (sk, "r");
795 POPEN:
796 #endif
797 sprintf (command, "./any2ppm %s %d", filename, page);
798 return popen (command, "r");
801 static cairo_bool_t
802 freadn (unsigned char *buf, int len, FILE *file)
804 int ret;
806 while (len) {
807 ret = fread (buf, 1, len, file);
808 if (ret != len) {
809 if (ferror (file) || feof (file))
810 return FALSE;
812 len -= ret;
813 buf += len;
816 return TRUE;
819 cairo_surface_t *
820 cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file)
822 char format;
823 int width, height, stride;
824 int x, y;
825 unsigned char *data;
826 cairo_surface_t *image = NULL;
828 if (fscanf (file, "P%c %d %d 255\n", &format, &width, &height) != 3)
829 goto FAIL;
831 switch (format) {
832 case '7': /* XXX */
833 image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
834 break;
835 case '6':
836 image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
837 break;
838 case '5':
839 image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
840 break;
841 default:
842 goto FAIL;
844 if (cairo_surface_status (image))
845 goto FAIL;
847 data = cairo_image_surface_get_data (image);
848 stride = cairo_image_surface_get_stride (image);
849 for (y = 0; y < height; y++) {
850 unsigned char *buf = data + y *stride;
851 switch (format) {
852 case '7':
853 if (! freadn (buf, 4 * width, file))
854 goto FAIL;
855 break;
856 case '6':
857 for (x = 0; x < width; x++) {
858 if (! freadn (buf, 3, file))
859 goto FAIL;
860 buf += 4;
862 break;
863 case '5':
864 if (! freadn (buf, width, file))
865 goto FAIL;
866 break;
870 return image;
872 FAIL:
873 cairo_surface_destroy (image);
874 return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
877 cairo_surface_t *
878 cairo_boilerplate_convert_to_image (const char *filename, int page)
880 FILE *file;
881 unsigned int flags = 0;
882 cairo_surface_t *image;
884 RETRY:
885 file = cairo_boilerplate_open_any2ppm (filename, page, flags);
886 if (file == NULL)
887 return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
889 image = cairo_boilerplate_image_surface_create_from_ppm_stream (file);
890 fclose (file);
892 if (cairo_surface_status (image) == CAIRO_STATUS_READ_ERROR) {
893 if (flags == 0) {
894 /* Try again in process, e.g. to propagate a CRASH. */
895 cairo_surface_destroy (image);
896 flags = CAIRO_BOILERPLATE_OPEN_NO_DAEMON;
897 goto RETRY;
901 return image;
905 cairo_boilerplate_version (void)
907 return CAIRO_VERSION;
910 const char*
911 cairo_boilerplate_version_string (void)
913 return CAIRO_VERSION_STRING;