summaryrefslogtreecommitdiff
path: root/boilerplate
diff options
context:
space:
mode:
Diffstat (limited to 'boilerplate')
-rwxr-xr-xboilerplate/.gitignore24
-rwxr-xr-xboilerplate/Makefile.am76
-rwxr-xr-xboilerplate/Makefile.sources43
-rwxr-xr-xboilerplate/Makefile.win3224
-rwxr-xr-xboilerplate/Makefile.win32.features586
-rwxr-xr-xboilerplate/README14
-rwxr-xr-xboilerplate/cairo-boilerplate-beos.cpp273
-rwxr-xr-xboilerplate/cairo-boilerplate-cogl.c206
-rwxr-xr-xboilerplate/cairo-boilerplate-directfb.c235
-rwxr-xr-xboilerplate/cairo-boilerplate-drm.c106
-rwxr-xr-xboilerplate/cairo-boilerplate-egl.c184
-rwxr-xr-xboilerplate/cairo-boilerplate-evas-gl.c143
-rwxr-xr-xboilerplate/cairo-boilerplate-getopt.c247
-rwxr-xr-xboilerplate/cairo-boilerplate-getopt.h63
-rwxr-xr-xboilerplate/cairo-boilerplate-glx.c454
-rwxr-xr-xboilerplate/cairo-boilerplate-pdf.c280
-rwxr-xr-xboilerplate/cairo-boilerplate-private.h53
-rwxr-xr-xboilerplate/cairo-boilerplate-ps.c369
-rwxr-xr-xboilerplate/cairo-boilerplate-qt.cpp114
-rwxr-xr-xboilerplate/cairo-boilerplate-quartz.c76
-rwxr-xr-xboilerplate/cairo-boilerplate-scaled-font.h34
-rwxr-xr-xboilerplate/cairo-boilerplate-script.c141
-rwxr-xr-xboilerplate/cairo-boilerplate-skia.c55
-rwxr-xr-xboilerplate/cairo-boilerplate-svg.c344
-rwxr-xr-xboilerplate/cairo-boilerplate-system.c166
-rwxr-xr-xboilerplate/cairo-boilerplate-system.h59
-rwxr-xr-xboilerplate/cairo-boilerplate-test-surfaces.c462
-rwxr-xr-xboilerplate/cairo-boilerplate-tg.c81
-rwxr-xr-xboilerplate/cairo-boilerplate-vg.c363
-rwxr-xr-xboilerplate/cairo-boilerplate-wgl.c239
-rwxr-xr-xboilerplate/cairo-boilerplate-win32-printing.c407
-rwxr-xr-xboilerplate/cairo-boilerplate-win32.c77
-rwxr-xr-xboilerplate/cairo-boilerplate-xcb.c876
-rwxr-xr-xboilerplate/cairo-boilerplate-xlib.c632
-rwxr-xr-xboilerplate/cairo-boilerplate-xlib.h33
-rwxr-xr-xboilerplate/cairo-boilerplate.c989
-rwxr-xr-xboilerplate/cairo-boilerplate.h243
-rwxr-xr-xboilerplate/check-link.c24
-rwxr-xr-xboilerplate/make-cairo-boilerplate-constructors.sh29
39 files changed, 8824 insertions, 0 deletions
diff --git a/boilerplate/.gitignore b/boilerplate/.gitignore
new file mode 100755
index 000000000..a81663b80
--- /dev/null
+++ b/boilerplate/.gitignore
@@ -0,0 +1,24 @@
+TAGS
+tags
+Makefile
+Makefile.in
+Makefile.am.features
+#Makefile.win32.features
+*.lo
+*.la
+*.exe
+*.manifest
+*.o
+*.gcda
+*.gcno
+*.obj
+*.ilk
+*.suo
+*.lib
+*.pdb
+*~
+.*.sw?
+check-link
+cairo-boilerplate-constructors.c
+cairo-boilerplate-constructors
+make-cairo-boilerplate-constructors
diff --git a/boilerplate/Makefile.am b/boilerplate/Makefile.am
new file mode 100755
index 000000000..29ad015ac
--- /dev/null
+++ b/boilerplate/Makefile.am
@@ -0,0 +1,76 @@
+# Note: All source files are listed in Makefile.sources.
+
+include $(top_srcdir)/build/Makefile.am.common
+include $(srcdir)/Makefile.am.features
+
+EXTRA_DIST += Makefile.win32 Makefile.win32.features
+#MAINTAINERCLEANFILES += $(srcdir)/Makefile.win32.features
+
+AM_CPPFLAGS = \
+ -I$(srcdir) \
+ -I$(top_builddir)/src \
+ -I$(top_srcdir)/src \
+ $(CAIRO_CFLAGS) \
+ $(NULL)
+AM_LDFLAGS = $(CAIRO_LDFLAGS)
+
+if BUILD_CXX
+cxx_boilerplate_lib = libcairoboilerplate_cxx.la
+else
+cxx_boilerplate_lib =
+endif
+
+EXTRA_LTLIBRARIES += libcairoboilerplate.la $(cxx_boilerplate_lib)
+
+
+libcairoboilerplate_la_SOURCES = \
+ $(enabled_cairo_boilerplate_headers) \
+ $(enabled_cairo_boilerplate_private) \
+ $(enabled_cairo_boilerplate_sources) \
+ cairo-boilerplate-constructors.c \
+ $(NULL)
+libcairoboilerplate_cxx_la_SOURCES = \
+ $(enabled_cairo_boilerplate_cxx_sources) \
+ $(NULL)
+libcairoboilerplate_la_LIBADD = $(top_builddir)/src/libcairo.la \
+ $(cxx_boilerplate_lib) \
+ $(CAIRO_LIBS) \
+ $(CAIROBOILERPLATE_LIBS) \
+ $(NULL)
+libcairoboilerplate_cxx_la_LIBADD = $(top_builddir)/src/libcairo.la \
+ $(CAIRO_LIBS) \
+ $(CAIROBOILERPLATE_LIBS) \
+ $(NULL)
+libcairoboilerplate_la_DEPENDENCIES = \
+ $(cxx_boilerplate_lib) \
+ $(NULL)
+
+if CAIRO_HAS_DL
+libcairoboilerplate_la_LIBADD += -ldl
+endif
+
+if CAIRO_HAS_BEOS_SURFACE
+# BeOS system headers trigger this warning
+libcairoboilerplate_cxx_la_CXXFLAGS = -Wno-multichar
+endif
+
+if CAIRO_HAS_WIN32_SURFACE
+libcairoboilerplate_la_LIBADD += -lwinspool
+endif
+
+cairo-boilerplate-constructors.c: Makefile $(enabled_cairo_boilerplate_sources) $(enabled_cairo_boilerplate_cxx_sources) make-cairo-boilerplate-constructors.sh
+ (cd $(srcdir) && sh ./make-cairo-boilerplate-constructors.sh $(enabled_cairo_boilerplate_sources) $(enabled_cairo_boilerplate_cxx_sources)) > $@
+
+BUILT_SOURCES += cairo-boilerplate-constructors.c
+EXTRA_DIST += $(BUILT_SOURCES) make-cairo-boilerplate-constructors.sh
+CLEANFILES += $(BUILT_SOURCES)
+
+test: check
+
+if CROSS_COMPILING
+else
+TESTS += check-link$(EXEEXT)
+endif
+
+check_PROGRAMS += check-link
+check_link_LDADD = libcairoboilerplate.la
diff --git a/boilerplate/Makefile.sources b/boilerplate/Makefile.sources
new file mode 100755
index 000000000..e0fdb4e99
--- /dev/null
+++ b/boilerplate/Makefile.sources
@@ -0,0 +1,43 @@
+# Makefile.sources
+#
+# This file is pretty similar to $(top_srcdir)/src/Makefile.sources,
+# but for boilerplate. Unlike that file, there are no special headers.
+#
+
+cairo_boilerplate_headers = \
+ cairo-boilerplate-getopt.h \
+ cairo-boilerplate-scaled-font.h \
+ cairo-boilerplate-system.h \
+ cairo-boilerplate.h \
+ $(NULL)
+cairo_boilerplate_sources = \
+ cairo-boilerplate-getopt.c \
+ cairo-boilerplate-system.c \
+ cairo-boilerplate.c \
+ $(NULL)
+cairo_boilerplate_private = \
+ cairo-boilerplate-private.h \
+ $(NULL)
+
+cairo_boilerplate_beos_cxx_sources = cairo-boilerplate-beos.cpp
+cairo_boilerplate_directfb_sources = cairo-boilerplate-directfb.c
+cairo_boilerplate_drm_sources = cairo-boilerplate-drm.c
+cairo_boilerplate_glx_sources = cairo-boilerplate-glx.c
+cairo_boilerplate_wgl_sources = cairo-boilerplate-wgl.c
+cairo_boilerplate_egl_sources = cairo-boilerplate-egl.c
+cairo_boilerplate_evasgl_sources = cairo-boilerplate-evas-gl.c
+cairo_boilerplate_pdf_sources = cairo-boilerplate-pdf.c
+cairo_boilerplate_ps_sources = cairo-boilerplate-ps.c
+cairo_boilerplate_qt_cxx_sources = cairo-boilerplate-qt.cpp
+cairo_boilerplate_quartz_sources = cairo-boilerplate-quartz.c
+cairo_boilerplate_script_sources = cairo-boilerplate-script.c
+cairo_boilerplate_skia_sources = cairo-boilerplate-skia.c
+cairo_boilerplate_svg_sources = cairo-boilerplate-svg.c
+cairo_boilerplate_test_surfaces_sources = cairo-boilerplate-test-surfaces.c
+cairo_boilerplate_win32_sources = cairo-boilerplate-win32.c cairo-boilerplate-win32-printing.c
+cairo_boilerplate_xcb_sources = cairo-boilerplate-xcb.c
+cairo_boilerplate_xlib_headers = cairo-boilerplate-xlib.h
+cairo_boilerplate_xlib_sources = cairo-boilerplate-xlib.c
+cairo_boilerplate_vg_sources = cairo-boilerplate-vg.c
+cairo_boilerplate_cogl_sources = cairo-boilerplate-cogl.c
+cairo_boilerplate_tg_sources = cairo-boilerplate-tg.c
diff --git a/boilerplate/Makefile.win32 b/boilerplate/Makefile.win32
new file mode 100755
index 000000000..29df5cf79
--- /dev/null
+++ b/boilerplate/Makefile.win32
@@ -0,0 +1,24 @@
+top_srcdir = ..
+include $(top_srcdir)/build/Makefile.win32.common
+include Makefile.win32.features
+
+HEADERS = \
+ $(enabled_cairo_boilerplate_headers) \
+ $(enabled_cairo_boilerplate_private) \
+ $(NULL)
+
+SOURCES = \
+ $(enabled_cairo_boilerplate_sources) \
+ cairo-boilerplate-constructors.c \
+ $(NULL)
+
+OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(SOURCES))
+
+cairo-boilerplate-constructors.c: Makefile.sources Makefile.win32 $(enabled_cairo_boilerplate_sources) make-cairo-boilerplate-constructors.sh
+ sh ./make-cairo-boilerplate-constructors.sh $(enabled_cairo_boilerplate_sources) > $@
+
+all: $(CFG)/boiler.lib
+
+
+$(CFG)/boiler.lib: $(OBJECTS)
+ @$(AR) $(CAIRO_ARFLAGS) -OUT:$@ $(OBJECTS)
diff --git a/boilerplate/Makefile.win32.features b/boilerplate/Makefile.win32.features
new file mode 100755
index 000000000..8efe8562c
--- /dev/null
+++ b/boilerplate/Makefile.win32.features
@@ -0,0 +1,586 @@
+# Generated by configure. Do not edit.
+
+ifeq ($(top_srcdir),)
+include Makefile.sources
+else
+include $(top_srcdir)/boilerplate/Makefile.sources
+endif
+
+supported_cairo_boilerplate_headers = $(cairo_boilerplate_headers)
+unsupported_cairo_boilerplate_headers =
+all_cairo_boilerplate_headers = $(cairo_boilerplate_headers)
+all_cairo_boilerplate_private = $(cairo_boilerplate_private)
+all_cairo_boilerplate_cxx_sources = $(cairo_boilerplate_cxx_sources)
+all_cairo_boilerplate_sources = $(cairo_boilerplate_sources)
+
+enabled_cairo_boilerplate_headers = $(cairo_boilerplate_headers)
+enabled_cairo_boilerplate_private = $(cairo_boilerplate_private)
+enabled_cairo_boilerplate_cxx_sources = $(cairo_boilerplate_cxx_sources)
+enabled_cairo_boilerplate_sources = $(cairo_boilerplate_sources)
+
+
+all_cairo_boilerplate_private += $(cairo_boilerplate_tls_private) $(cairo_boilerplate_tls_headers)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_tls_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_tls_sources)
+ifeq ($(CAIRO_HAS_TLS),1)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_tls_private) $(cairo_boilerplate_tls_headers)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_tls_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_tls_sources)
+endif
+
+all_cairo_boilerplate_private += $(cairo_boilerplate_pthread_setspecific_private) $(cairo_boilerplate_pthread_setspecific_headers)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_pthread_setspecific_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_pthread_setspecific_sources)
+ifeq ($(CAIRO_HAS_PTHREAD_SETSPECIFIC),1)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_pthread_setspecific_private) $(cairo_boilerplate_pthread_setspecific_headers)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_pthread_setspecific_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_pthread_setspecific_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_xlib_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xlib_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_xlib_sources)
+ifeq ($(CAIRO_HAS_XLIB_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_xlib_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xlib_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_xlib_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_xrender_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_xrender_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_xlib_xrender_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xlib_xrender_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_xlib_xrender_sources)
+ifeq ($(CAIRO_HAS_XLIB_XRENDER_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_xrender_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_xlib_xrender_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xlib_xrender_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_xlib_xrender_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_xcb_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_xcb_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_xcb_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xcb_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_xcb_sources)
+ifeq ($(CAIRO_HAS_XCB_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_xcb_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_xcb_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xcb_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_xcb_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_xcb_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_xcb_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_xlib_xcb_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xlib_xcb_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_xlib_xcb_sources)
+ifeq ($(CAIRO_HAS_XLIB_XCB_FUNCTIONS),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_xlib_xcb_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_xlib_xcb_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xlib_xcb_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_xlib_xcb_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_xcb_shm_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_xcb_shm_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_xcb_shm_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xcb_shm_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_xcb_shm_sources)
+ifeq ($(CAIRO_HAS_XCB_SHM_FUNCTIONS),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_xcb_shm_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_xcb_shm_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xcb_shm_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_xcb_shm_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_qt_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_qt_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_qt_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_qt_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_qt_sources)
+ifeq ($(CAIRO_HAS_QT_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_qt_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_qt_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_qt_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_qt_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_quartz_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_quartz_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_quartz_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_quartz_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_quartz_sources)
+ifeq ($(CAIRO_HAS_QUARTZ_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_quartz_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_quartz_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_quartz_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_quartz_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_quartz_font_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_quartz_font_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_quartz_font_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_quartz_font_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_quartz_font_sources)
+ifeq ($(CAIRO_HAS_QUARTZ_FONT),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_quartz_font_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_quartz_font_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_quartz_font_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_quartz_font_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_quartz_image_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_quartz_image_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_quartz_image_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_quartz_image_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_quartz_image_sources)
+ifeq ($(CAIRO_HAS_QUARTZ_IMAGE_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_quartz_image_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_quartz_image_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_quartz_image_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_quartz_image_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_win32_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_win32_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_win32_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_win32_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_win32_sources)
+ifeq ($(CAIRO_HAS_WIN32_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_win32_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_win32_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_win32_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_win32_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_win32_font_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_win32_font_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_win32_font_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_win32_font_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_win32_font_sources)
+ifeq ($(CAIRO_HAS_WIN32_FONT),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_win32_font_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_win32_font_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_win32_font_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_win32_font_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_skia_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_skia_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_skia_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_skia_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_skia_sources)
+ifeq ($(CAIRO_HAS_SKIA_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_skia_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_skia_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_skia_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_skia_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_os2_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_os2_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_os2_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_os2_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_os2_sources)
+ifeq ($(CAIRO_HAS_OS2_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_os2_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_os2_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_os2_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_os2_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_beos_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_beos_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_beos_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_beos_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_beos_sources)
+ifeq ($(CAIRO_HAS_BEOS_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_beos_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_beos_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_beos_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_beos_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_drm_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_drm_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_drm_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_drm_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_drm_sources)
+ifeq ($(CAIRO_HAS_DRM_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_drm_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_drm_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_drm_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_drm_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_gallium_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_gallium_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_gallium_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_gallium_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_gallium_sources)
+ifeq ($(CAIRO_HAS_GALLIUM_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_gallium_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_gallium_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_gallium_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_gallium_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_png_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_png_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_png_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_png_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_png_sources)
+ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_png_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_png_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_png_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_png_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_gl_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_gl_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_gl_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_gl_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_gl_sources)
+ifeq ($(CAIRO_HAS_GL_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_gl_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_gl_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_gl_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_gl_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_evasgl_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_evasgl_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_evasgl_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_evasgl_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_evasgl_sources)
+ifeq ($(CAIRO_HAS_EVASGL_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_evasgl_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_evasgl_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_evasgl_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_evasgl_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_glesv2_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_glesv2_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_glesv2_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_glesv2_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_glesv2_sources)
+ifeq ($(CAIRO_HAS_GLESV2_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_glesv2_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_glesv2_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_glesv2_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_glesv2_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_glesv3_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_glesv3_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_glesv3_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_glesv3_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_glesv3_sources)
+ifeq ($(CAIRO_HAS_GLESV3_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_glesv3_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_glesv3_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_glesv3_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_glesv3_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_cogl_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_cogl_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_cogl_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_cogl_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_cogl_sources)
+ifeq ($(CAIRO_HAS_COGL_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_cogl_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_cogl_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_cogl_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_cogl_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_directfb_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_directfb_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_directfb_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_directfb_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_directfb_sources)
+ifeq ($(CAIRO_HAS_DIRECTFB_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_directfb_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_directfb_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_directfb_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_directfb_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_tg_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_tg_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_tg_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_tg_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_tg_sources)
+ifeq ($(CAIRO_HAS_TG_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_tg_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_tg_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_tg_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_tg_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_vg_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_vg_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_vg_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_vg_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_vg_sources)
+ifeq ($(CAIRO_HAS_VG_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_vg_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_vg_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_vg_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_vg_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_egl_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_egl_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_egl_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_egl_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_egl_sources)
+ifeq ($(CAIRO_HAS_EGL_FUNCTIONS),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_egl_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_egl_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_egl_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_egl_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_glx_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_glx_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_glx_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_glx_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_glx_sources)
+ifeq ($(CAIRO_HAS_GLX_FUNCTIONS),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_glx_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_glx_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_glx_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_glx_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_wgl_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_wgl_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_wgl_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_wgl_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_wgl_sources)
+ifeq ($(CAIRO_HAS_WGL_FUNCTIONS),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_wgl_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_wgl_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_wgl_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_wgl_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_script_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_script_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_script_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_script_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_script_sources)
+ifeq ($(CAIRO_HAS_SCRIPT_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_script_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_script_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_script_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_script_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_ft_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_ft_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_ft_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_ft_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_ft_sources)
+ifeq ($(CAIRO_HAS_FT_FONT),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_ft_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_ft_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_ft_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_ft_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_fc_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_fc_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_fc_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_fc_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_fc_sources)
+ifeq ($(CAIRO_HAS_FC_FONT),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_fc_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_fc_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_fc_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_fc_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_ps_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_ps_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_ps_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_ps_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_ps_sources)
+ifeq ($(CAIRO_HAS_PS_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_ps_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_ps_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_ps_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_ps_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_pdf_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_pdf_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_pdf_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_pdf_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_pdf_sources)
+ifeq ($(CAIRO_HAS_PDF_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_pdf_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_pdf_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_pdf_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_pdf_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_svg_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_svg_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_svg_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_svg_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_svg_sources)
+ifeq ($(CAIRO_HAS_SVG_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_svg_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_svg_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_svg_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_svg_sources)
+endif
+
+all_cairo_boilerplate_private += $(cairo_boilerplate_test_surfaces_private) $(cairo_boilerplate_test_surfaces_headers)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_test_surfaces_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_test_surfaces_sources)
+ifeq ($(CAIRO_HAS_TEST_SURFACES),1)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_test_surfaces_private) $(cairo_boilerplate_test_surfaces_headers)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_test_surfaces_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_test_surfaces_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_image_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_image_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_image_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_image_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_image_sources)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_image_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_image_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_image_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_image_sources)
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_mime_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_mime_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_mime_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_mime_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_mime_sources)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_mime_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_mime_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_mime_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_mime_sources)
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_recording_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_recording_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_recording_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_recording_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_recording_sources)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_recording_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_recording_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_recording_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_recording_sources)
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_observer_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_observer_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_observer_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_observer_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_observer_sources)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_observer_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_observer_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_observer_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_observer_sources)
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_tee_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_tee_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_tee_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_tee_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_tee_sources)
+ifeq ($(CAIRO_HAS_TEE_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_tee_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_tee_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_tee_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_tee_sources)
+endif
+
+unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_xml_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_xml_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_xml_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xml_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_xml_sources)
+ifeq ($(CAIRO_HAS_XML_SURFACE),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_xml_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_xml_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_xml_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_xml_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_user_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_user_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_user_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_user_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_user_sources)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_user_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_user_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_user_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_user_sources)
+
+all_cairo_boilerplate_private += $(cairo_boilerplate_openmp_private) $(cairo_boilerplate_openmp_headers)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_openmp_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_openmp_sources)
+ifeq ($(CAIRO_HAS_OPENMP),1)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_openmp_private) $(cairo_boilerplate_openmp_headers)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_openmp_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_openmp_sources)
+endif
+
+all_cairo_boilerplate_private += $(cairo_boilerplate_pthread_private) $(cairo_boilerplate_pthread_headers)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_pthread_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_pthread_sources)
+ifeq ($(CAIRO_HAS_PTHREAD),1)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_pthread_private) $(cairo_boilerplate_pthread_headers)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_pthread_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_pthread_sources)
+endif
+
+supported_cairo_boilerplate_headers += $(cairo_boilerplate_gobject_headers)
+all_cairo_boilerplate_headers += $(cairo_boilerplate_gobject_headers)
+all_cairo_boilerplate_private += $(cairo_boilerplate_gobject_private)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_gobject_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_gobject_sources)
+ifeq ($(CAIRO_HAS_GOBJECT_FUNCTIONS),1)
+enabled_cairo_boilerplate_headers += $(cairo_boilerplate_gobject_headers)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_gobject_private)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_gobject_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_gobject_sources)
+endif
+
+all_cairo_boilerplate_private += $(cairo_boilerplate_trace_private) $(cairo_boilerplate_trace_headers)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_trace_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_trace_sources)
+ifeq ($(CAIRO_HAS_TRACE),1)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_trace_private) $(cairo_boilerplate_trace_headers)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_trace_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_trace_sources)
+endif
+
+all_cairo_boilerplate_private += $(cairo_boilerplate_interpreter_private) $(cairo_boilerplate_interpreter_headers)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_interpreter_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_interpreter_sources)
+ifeq ($(CAIRO_HAS_INTERPRETER),1)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_interpreter_private) $(cairo_boilerplate_interpreter_headers)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_interpreter_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_interpreter_sources)
+endif
+
+all_cairo_boilerplate_private += $(cairo_boilerplate_symbol_lookup_private) $(cairo_boilerplate_symbol_lookup_headers)
+all_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_symbol_lookup_cxx_sources)
+all_cairo_boilerplate_sources += $(cairo_boilerplate_symbol_lookup_sources)
+ifeq ($(CAIRO_HAS_SYMBOL_LOOKUP),1)
+enabled_cairo_boilerplate_private += $(cairo_boilerplate_symbol_lookup_private) $(cairo_boilerplate_symbol_lookup_headers)
+enabled_cairo_boilerplate_cxx_sources += $(cairo_boilerplate_symbol_lookup_cxx_sources)
+enabled_cairo_boilerplate_sources += $(cairo_boilerplate_symbol_lookup_sources)
+endif
diff --git a/boilerplate/README b/boilerplate/README
new file mode 100755
index 000000000..2a27c415c
--- /dev/null
+++ b/boilerplate/README
@@ -0,0 +1,14 @@
+This directory provides code that is common to both of cairo's tests
+suites:
+
+ * The test suite for correctness in test/
+ * The test suite for performance in perf/
+
+We call it boilerplate as it consists primarily of the boilerplate
+code necessary for initializing a backend in order to create a surface
+for that backend.
+
+The code here just might be useful for someone looking to get started
+writing cairo code to use a particular backend, (but there are no
+promises that the boilerplate code found here for any particular
+backend is exemplary).
diff --git a/boilerplate/cairo-boilerplate-beos.cpp b/boilerplate/cairo-boilerplate-beos.cpp
new file mode 100755
index 000000000..8a1b1afb5
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-beos.cpp
@@ -0,0 +1,273 @@
+/* vim:set ts=8 sw=4 noet cin: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Takashi Toyoshima <toyoshim@be-in.org>
+ * Fredrik Holmqvist <thesuckiestemail@yahoo.se>
+ * Christian Biesinger <cbiesinger@web.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "cairo-boilerplate.h"
+#include <cairo-beos.h>
+
+// Part of this code was originally part of
+// xpfe/bootstrap/nsNativeAppSupportBeOS.cpp in the Mozilla source code.
+
+#include <Application.h>
+#include <Window.h>
+#include <View.h>
+#include <Bitmap.h>
+
+class CairoTestWindow : public BWindow
+{
+public:
+ CairoTestWindow(BRect frame, const char* title);
+ virtual ~CairoTestWindow();
+ BView* View() const { return mView; }
+private:
+ BView* mView;
+};
+
+CairoTestWindow::CairoTestWindow(BRect frame, const char* title)
+ : BWindow(frame, title, B_TITLED_WINDOW,
+ B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
+{
+ mView = new BView(frame, "CairoWindowTestView", B_FOLLOW_ALL_SIDES, 0);
+ AddChild(mView);
+ Show();
+
+ // Make sure the window is actually on screen
+ Lock();
+ Sync();
+ mView->SetViewColor(B_TRANSPARENT_COLOR);
+ mView->Sync();
+ Unlock();
+}
+
+CairoTestWindow::~CairoTestWindow()
+{
+ RemoveChild(mView);
+ delete mView;
+}
+
+
+class nsBeOSApp : public BApplication
+{
+public:
+ nsBeOSApp(sem_id sem) : BApplication(GetAppSig()), init(sem)
+ {}
+
+ void ReadyToRun()
+ {
+ release_sem(init);
+ }
+
+ static int32 Main(void *args)
+ {
+ nsBeOSApp *app = new nsBeOSApp( (sem_id)args );
+ if(app == NULL)
+ return B_ERROR;
+ return app->Run();
+ }
+
+private:
+
+ const char *GetAppSig()
+ {
+ return "application/x-vnd.cairo-test-app";
+ }
+
+ sem_id init;
+}; //class nsBeOSApp
+
+class AppRunner
+{
+ public:
+ AppRunner();
+ ~AppRunner();
+};
+
+AppRunner::AppRunner()
+{
+ if (be_app)
+ return;
+
+ sem_id initsem = create_sem(0, "Cairo BApplication init");
+ if (initsem < B_OK) {
+ fprintf (stderr, "Error creating BeOS initialization semaphore\n");
+ return;
+ }
+
+ thread_id tid = spawn_thread(nsBeOSApp::Main, "Cairo/BeOS test", B_NORMAL_PRIORITY, (void *)initsem);
+ if (tid < B_OK || B_OK != resume_thread(tid)) {
+ fprintf (stderr, "Error spawning thread\n");
+ return;
+ }
+
+ if (B_OK != acquire_sem(initsem)) {
+ fprintf (stderr, "Error acquiring semaphore\n");
+ return;
+ }
+
+ delete_sem(initsem);
+ return;
+}
+
+AppRunner::~AppRunner()
+{
+ if (be_app) {
+ if (be_app->Lock())
+ be_app->Quit();
+ delete be_app;
+ be_app = NULL;
+ }
+}
+
+// Make sure that the BApplication is initialized
+static AppRunner sAppRunner;
+
+struct beos_boilerplate_closure {
+ BView* view;
+ BBitmap* bitmap;
+ BWindow* window;
+};
+
+// Test a real window
+static cairo_surface_t *
+_cairo_boilerplate_beos_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ float right = width ? width - 1 : 0;
+ float bottom = height ? height - 1 : 0;
+ BRect rect(0.0, 0.0, right, bottom);
+ CairoTestWindow* wnd = new CairoTestWindow(rect, name);
+
+ beos_boilerplate_closure* bclosure = new beos_boilerplate_closure;
+ bclosure->view = wnd->View();
+ bclosure->bitmap = NULL;
+ bclosure->window = wnd;
+
+ *closure = bclosure;
+
+ return cairo_beos_surface_create(wnd->View());
+}
+
+static void
+_cairo_boilerplate_beos_cleanup (void *closure)
+{
+ beos_boilerplate_closure* bclosure = reinterpret_cast<beos_boilerplate_closure*>(closure);
+
+ bclosure->window->Lock();
+ bclosure->window->Quit();
+
+ delete bclosure;
+}
+
+// Test a bitmap
+static cairo_surface_t *
+_cairo_boilerplate_beos_create_surface_for_bitmap (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ BRect rect(0.0, 0.0, width - 1, height - 1);
+ color_space beosformat = (content == CAIRO_CONTENT_COLOR_ALPHA) ? B_RGBA32
+ : B_RGB32;
+ BBitmap* bmp = new BBitmap(rect, beosformat, true);
+ BView* view = new BView(rect, "Cairo test view", B_FOLLOW_ALL_SIDES, 0);
+ bmp->AddChild(view);
+
+ beos_boilerplate_closure* bclosure = new beos_boilerplate_closure;
+ bclosure->view = view;
+ bclosure->bitmap = bmp;
+ bclosure->window = NULL;
+ *closure = bclosure;
+
+ return cairo_beos_surface_create_for_bitmap(view, bmp);
+}
+
+static void
+_cairo_boilerplate_beos_cleanup_bitmap (void *closure)
+{
+ beos_boilerplate_closure* bclosure = reinterpret_cast<beos_boilerplate_closure*>(closure);
+
+ bclosure->bitmap->RemoveChild(bclosure->view);
+
+
+ delete bclosure->view;
+ delete bclosure->bitmap;
+
+ delete bclosure;
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ /* 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, 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, 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, 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
+ },
+};
+CAIRO_BOILERPLATE (beos, targets)
+
diff --git a/boilerplate/cairo-boilerplate-cogl.c b/boilerplate/cairo-boilerplate-cogl.c
new file mode 100755
index 000000000..e39ad333d
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-cogl.c
@@ -0,0 +1,206 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Chris Wilson.
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-cogl.h>
+#include <cogl/cogl2-experimental.h>
+
+typedef struct _cogl_closure {
+ cairo_device_t *device;
+ CoglFramebuffer *fb;
+ cairo_surface_t *surface;
+} cogl_closure_t;
+
+static const cairo_user_data_key_t cogl_closure_key;
+
+static CoglContext *context = NULL;
+
+static void
+_cairo_boilerplate_cogl_cleanup (void *abstract_closure)
+{
+ cogl_closure_t *closure = abstract_closure;
+
+ cogl_object_unref (closure->fb);
+
+ cairo_device_finish (closure->device);
+ cairo_device_destroy (closure->device);
+
+ free (closure);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_cogl_create_offscreen_color_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **abstract_closure)
+{
+ cairo_device_t *device;
+ CoglTexture *tex;
+ CoglHandle offscreen;
+ CoglFramebuffer *fb;
+ cogl_closure_t *closure;
+ cairo_status_t status;
+
+ if (!context)
+ context = cogl_context_new (NULL, NULL);
+
+ device = cairo_cogl_device_create (context);
+ tex = cogl_texture_new_with_size (width, height,
+ COGL_TEXTURE_NO_SLICING,
+ COGL_PIXEL_FORMAT_BGRA_8888_PRE);
+ offscreen = cogl_offscreen_new_to_texture (tex);
+ fb = COGL_FRAMEBUFFER (offscreen);
+
+ cogl_framebuffer_allocate (fb, NULL);
+ cogl_push_framebuffer (fb);
+ cogl_ortho (0, cogl_framebuffer_get_width (fb),
+ cogl_framebuffer_get_height (fb), 0,
+ -1, 100);
+ cogl_pop_framebuffer ();
+
+ closure = malloc (sizeof (cogl_closure_t));
+ *abstract_closure = closure;
+ closure->device = device;
+ closure->fb = fb;
+ closure->surface = cairo_cogl_surface_create (device, fb);
+
+ status = cairo_surface_set_user_data (closure->surface,
+ &cogl_closure_key, closure, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return closure->surface;
+
+ _cairo_boilerplate_cogl_cleanup (closure);
+ return cairo_boilerplate_surface_create_in_error (status);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_cogl_create_onscreen_color_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **abstract_closure)
+{
+ cairo_device_t *device;
+ CoglOnscreen *onscreen;
+ CoglFramebuffer *fb;
+ cogl_closure_t *closure;
+ cairo_status_t status;
+
+ if (!context)
+ context = cogl_context_new (NULL, NULL);
+
+ device = cairo_cogl_device_create (context);
+ onscreen = cogl_onscreen_new (context, width, height);
+ fb = COGL_FRAMEBUFFER (onscreen);
+
+ cogl_onscreen_show (onscreen);
+
+ cogl_push_framebuffer (fb);
+ cogl_ortho (0, cogl_framebuffer_get_width (fb),
+ cogl_framebuffer_get_height (fb), 0,
+ -1, 100);
+ cogl_pop_framebuffer ();
+
+ closure = malloc (sizeof (cogl_closure_t));
+ *abstract_closure = closure;
+ closure->device = device;
+ closure->fb = fb;
+ closure->surface = cairo_cogl_surface_create (device, fb);
+
+ status = cairo_surface_set_user_data (closure->surface,
+ &cogl_closure_key, closure, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return closure->surface;
+
+ _cairo_boilerplate_cogl_cleanup (closure);
+ return cairo_boilerplate_surface_create_in_error (status);
+}
+
+static cairo_status_t
+_cairo_boilerplate_cogl_finish_onscreen (cairo_surface_t *surface)
+{
+ cogl_closure_t *closure = cairo_surface_get_user_data (surface, &cogl_closure_key);
+
+ cairo_cogl_surface_end_frame (surface);
+
+ cogl_framebuffer_swap_buffers (closure->fb);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_boilerplate_cogl_synchronize (void *abstract_closure)
+{
+ cogl_closure_t *closure = abstract_closure;
+ cogl_framebuffer_finish (closure->fb);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "cogl-offscreen-color", "cogl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_COGL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_cogl_device_create",
+ _cairo_boilerplate_cogl_create_offscreen_color_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_cogl_cleanup,
+ _cairo_boilerplate_cogl_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ },
+ {
+ "cogl-onscreen-color", "cogl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_COGL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_cogl_device_create",
+ _cairo_boilerplate_cogl_create_onscreen_color_surface,
+ cairo_surface_create_similar,
+ NULL,
+ _cairo_boilerplate_cogl_finish_onscreen,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_cogl_cleanup,
+ _cairo_boilerplate_cogl_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ }
+};
+CAIRO_BOILERPLATE (cogl, targets)
diff --git a/boilerplate/cairo-boilerplate-directfb.c b/boilerplate/cairo-boilerplate-directfb.c
new file mode 100755
index 000000000..a479011d9
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-directfb.c
@@ -0,0 +1,235 @@
+/*
+Test were run with the following script
+target can be directfb_bitmap or directfb
+
+export CAIRO_TEST_TARGET=directfb_bitmap
+export DFBARGS=quiet,no-banner,no-debug,log-file=dfblog,system=x11
+cd cairo/test
+make check
+
+*/
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-directfb.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <direct/debug.h>
+
+D_DEBUG_DOMAIN (CairoDFB_Boiler, "CairoDFB/Boiler", "Cairo DirectFB Boilerplate");
+
+/* macro for a safe call to DirectFB functions */
+#define DFBCHECK(x...) do{ \
+ err = x; \
+ if (err != DFB_OK) { \
+ fprintf (stderr, "%s <%d>:\n\t", __FILE__, __LINE__); \
+ goto ERROR; \
+ } \
+} while (0)
+
+typedef struct _DFBInfo {
+ IDirectFB *dfb;
+ IDirectFBDisplayLayer *layer;
+ IDirectFBWindow *window;
+ IDirectFBSurface *surface;
+} DFBInfo;
+
+static void
+_cairo_boilerplate_directfb_cleanup (void *closure)
+{
+ DFBInfo *info = (DFBInfo *) closure;
+
+ if (info->surface)
+ info->surface->Release (info->surface);
+
+ if (info->window)
+ info->window->Release (info->window);
+
+ if (info->layer)
+ info->layer->Release (info->layer);
+
+ if (info->dfb)
+ info->dfb->Release (info->dfb);
+
+ free (info);
+}
+
+static DFBInfo *
+init (void)
+{
+ DFBDisplayLayerConfig layer_config;
+ DFBGraphicsDeviceDescription desc;
+ int err;
+ DFBInfo *info;
+
+ info = xcalloc (1, sizeof (DFBInfo));
+ if (info == NULL)
+ return NULL;
+
+ DFBCHECK (DirectFBInit (NULL, NULL));
+ DFBCHECK (DirectFBCreate (&info->dfb));
+ info->dfb->GetDeviceDescription (info->dfb, &desc);
+
+ DFBCHECK (info->dfb->GetDisplayLayer (info->dfb,
+ DLID_PRIMARY, &info->layer));
+ info->layer->SetCooperativeLevel (info->layer, DLSCL_ADMINISTRATIVE);
+
+ if ((desc.blitting_flags & (DSBLIT_BLEND_ALPHACHANNEL |
+ DSBLIT_BLEND_COLORALPHA)) !=
+ (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA))
+ {
+ layer_config.flags = DLCONF_BUFFERMODE;
+ layer_config.buffermode = DLBM_BACKSYSTEM;
+ info->layer->SetConfiguration (info->layer, &layer_config);
+ }
+
+ return info;
+
+ERROR:
+ if (info != NULL)
+ _cairo_boilerplate_directfb_cleanup (info);
+ return NULL;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_directfb_window_create_surface (DFBInfo *info,
+ cairo_content_t content,
+ int width,
+ int height)
+{
+ DFBWindowDescription desc;
+ int err;
+
+ D_DEBUG_AT (CairoDFB_Boiler, "%s (%p, %s, %dx%d)\n", __FUNCTION__, info,
+ content == CAIRO_CONTENT_ALPHA ? "ALPHA" :
+ content == CAIRO_CONTENT_COLOR ? "RGB" :
+ content == CAIRO_CONTENT_COLOR_ALPHA ? "ARGB" : "unknown content!",
+ width, height);
+
+ desc.flags = DWDESC_POSX | DWDESC_POSY |
+ DWDESC_WIDTH | DWDESC_HEIGHT;
+ desc.caps = DSCAPS_NONE;
+ desc.posx = 0;
+ desc.posy = 0;
+ desc.width = width;
+ desc.height = height;
+ if (content == CAIRO_CONTENT_COLOR_ALPHA) {
+ desc.flags |= DWDESC_CAPS | DWDESC_PIXELFORMAT;
+ desc.caps |= DWCAPS_DOUBLEBUFFER | DWCAPS_ALPHACHANNEL;
+ desc.pixelformat = DSPF_ARGB;
+ }
+
+ DFBCHECK (info->layer->CreateWindow (info->layer, &desc, &info->window));
+ info->window->SetOpacity (info->window, 0xFF);
+ info->window->GetSurface (info->window, &info->surface);
+ info->surface->SetColor (info->surface, 0xFF, 0xFF, 0xFF, 0xFF);
+ info->surface->FillRectangle (info->surface,0, 0, desc.width, desc.height);
+ info->surface->Flip (info->surface, NULL, 0);
+
+ return cairo_directfb_surface_create (info->dfb, info->surface);
+
+ERROR:
+ _cairo_boilerplate_directfb_cleanup (info);
+ return NULL;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_directfb_bitmap_create_surface (DFBInfo *info,
+ cairo_content_t content,
+ int width,
+ int height)
+{
+ int err;
+ DFBSurfaceDescription desc;
+
+ D_DEBUG_AT (CairoDFB_Boiler, "%s (%p, %s, %dx%d)\n", __FUNCTION__, info,
+ content == CAIRO_CONTENT_ALPHA ? "ALPHA" :
+ content == CAIRO_CONTENT_COLOR ? "RGB" :
+ content == CAIRO_CONTENT_COLOR_ALPHA ? "ARGB" : "unknown content!",
+ width, height);
+
+ desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT;
+ desc.caps = DSCAPS_NONE;
+ desc.width = width;
+ desc.height = height;
+ if (content == CAIRO_CONTENT_COLOR_ALPHA) {
+ desc.flags |= DSDESC_PIXELFORMAT;
+ desc.pixelformat = DSPF_ARGB;
+ }
+ DFBCHECK (info->dfb->CreateSurface (info->dfb, &desc, &info->surface));
+
+ return cairo_directfb_surface_create (info->dfb, info->surface);
+
+ERROR:
+ _cairo_boilerplate_directfb_cleanup (info);
+ return NULL;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_directfb_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+
+ DFBInfo *info;
+
+ info = init ();
+ if (info == NULL)
+ return NULL;
+
+ *closure = info;
+
+ D_DEBUG_AT (CairoDFB_Boiler, "%s ('%s', %s, %dx%d, %s)\n",
+ __FUNCTION__, name,
+ content == CAIRO_CONTENT_ALPHA ? "ALPHA" :
+ content == CAIRO_CONTENT_COLOR ? "RGB" :
+ content == CAIRO_CONTENT_COLOR_ALPHA ? "ARGB" : "unknown content!",
+ width, height,
+ mode == CAIRO_BOILERPLATE_MODE_TEST ? "TEST" :
+ mode == CAIRO_BOILERPLATE_MODE_PERF ? "PERF" : "unknown mode!");
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ if (mode == CAIRO_BOILERPLATE_MODE_TEST)
+ return _cairo_boilerplate_directfb_bitmap_create_surface (info, content, width, height);
+ else /* mode == CAIRO_BOILERPLATE_MODE_PERF */
+ return _cairo_boilerplate_directfb_window_create_surface (info, content, width, height);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "directfb", "directfb", NULL, NULL,
+ CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR, 0,
+ "cairo_directfb_surface_create",
+ _cairo_boilerplate_directfb_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_directfb_cleanup,
+ NULL, NULL, TRUE, FALSE, FALSE
+ },
+ {
+ "directfb-bitmap", "directfb", NULL, NULL,
+ CAIRO_SURFACE_TYPE_DIRECTFB, CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "cairo_directfb_surface_create",
+ _cairo_boilerplate_directfb_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_directfb_cleanup,
+ NULL, NULL, FALSE, FALSE, FALSE
+ },
+};
+CAIRO_BOILERPLATE (directfb, targets);
diff --git a/boilerplate/cairo-boilerplate-drm.c b/boilerplate/cairo-boilerplate-drm.c
new file mode 100755
index 000000000..214ce50cd
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-drm.c
@@ -0,0 +1,106 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Chris Wilson.
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-drm.h>
+
+static cairo_surface_t *
+_cairo_boilerplate_drm_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ cairo_device_t *device;
+ cairo_format_t format;
+
+ device = cairo_drm_device_default ();
+ if (device == NULL)
+ return NULL; /* skip tests if no supported h/w found */
+
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
+ case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break;
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+ }
+
+ return *closure = cairo_drm_surface_create (device, format, width, height);
+}
+
+static void
+_cairo_boilerplate_drm_synchronize (void *closure)
+{
+ cairo_surface_t *image;
+
+ image = cairo_drm_surface_map_to_image (closure);
+ if (cairo_surface_status (image) == CAIRO_STATUS_SUCCESS)
+ cairo_drm_surface_unmap (closure, image);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ /* Acceleration architectures may make the results differ by a
+ * bit, so we set the error tolerance to 1. */
+ {
+ "drm", "drm", NULL, NULL,
+ CAIRO_SURFACE_TYPE_DRM, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_drm_surface_create",
+ _cairo_boilerplate_drm_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL,
+ _cairo_boilerplate_drm_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ },
+ {
+ "drm", "drm", NULL, NULL,
+ CAIRO_SURFACE_TYPE_DRM, CAIRO_CONTENT_COLOR, 1,
+ "cairo_drm_surface_create",
+ _cairo_boilerplate_drm_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL,
+ _cairo_boilerplate_drm_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+};
+CAIRO_BOILERPLATE (drm, targets)
diff --git a/boilerplate/cairo-boilerplate-egl.c b/boilerplate/cairo-boilerplate-egl.c
new file mode 100755
index 000000000..dd62ea8a0
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-egl.c
@@ -0,0 +1,184 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Chris Wilson.
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#if CAIRO_HAS_EVASGL_SURFACE && CAIRO_HAS_GLESV2_SURFACE
+extern void glFinish (void);
+#endif
+
+#include <cairo-gl.h>
+#if CAIRO_HAS_GL_SURFACE
+#include <GL/gl.h>
+#elif CAIRO_HAS_GLESV2_SURFACE
+#include <GLES2/gl2.h>
+#endif
+
+static const cairo_user_data_key_t gl_closure_key;
+
+typedef struct _egl_target_closure {
+ EGLDisplay dpy;
+ EGLContext ctx;
+
+ cairo_device_t *device;
+ cairo_surface_t *surface;
+} egl_target_closure_t;
+
+static void
+_cairo_boilerplate_egl_cleanup (void *closure)
+{
+ egl_target_closure_t *gltc = closure;
+
+ cairo_device_finish (gltc->device);
+ cairo_device_destroy (gltc->device);
+
+ eglDestroyContext (gltc->dpy, gltc->ctx);
+ eglMakeCurrent (gltc->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglTerminate (gltc->dpy);
+
+ free (gltc);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_egl_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ egl_target_closure_t *gltc;
+ cairo_surface_t *surface;
+ int major, minor;
+ EGLConfig config;
+ EGLint numConfigs;
+ EGLint config_attribs[] = {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+#if CAIRO_HAS_GL_SURFACE
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+#elif CAIRO_HAS_GLESV2_SURFACE
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#endif
+ EGL_SAMPLES, 4,
+ EGL_NONE
+ };
+ const EGLint ctx_attribs[] = {
+#if CAIRO_HAS_GLESV2_SURFACE
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+#endif
+ EGL_NONE
+ };
+
+ gltc = xcalloc (1, sizeof (egl_target_closure_t));
+ *closure = gltc;
+
+ gltc->dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
+
+ if (! eglInitialize (gltc->dpy, &major, &minor)) {
+ free (gltc);
+ return NULL;
+ }
+
+ eglChooseConfig (gltc->dpy, config_attribs, &config, 1, &numConfigs);
+ if (numConfigs == 0) {
+ free (gltc);
+ return NULL;
+ }
+
+#if CAIRO_HAS_GL_SURFACE
+ eglBindAPI (EGL_OPENGL_API);
+#elif CAIRO_HAS_GLESV2_SURFACE
+ eglBindAPI (EGL_OPENGL_ES_API);
+#endif
+
+ gltc->ctx = eglCreateContext (gltc->dpy, config, EGL_NO_CONTEXT,
+ ctx_attribs);
+ if (gltc->ctx == EGL_NO_CONTEXT) {
+ eglTerminate (gltc->dpy);
+ free (gltc);
+ return NULL;
+ }
+
+ gltc->device = cairo_egl_device_create (gltc->dpy, gltc->ctx);
+ cairo_gl_device_set_thread_aware (gltc->device, FALSE);
+
+ if (width < 1)
+ width = 1;
+ if (height < 1)
+ height = 1;
+
+ gltc->surface = surface = cairo_gl_surface_create (gltc->device,
+ content,
+ ceil (width),
+ ceil (height));
+ if (cairo_surface_status (surface))
+ _cairo_boilerplate_egl_cleanup (gltc);
+
+ return surface;
+}
+
+static void
+_cairo_boilerplate_egl_synchronize (void *closure)
+{
+ egl_target_closure_t *gltc = closure;
+
+ if (cairo_device_acquire (gltc->device))
+ return;
+
+ glFinish ();
+
+ cairo_device_release (gltc->device);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "egl", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_egl_device_create",
+ _cairo_boilerplate_egl_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_egl_cleanup,
+ _cairo_boilerplate_egl_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ }
+};
+CAIRO_BOILERPLATE (egl, targets)
diff --git a/boilerplate/cairo-boilerplate-evas-gl.c b/boilerplate/cairo-boilerplate-evas-gl.c
new file mode 100755
index 000000000..151e6af29
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-evas-gl.c
@@ -0,0 +1,143 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2014 Samsung Research America, Inc - Silicon Valley
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Henry Song.
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-gl.h>
+#include <cairo-evas-gl.h>
+#include <Ecore_Evas.h>
+#include <Ecore.h>
+#include <Evas_GL.h>
+
+static const cairo_user_data_key_t gl_closure_key;
+
+typedef struct _evas_gl_target_closure {
+ Evas_GL *evas_gl;
+ Evas_GL_Context *evas_ctx;
+ Evas_GL_API *evas_api;
+
+ cairo_device_t *device;
+ cairo_surface_t *surface;
+} evas_gl_target_closure_t;
+
+static void
+_cairo_boilerplate_evas_gl_cleanup (void *closure)
+{
+ evas_gl_target_closure_t *gltc = closure;
+
+ cairo_device_finish (gltc->device);
+ cairo_device_destroy (gltc->device);
+
+ evas_gl_context_destroy (gltc->evas_gl, gltc->evas_ctx);
+ evas_gl_free (gltc->evas_gl);
+
+ free (gltc);
+
+ ecore_evas_shutdown ();
+ ecore_shutdown ();
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_evas_gl_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ Ecore_Evas *ee;
+ Evas *canvas;
+
+ evas_gl_target_closure_t *gltc;
+ cairo_surface_t *surface;
+
+ if (width < 1)
+ width = 1;
+ if (height < 1)
+ height = 1;
+
+ ecore_init ();
+ ecore_evas_init ();
+ ee = ecore_evas_gl_x11_new (NULL, 0, 0, 0, ceil (width), ceil (height));;
+ canvas = ecore_evas_get (ee);
+
+ gltc = xcalloc (1, sizeof (evas_gl_target_closure_t));
+ *closure = gltc;
+
+ gltc->evas_gl = evas_gl_new (canvas);
+ gltc->evas_ctx = evas_gl_context_create (gltc->evas_gl, NULL);
+ gltc->evas_api = evas_gl_api_get (gltc->evas_gl);
+
+ gltc->device = cairo_evas_gl_device_create (gltc->evas_gl, gltc->evas_ctx);
+
+ gltc->surface = surface =
+ cairo_gl_surface_create (gltc->device, CAIRO_CONTENT_COLOR_ALPHA,
+ ceil (width), ceil (height));
+ if (cairo_surface_status (surface))
+ _cairo_boilerplate_evas_gl_cleanup (gltc);
+
+ return surface;
+}
+
+static void
+_cairo_boilerplate_evas_gl_synchronize (void *closure)
+{
+ evas_gl_target_closure_t *gltc = closure;
+
+ if (cairo_device_acquire (gltc->device))
+ return;
+
+ gltc->evas_api->glFinish ();
+
+ cairo_device_release (gltc->device);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "evasgl", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_evas_gl_device_create",
+ _cairo_boilerplate_evas_gl_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_evas_gl_cleanup,
+ _cairo_boilerplate_evas_gl_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ }
+};
+CAIRO_BOILERPLATE (evasgl, targets)
diff --git a/boilerplate/cairo-boilerplate-getopt.c b/boilerplate/cairo-boilerplate-getopt.c
new file mode 100755
index 000000000..53b150c29
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-getopt.c
@@ -0,0 +1,247 @@
+/*****************************************************************************
+* getopt.c - competent and free getopt library.
+* $Header: /cvsroot/freegetopt/freegetopt/getopt.c,v 1.2 2003/10/26 03:10:20 vindaci Exp $
+*
+* Copyright (c)2002-2003 Mark K. Kim
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* * Neither the original author of this software nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cairo-boilerplate-getopt.h"
+
+
+char* optarg = NULL;
+int optind = 0;
+int opterr = 1;
+int optopt = '?';
+
+
+static char** prev_argv = NULL; /* Keep a copy of argv and argc to */
+static int prev_argc = 0; /* tell if getopt params change */
+static int argv_index = 0; /* Option we're checking */
+static int argv_index2 = 0; /* Option argument we're checking */
+static int opt_offset = 0; /* Index into compounded "-option" */
+static int dashdash = 0; /* True if "--" option reached */
+static int nonopt = 0; /* How many nonopts we've found */
+
+static void increment_index(void)
+{
+ /* Move onto the next option */
+ if(argv_index < argv_index2)
+ {
+ while(prev_argv[++argv_index] && prev_argv[argv_index][0] != '-'
+ && argv_index < argv_index2+1);
+ }
+ else argv_index++;
+ opt_offset = 1;
+}
+
+
+/*
+* Permutes argv[] so that the argument currently being processed is moved
+* to the end.
+*/
+static int permute_argv_once(void)
+{
+ /* Movability check */
+ if(argv_index + nonopt >= prev_argc) return 1;
+ /* Move the current option to the end, bring the others to front */
+ else
+ {
+ char* tmp = prev_argv[argv_index];
+
+ /* Move the data */
+ memmove(&prev_argv[argv_index], &prev_argv[argv_index+1],
+ sizeof(char**) * (prev_argc - argv_index - 1));
+ prev_argv[prev_argc - 1] = tmp;
+
+ nonopt++;
+ return 0;
+ }
+}
+
+
+int _cairo_getopt(int argc, char** argv, const char* optstr)
+{
+ int c = 0;
+
+ /* If we have new argv, reinitialize */
+ if(prev_argv != argv || prev_argc != argc)
+ {
+ /* Initialize variables */
+ prev_argv = argv;
+ prev_argc = argc;
+ argv_index = 1;
+ argv_index2 = 1;
+ opt_offset = 1;
+ dashdash = 0;
+ nonopt = 0;
+ }
+
+ /* Jump point in case we want to ignore the current argv_index */
+ getopt_top:
+
+ /* Misc. initializations */
+ optarg = NULL;
+
+ /* Dash-dash check */
+ if(argv[argv_index] && !strcmp(argv[argv_index], "--"))
+ {
+ dashdash = 1;
+ increment_index();
+ }
+
+ /* If we're at the end of argv, that's it. */
+ if(argv[argv_index] == NULL)
+ {
+ c = -1;
+ }
+ /* Are we looking at a string? Single dash is also a string */
+ else if(dashdash || argv[argv_index][0] != '-' || !strcmp(argv[argv_index], "-"))
+ {
+ /* If we want a string... */
+ if(optstr[0] == '-')
+ {
+ c = 1;
+ optarg = argv[argv_index];
+ increment_index();
+ }
+ /* If we really don't want it (we're in POSIX mode), we're done */
+ else if(optstr[0] == '+' || getenv("POSIXLY_CORRECT"))
+ {
+ c = -1;
+
+ /* Everything else is a non-opt argument */
+ nonopt = argc - argv_index;
+ }
+ /* If we mildly don't want it, then move it back */
+ else
+ {
+ if(!permute_argv_once()) goto getopt_top;
+ else c = -1;
+ }
+ }
+ /* Otherwise we're looking at an option */
+ else
+ {
+ char* opt_ptr = NULL;
+
+ /* Grab the option */
+ c = argv[argv_index][opt_offset++];
+
+ /* Is the option in the optstr? */
+ if(optstr[0] == '-') opt_ptr = strchr(optstr+1, c);
+ else opt_ptr = strchr(optstr, c);
+ /* Invalid argument */
+ if(!opt_ptr)
+ {
+ if(opterr)
+ {
+ fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
+ }
+
+ optopt = c;
+ c = '?';
+
+ /* Move onto the next option */
+ increment_index();
+ }
+ /* Option takes argument */
+ else if(opt_ptr[1] == ':')
+ {
+ /* ie, -oARGUMENT, -xxxoARGUMENT, etc. */
+ if(argv[argv_index][opt_offset] != '\0')
+ {
+ optarg = &argv[argv_index][opt_offset];
+ increment_index();
+ }
+ /* ie, -o ARGUMENT (only if it's a required argument) */
+ else if(opt_ptr[2] != ':')
+ {
+ /* One of those "you're not expected to understand this" moment */
+ if(argv_index2 < argv_index) argv_index2 = argv_index;
+ while(argv[++argv_index2] && argv[argv_index2][0] == '-');
+ optarg = argv[argv_index2];
+
+ /* Don't cross into the non-option argument list */
+ if(argv_index2 + nonopt >= prev_argc) optarg = NULL;
+
+ /* Move onto the next option */
+ increment_index();
+ }
+ else
+ {
+ /* Move onto the next option */
+ increment_index();
+ }
+
+ /* In case we got no argument for an option with required argument */
+ if(optarg == NULL && opt_ptr[2] != ':')
+ {
+ optopt = c;
+ c = '?';
+
+ if(opterr)
+ {
+ fprintf(stderr,"%s: option requires an argument -- %c\n",
+ argv[0], optopt);
+ }
+ }
+ }
+ /* Option does not take argument */
+ else
+ {
+ /* Next argv_index */
+ if(argv[argv_index][opt_offset] == '\0')
+ {
+ increment_index();
+ }
+ }
+ }
+
+ /* Calculate optind */
+ if(c == -1)
+ {
+ optind = argc - nonopt;
+ }
+ else
+ {
+ optind = argv_index;
+ }
+
+ return c;
+}
+
+
+/* vim:ts=3
+*/
diff --git a/boilerplate/cairo-boilerplate-getopt.h b/boilerplate/cairo-boilerplate-getopt.h
new file mode 100755
index 000000000..74bce14c7
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-getopt.h
@@ -0,0 +1,63 @@
+/*****************************************************************************
+* getopt.h - competent and free getopt library.
+* $Header: /cvsroot/freegetopt/freegetopt/getopt.h,v 1.2 2003/10/26 03:10:20 vindaci Exp $
+*
+* Copyright (c)2002-2003 Mark K. Kim
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* * Neither the original author of this software nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*/
+#ifndef GETOPT_H_
+#define GETOPT_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern char* optarg;
+extern int optind;
+extern int opterr;
+extern int optopt;
+
+int _cairo_getopt(int argc, char** argv, const char* optstr);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* GETOPT_H_ */
+
+
+/* vim:ts=3
+*/
diff --git a/boilerplate/cairo-boilerplate-glx.c b/boilerplate/cairo-boilerplate-glx.c
new file mode 100755
index 000000000..52cd99f9b
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-glx.c
@@ -0,0 +1,454 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Chris Wilson.
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-gl.h>
+
+#include <X11/X.h>
+#include <X11/Xutil.h> /* for XDestroyImage */
+
+static const cairo_user_data_key_t gl_closure_key;
+
+typedef struct _gl_target_closure {
+ Display *dpy;
+ int screen;
+ Window drawable;
+
+ GLXContext ctx;
+ cairo_device_t *device;
+ cairo_surface_t *surface;
+} gl_target_closure_t;
+
+static void
+_cairo_boilerplate_gl_cleanup (void *closure)
+{
+ gl_target_closure_t *gltc = closure;
+
+ cairo_device_finish (gltc->device);
+ cairo_device_destroy (gltc->device);
+
+ glXDestroyContext (gltc->dpy, gltc->ctx);
+
+ if (gltc->drawable)
+ XDestroyWindow (gltc->dpy, gltc->drawable);
+ XCloseDisplay (gltc->dpy);
+
+ free (gltc);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_gl_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ int rgba_attribs[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+ int rgb_attribs[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+ XVisualInfo *visinfo;
+ GLXContext ctx;
+ gl_target_closure_t *gltc;
+ cairo_surface_t *surface;
+ Display *dpy;
+
+ gltc = calloc (1, sizeof (gl_target_closure_t));
+ *closure = gltc;
+
+ width = ceil (width);
+ height = ceil (height);
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ dpy = XOpenDisplay (NULL);
+ gltc->dpy = dpy;
+ if (!gltc->dpy) {
+ fprintf (stderr, "Failed to open display: %s\n", XDisplayName(0));
+ free (gltc);
+ return NULL;
+ }
+
+ if (mode == CAIRO_BOILERPLATE_MODE_TEST)
+ XSynchronize (gltc->dpy, 1);
+
+ if (content == CAIRO_CONTENT_COLOR)
+ visinfo = glXChooseVisual (dpy, DefaultScreen (dpy), rgb_attribs);
+ else
+ visinfo = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
+
+ if (visinfo == NULL) {
+ fprintf (stderr, "Failed to create RGB, double-buffered visual\n");
+ XCloseDisplay (dpy);
+ free (gltc);
+ return NULL;
+ }
+
+ ctx = glXCreateContext (dpy, visinfo, NULL, True);
+ XFree (visinfo);
+
+ gltc->ctx = ctx;
+ gltc->device = cairo_glx_device_create (dpy, ctx);
+
+ gltc->surface = surface = cairo_gl_surface_create (gltc->device,
+ content, width, height);
+ if (cairo_surface_status (surface))
+ _cairo_boilerplate_gl_cleanup (gltc);
+
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_gl_create_window_common (int rgba_attribs[],
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ gl_target_closure_t *gltc)
+{
+ XVisualInfo *vi;
+ GLXContext ctx;
+ cairo_surface_t *surface;
+ Display *dpy;
+ XSetWindowAttributes attr;
+
+ width = ceil (width);
+ height = ceil (height);
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ dpy = XOpenDisplay (NULL);
+ gltc->dpy = dpy;
+ if (!gltc->dpy) {
+ fprintf (stderr, "Failed to open display: %s\n", XDisplayName(0));
+ free (gltc);
+ return NULL;
+ }
+
+ if (mode == CAIRO_BOILERPLATE_MODE_TEST)
+ XSynchronize (gltc->dpy, 1);
+
+ vi = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
+ if (vi == NULL) {
+ fprintf (stderr, "Failed to create RGBA, double-buffered visual\n");
+ XCloseDisplay (dpy);
+ free (gltc);
+ return NULL;
+ }
+
+ attr.colormap = XCreateColormap (dpy,
+ RootWindow (dpy, vi->screen),
+ vi->visual,
+ AllocNone);
+ attr.border_pixel = 0;
+ attr.override_redirect = True;
+ gltc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0,
+ width, height, 0, vi->depth,
+ InputOutput, vi->visual,
+ CWOverrideRedirect | CWBorderPixel | CWColormap,
+ &attr);
+ XMapWindow (dpy, gltc->drawable);
+
+ ctx = glXCreateContext (dpy, vi, NULL, True);
+ XFree (vi);
+
+ gltc->ctx = ctx;
+ gltc->device = cairo_glx_device_create (dpy, ctx);
+
+ gltc->surface = surface = cairo_gl_surface_create_for_window (gltc->device,
+ gltc->drawable,
+ width, height);
+ if (cairo_surface_status (surface)) {
+ _cairo_boilerplate_gl_cleanup (gltc);
+ return NULL;
+ }
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_gl_create_window (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ gl_target_closure_t *gltc;
+
+ int rgba_attribs[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+
+ gltc = calloc (1, sizeof (gl_target_closure_t));
+ *closure = gltc;
+
+ return _cairo_boilerplate_gl_create_window_common (rgba_attribs, content,
+ width, height,
+ max_width, max_height,
+ mode, gltc);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_gl_create_window_msaa (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ gl_target_closure_t *gltc;
+
+ int rgba_attribs[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_STENCIL_SIZE, 1,
+ GLX_SAMPLES, 4,
+ GLX_SAMPLE_BUFFERS, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+
+ gltc = calloc (1, sizeof (gl_target_closure_t));
+ *closure = gltc;
+ return _cairo_boilerplate_gl_create_window_common (rgba_attribs, content,
+ width, height,
+ max_width, max_height,
+ mode, gltc);
+
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_gl_create_window_db (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ cairo_status_t status;
+ cairo_surface_t *surface;
+ gl_target_closure_t *gltc;
+
+ int rgba_attribs[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+
+ gltc = calloc (1, sizeof (gl_target_closure_t));
+ *closure = gltc;
+
+ surface = _cairo_boilerplate_gl_create_window_common (rgba_attribs, content,
+ width, height,
+ max_width, max_height,
+ mode, gltc);
+
+ if (! surface)
+ return NULL;
+
+ surface = cairo_surface_create_similar (gltc->surface, content, width, height);
+ status = cairo_surface_set_user_data (surface, &gl_closure_key, gltc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+ _cairo_boilerplate_gl_cleanup (gltc);
+ return cairo_boilerplate_surface_create_in_error (status);
+}
+
+static cairo_status_t
+_cairo_boilerplate_gl_finish_window (cairo_surface_t *surface)
+{
+ gl_target_closure_t *gltc = cairo_surface_get_user_data (surface,
+ &gl_closure_key);
+
+ if (gltc != NULL && gltc->surface != NULL) {
+ cairo_t *cr;
+
+ cr = cairo_create (gltc->surface);
+ cairo_surface_set_device_offset (surface, 0, 0);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ surface = gltc->surface;
+ }
+
+ cairo_gl_surface_swapbuffers (surface);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_boilerplate_gl_synchronize (void *closure)
+{
+ gl_target_closure_t *gltc = closure;
+
+ if (cairo_device_acquire (gltc->device))
+ return;
+
+ glFinish ();
+
+ cairo_device_release (gltc->device);
+}
+
+static char *
+_cairo_boilerplate_gl_describe (void *closure)
+{
+ gl_target_closure_t *gltc = closure;
+ char *s;
+ const GLubyte *vendor, *renderer, *version;
+
+ if (cairo_device_acquire (gltc->device))
+ return NULL;
+
+ vendor = glGetString (GL_VENDOR);
+ renderer = glGetString (GL_RENDERER);
+ version = glGetString (GL_VERSION);
+
+ xasprintf (&s, "%s %s %s", vendor, renderer, version);
+
+ cairo_device_release (gltc->device);
+
+ return s;
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "gl", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_gl_surface_create",
+ _cairo_boilerplate_gl_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_gl_cleanup,
+ _cairo_boilerplate_gl_synchronize,
+ _cairo_boilerplate_gl_describe,
+ TRUE, FALSE, FALSE
+ },
+ {
+ "gl", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR, 1,
+ "cairo_gl_surface_create",
+ _cairo_boilerplate_gl_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_gl_cleanup,
+ _cairo_boilerplate_gl_synchronize,
+ _cairo_boilerplate_gl_describe,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "gl-window", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_gl_surface_create_for_window",
+ _cairo_boilerplate_gl_create_window,
+ cairo_surface_create_similar,
+ NULL,
+ _cairo_boilerplate_gl_finish_window,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_gl_cleanup,
+ _cairo_boilerplate_gl_synchronize,
+ _cairo_boilerplate_gl_describe,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "gl-window-msaa", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_gl_surface_create_for_window",
+ _cairo_boilerplate_gl_create_window_msaa,
+ cairo_surface_create_similar,
+ NULL,
+ _cairo_boilerplate_gl_finish_window,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_gl_cleanup,
+ _cairo_boilerplate_gl_synchronize,
+ _cairo_boilerplate_gl_describe,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "gl-window&", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_gl_surface_create_for_window",
+ _cairo_boilerplate_gl_create_window_db,
+ cairo_surface_create_similar,
+ NULL,
+ _cairo_boilerplate_gl_finish_window,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_gl_cleanup,
+ _cairo_boilerplate_gl_synchronize,
+ _cairo_boilerplate_gl_describe,
+ FALSE, FALSE, FALSE
+ },
+};
+CAIRO_BOILERPLATE (gl, targets)
diff --git a/boilerplate/cairo-boilerplate-pdf.c b/boilerplate/cairo-boilerplate-pdf.c
new file mode 100755
index 000000000..d76d13951
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-pdf.c
@@ -0,0 +1,280 @@
+/* -*- 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 <cworth@cworth.org>
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#if CAIRO_CAN_TEST_PDF_SURFACE
+
+#include <cairo-pdf.h>
+#include <cairo-pdf-surface-private.h>
+#include <cairo-paginated-surface-private.h>
+
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#if ! CAIRO_HAS_RECORDING_SURFACE
+#define CAIRO_SURFACE_TYPE_RECORDING CAIRO_INTERNAL_SURFACE_TYPE_RECORDING
+#endif
+
+static const cairo_user_data_key_t pdf_closure_key;
+
+typedef struct _pdf_target_closure
+{
+ char *filename;
+ int width;
+ int height;
+ cairo_surface_t *target;
+} pdf_target_closure_t;
+
+#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
+
+static cairo_surface_t *
+_cairo_boilerplate_pdf_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ pdf_target_closure_t *ptc;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ /* Sanitize back to a real cairo_content_t value. */
+ if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
+ content = CAIRO_CONTENT_COLOR_ALPHA;
+
+ *closure = ptc = xmalloc (sizeof (pdf_target_closure_t));
+
+ ptc->width = ceil (width);
+ ptc->height = ceil (height);
+
+ xasprintf (&ptc->filename, "%s.out.pdf", name);
+ xunlink (ptc->filename);
+
+ surface = cairo_pdf_surface_create (ptc->filename, width, height);
+ if (cairo_surface_status (surface))
+ goto CLEANUP_FILENAME;
+
+ cairo_surface_set_fallback_resolution (surface, 72., 72.);
+
+ if (content == CAIRO_CONTENT_COLOR) {
+ ptc->target = surface;
+ surface = cairo_surface_create_similar (ptc->target,
+ CAIRO_CONTENT_COLOR,
+ ptc->width, ptc->height);
+ if (cairo_surface_status (surface))
+ goto CLEANUP_TARGET;
+ } else {
+ ptc->target = NULL;
+ }
+
+ status = cairo_surface_set_user_data (surface, &pdf_closure_key, ptc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+ surface = cairo_boilerplate_surface_create_in_error (status);
+
+ CLEANUP_TARGET:
+ cairo_surface_destroy (ptc->target);
+ CLEANUP_FILENAME:
+ free (ptc->filename);
+ free (ptc);
+ return surface;
+}
+
+static cairo_status_t
+_cairo_boilerplate_pdf_finish_surface (cairo_surface_t *surface)
+{
+ pdf_target_closure_t *ptc = cairo_surface_get_user_data (surface,
+ &pdf_closure_key);
+ cairo_status_t status;
+
+ /* Both surface and ptc->target were originally created at the
+ * same dimensions. We want a 1:1 copy here, so we first clear any
+ * device offset on surface.
+ *
+ * In a more realistic use case of device offsets, the target of
+ * this copying would be of a different size than the source, and
+ * the offset would be desirable during the copy operation. */
+ cairo_surface_set_device_offset (surface, 0, 0);
+
+ if (ptc->target) {
+ cairo_t *cr;
+ cr = cairo_create (ptc->target);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_show_page (cr);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ if (status)
+ return status;
+
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ if (status)
+ return status;
+
+ surface = ptc->target;
+ }
+
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ if (status)
+ return status;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_boilerplate_pdf_surface_write_to_png (cairo_surface_t *surface,
+ const char *filename)
+{
+ pdf_target_closure_t *ptc = cairo_surface_get_user_data (surface, &pdf_closure_key);
+ char command[4096];
+ int exitstatus;
+
+ sprintf (command, "./pdf2png %s %s 1",
+ ptc->filename, filename);
+
+ exitstatus = system (command);
+#if _XOPEN_SOURCE && HAVE_SIGNAL_H
+ if (WIFSIGNALED (exitstatus))
+ raise (WTERMSIG (exitstatus));
+#endif
+ if (exitstatus)
+ return CAIRO_STATUS_WRITE_ERROR;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_pdf_convert_to_image (cairo_surface_t *surface,
+ int page)
+{
+ pdf_target_closure_t *ptc = cairo_surface_get_user_data (surface,
+ &pdf_closure_key);
+
+ return cairo_boilerplate_convert_to_image (ptc->filename, page+1);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_pdf_get_image_surface (cairo_surface_t *surface,
+ int page,
+ int width,
+ int height)
+{
+ cairo_surface_t *image;
+
+ image = _cairo_boilerplate_pdf_convert_to_image (surface, page);
+ cairo_surface_set_device_offset (image,
+ cairo_image_surface_get_width (image) - width,
+ cairo_image_surface_get_height (image) - height);
+ surface = _cairo_boilerplate_get_image_surface (image, 0, width, height);
+ cairo_surface_destroy (image);
+
+ return surface;
+}
+
+static void
+_cairo_boilerplate_pdf_cleanup (void *closure)
+{
+ pdf_target_closure_t *ptc = closure;
+ if (ptc->target) {
+ cairo_surface_finish (ptc->target);
+ cairo_surface_destroy (ptc->target);
+ }
+ free (ptc->filename);
+ free (ptc);
+}
+
+static void
+_cairo_boilerplate_pdf_force_fallbacks (cairo_surface_t *abstract_surface,
+ double x_pixels_per_inch,
+ double y_pixels_per_inch)
+{
+ pdf_target_closure_t *ptc = cairo_surface_get_user_data (abstract_surface,
+ &pdf_closure_key);
+
+ cairo_paginated_surface_t *paginated;
+ cairo_pdf_surface_t *surface;
+
+ if (ptc->target)
+ abstract_surface = ptc->target;
+
+ paginated = (cairo_paginated_surface_t*) abstract_surface;
+ surface = (cairo_pdf_surface_t*) paginated->target;
+ surface->force_fallbacks = TRUE;
+ cairo_surface_set_fallback_resolution (&paginated->base,
+ x_pixels_per_inch,
+ y_pixels_per_inch);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "pdf", "pdf", ".pdf", NULL,
+ CAIRO_SURFACE_TYPE_PDF,
+ CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
+ "cairo_pdf_surface_create",
+ _cairo_boilerplate_pdf_create_surface,
+ cairo_surface_create_similar,
+ _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, NULL, FALSE, TRUE, TRUE
+ },
+ {
+ "pdf", "pdf", ".pdf", NULL,
+ CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR, 0,
+ "cairo_pdf_surface_create",
+ _cairo_boilerplate_pdf_create_surface,
+ cairo_surface_create_similar,
+ _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, NULL, FALSE, TRUE, TRUE
+ },
+};
+CAIRO_BOILERPLATE (pdf, targets)
+
+#else
+
+CAIRO_NO_BOILERPLATE (pdf)
+
+#endif
diff --git a/boilerplate/cairo-boilerplate-private.h b/boilerplate/cairo-boilerplate-private.h
new file mode 100755
index 000000000..a7a2dd0eb
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-private.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * 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: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#ifndef _CAIRO_BOILERPLATE_PRIVATE_H_
+#define _CAIRO_BOILERPLATE_PRIVATE_H_
+
+#include "cairo-boilerplate.h"
+
+CAIRO_BEGIN_DECLS
+
+void
+_cairo_boilerplate_register_all (void);
+
+void
+_cairo_boilerplate_register_backend (const cairo_boilerplate_target_t *targets,
+ unsigned int count);
+
+#define CAIRO_BOILERPLATE(name__, targets__) \
+void _register_##name__ (void); \
+void _register_##name__ (void) { \
+ _cairo_boilerplate_register_backend (targets__, \
+ sizeof (targets__) / sizeof (targets__[0])); \
+}
+
+#define CAIRO_NO_BOILERPLATE(name__) \
+void _register_##name__ (void); \
+void _register_##name__ (void) { }
+
+CAIRO_END_DECLS
+
+#endif /* _CAIRO_BOILERPLATE_PRIVATE_H_ */
diff --git a/boilerplate/cairo-boilerplate-ps.c b/boilerplate/cairo-boilerplate-ps.c
new file mode 100755
index 000000000..ae61239f3
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-ps.c
@@ -0,0 +1,369 @@
+/* -*- 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 <cworth@cworth.org>
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#if CAIRO_CAN_TEST_PS_SURFACE
+
+#include <cairo-ps.h>
+
+#include <cairo-ps-surface-private.h>
+#include <cairo-paginated-surface-private.h>
+
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#if ! CAIRO_HAS_RECORDING_SURFACE
+#define CAIRO_SURFACE_TYPE_RECORDING CAIRO_INTERNAL_SURFACE_TYPE_RECORDING
+#endif
+
+static const cairo_user_data_key_t ps_closure_key;
+
+typedef struct _ps_target_closure {
+ char *filename;
+ int width;
+ int height;
+ cairo_surface_t *target;
+ cairo_ps_level_t level;
+} ps_target_closure_t;
+
+static cairo_status_t
+_cairo_boilerplate_ps_surface_set_creation_date (cairo_surface_t *abstract_surface,
+ time_t date)
+{
+ cairo_paginated_surface_t *paginated = (cairo_paginated_surface_t*) abstract_surface;
+ cairo_ps_surface_t *surface;
+
+ if (cairo_surface_get_type (abstract_surface) != CAIRO_SURFACE_TYPE_PS)
+ return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+
+ surface = (cairo_ps_surface_t*) paginated->target;
+
+ surface->has_creation_date = TRUE;
+ surface->creation_date = date;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_ps_create_surface (const char *name,
+ cairo_content_t content,
+ cairo_ps_level_t level,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ ps_target_closure_t *ptc;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ /* Sanitize back to a real cairo_content_t value. */
+ if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
+ content = CAIRO_CONTENT_COLOR_ALPHA;
+
+ *closure = ptc = xmalloc (sizeof (ps_target_closure_t));
+
+ xasprintf (&ptc->filename, "%s.out.ps", name);
+ xunlink (ptc->filename);
+
+ ptc->level = level;
+ ptc->width = ceil (width);
+ ptc->height = ceil (height);
+
+ surface = cairo_ps_surface_create (ptc->filename, width, height);
+ if (cairo_surface_status (surface))
+ goto CLEANUP_FILENAME;
+
+ cairo_ps_surface_restrict_to_level (surface, level);
+ _cairo_boilerplate_ps_surface_set_creation_date (surface, 0);
+ cairo_surface_set_fallback_resolution (surface, 72., 72.);
+
+ if (content == CAIRO_CONTENT_COLOR) {
+ ptc->target = surface;
+ surface = cairo_surface_create_similar (ptc->target,
+ CAIRO_CONTENT_COLOR,
+ ptc->width, ptc->height);
+ if (cairo_surface_status (surface))
+ goto CLEANUP_TARGET;
+ } else {
+ ptc->target = NULL;
+ }
+
+ status = cairo_surface_set_user_data (surface, &ps_closure_key, ptc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+ surface = cairo_boilerplate_surface_create_in_error (status);
+
+ CLEANUP_TARGET:
+ cairo_surface_destroy (ptc->target);
+ CLEANUP_FILENAME:
+ free (ptc->filename);
+ free (ptc);
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_ps2_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ return _cairo_boilerplate_ps_create_surface (name, content,
+ CAIRO_PS_LEVEL_2,
+ width, height,
+ max_width, max_height,
+ mode,
+ closure);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_ps3_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ return _cairo_boilerplate_ps_create_surface (name, content,
+ CAIRO_PS_LEVEL_3,
+ width, height,
+ max_width, max_height,
+ mode,
+ closure);
+}
+
+static cairo_status_t
+_cairo_boilerplate_ps_finish_surface (cairo_surface_t *surface)
+{
+ ps_target_closure_t *ptc = cairo_surface_get_user_data (surface,
+ &ps_closure_key);
+ cairo_status_t status;
+
+ /* Both surface and ptc->target were originally created at the
+ * same dimensions. We want a 1:1 copy here, so we first clear any
+ * device offset on surface.
+ *
+ * In a more realistic use case of device offsets, the target of
+ * this copying would be of a different size than the source, and
+ * the offset would be desirable during the copy operation. */
+ cairo_surface_set_device_offset (surface, 0, 0);
+
+ if (ptc->target) {
+ cairo_t *cr;
+
+ cr = cairo_create (ptc->target);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_show_page (cr);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ if (status)
+ return status;
+
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ if (status)
+ return status;
+
+ surface = ptc->target;
+ }
+
+ cairo_surface_finish (surface);
+ return cairo_surface_status (surface);
+}
+
+static cairo_status_t
+_cairo_boilerplate_ps_surface_write_to_png (cairo_surface_t *surface,
+ const char *filename)
+{
+ ps_target_closure_t *ptc = cairo_surface_get_user_data (surface,
+ &ps_closure_key);
+ char command[4096];
+ int exitstatus;
+
+ sprintf (command, "gs -q -r72 -g%dx%d -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pngalpha -sOutputFile=%s %s %s",
+ ptc->width, ptc->height, filename,
+ ptc->level == CAIRO_PS_LEVEL_2 ? "-c 2 .setlanguagelevel -f" : "",
+ ptc->filename);
+ exitstatus = system (command);
+#if _XOPEN_SOURCE && HAVE_SIGNAL_H
+ if (WIFSIGNALED (exitstatus))
+ raise (WTERMSIG (exitstatus));
+#endif
+ if (exitstatus)
+ return CAIRO_STATUS_WRITE_ERROR;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_ps_get_image_surface (cairo_surface_t *surface,
+ int page,
+ int width,
+ int height)
+{
+ ps_target_closure_t *ptc = cairo_surface_get_user_data (surface,
+ &ps_closure_key);
+ char *filename;
+ cairo_status_t status;
+
+ if (page == 0)
+ xasprintf (&filename, "%s.png", ptc->filename);
+ else
+ xasprintf (&filename, "%s-%%05d.png", ptc->filename);
+ status = _cairo_boilerplate_ps_surface_write_to_png (surface, filename);
+ if (status)
+ return cairo_boilerplate_surface_create_in_error (status);
+
+ if (page != 0) {
+ free (filename);
+ xasprintf (&filename, "%s-%05d.png", ptc->filename, page);
+ }
+ surface = cairo_boilerplate_get_image_surface_from_png (filename,
+ width,
+ height,
+ ptc->target == NULL);
+
+ remove (filename);
+ free (filename);
+
+ return surface;
+}
+
+static void
+_cairo_boilerplate_ps_cleanup (void *closure)
+{
+ ps_target_closure_t *ptc = closure;
+ if (ptc->target) {
+ cairo_surface_finish (ptc->target);
+ cairo_surface_destroy (ptc->target);
+ }
+ free (ptc->filename);
+ free (ptc);
+}
+
+static void
+_cairo_boilerplate_ps_force_fallbacks (cairo_surface_t *abstract_surface,
+ double x_pixels_per_inch,
+ double y_pixels_per_inch)
+{
+ ps_target_closure_t *ptc = cairo_surface_get_user_data (abstract_surface,
+ &ps_closure_key);
+
+ cairo_paginated_surface_t *paginated;
+ cairo_ps_surface_t *surface;
+
+ if (ptc->target)
+ abstract_surface = ptc->target;
+
+ paginated = (cairo_paginated_surface_t*) abstract_surface;
+ surface = (cairo_ps_surface_t*) paginated->target;
+ surface->force_fallbacks = TRUE;
+ cairo_surface_set_fallback_resolution (&paginated->base,
+ x_pixels_per_inch,
+ y_pixels_per_inch);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "ps2", "ps", ".ps", NULL,
+ CAIRO_SURFACE_TYPE_PS,
+ CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
+ "cairo_ps_surface_create",
+ _cairo_boilerplate_ps2_create_surface,
+ cairo_surface_create_similar,
+ _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, NULL, FALSE, TRUE, TRUE
+ },
+ {
+ "ps2", "ps", ".ps", NULL,
+ CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR, 0,
+ "cairo_ps_surface_create",
+ _cairo_boilerplate_ps2_create_surface,
+ cairo_surface_create_similar,
+ _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, NULL, FALSE, TRUE, TRUE
+ },
+ {
+ "ps3", "ps", ".ps", NULL,
+ CAIRO_SURFACE_TYPE_PS,
+ CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
+ "cairo_ps_surface_create",
+ _cairo_boilerplate_ps3_create_surface,
+ cairo_surface_create_similar,
+ _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, NULL, FALSE, TRUE, TRUE
+ },
+ {
+ "ps3", "ps", ".ps", NULL,
+ CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR, 0,
+ "cairo_ps_surface_create",
+ _cairo_boilerplate_ps3_create_surface,
+ cairo_surface_create_similar,
+ _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, NULL, FALSE, TRUE, TRUE
+ },
+};
+CAIRO_BOILERPLATE (ps, targets)
+
+#else
+
+CAIRO_NO_BOILERPLATE (ps)
+
+#endif
diff --git a/boilerplate/cairo-boilerplate-qt.cpp b/boilerplate/cairo-boilerplate-qt.cpp
new file mode 100755
index 000000000..31c081483
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-qt.cpp
@@ -0,0 +1,114 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Chris Wilson.
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-qt.h>
+
+#include <qapplication.h>
+#include <X11/Xlib.h>
+
+typedef struct _qt_closure {
+ Display *dpy;
+ QApplication *app;
+} qt_closure_t;
+
+static void
+_cairo_boilerplate_qt_cleanup (void *closure)
+{
+ qt_closure_t *qtc = (qt_closure_t *) closure;
+
+ delete qtc->app;
+ XCloseDisplay (qtc->dpy);
+ free (qtc);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_qt_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ qt_closure_t *qtc;
+
+ qtc = (qt_closure_t *) xcalloc (1, sizeof (qt_closure_t));
+ qtc->dpy = XOpenDisplay (NULL);
+ if (qtc->dpy == NULL) {
+ free (qtc);
+ return NULL;
+ }
+
+ if (mode == CAIRO_BOILERPLATE_MODE_TEST)
+ XSynchronize (qtc->dpy, True);
+
+ qtc->app = new QApplication (qtc->dpy);
+ *closure = qtc;
+ return cairo_qt_surface_create_with_qpixmap (content, width, height);
+}
+
+static void
+_cairo_boilerplate_qt_synchronize (void *closure)
+{
+ qt_closure_t *qtc = (qt_closure_t *) closure;
+
+ qtc->app->flush (); /* not sure if this is sufficient */
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "qt", "qt", NULL, NULL,
+ CAIRO_SURFACE_TYPE_QT, CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "cairo_qt_surface_create",
+ _cairo_boilerplate_qt_create_surface,
+ NULL, NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_qt_cleanup
+ },
+ {
+ "qt", "qt", NULL, NULL,
+ CAIRO_SURFACE_TYPE_QT, CAIRO_CONTENT_COLOR, 0,
+ "cairo_qt_surface_create",
+ _cairo_boilerplate_qt_create_surface,
+ NULL, NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_qt_cleanup
+ },
+};
+extern "C" {
+CAIRO_BOILERPLATE (qt, targets)
+}
diff --git a/boilerplate/cairo-boilerplate-quartz.c b/boilerplate/cairo-boilerplate-quartz.c
new file mode 100755
index 000000000..d4ca35383
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-quartz.c
@@ -0,0 +1,76 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © 2004,2007 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 <cworth@cworth.org>
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-quartz.h>
+
+static cairo_surface_t *
+_cairo_boilerplate_quartz_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ cairo_format_t format;
+
+ format = cairo_boilerplate_format_from_content (content);
+
+ *closure = NULL;
+
+ return cairo_quartz_surface_create (format, width, height);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "quartz", "quartz", NULL, NULL,
+ CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "cairo_quartz_surface_create",
+ _cairo_boilerplate_quartz_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL,
+ TRUE, FALSE, FALSE
+ },
+ {
+ "quartz", "quartz", NULL, NULL,
+ CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_CONTENT_COLOR, 0,
+ "cairo_quartz_surface_create",
+ _cairo_boilerplate_quartz_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL,
+ FALSE, FALSE, FALSE
+ },
+};
+CAIRO_BOILERPLATE (quartz, targets)
diff --git a/boilerplate/cairo-boilerplate-scaled-font.h b/boilerplate/cairo-boilerplate-scaled-font.h
new file mode 100755
index 000000000..a7ba2fede
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-scaled-font.h
@@ -0,0 +1,34 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © 2007 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: Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#ifndef _CAIRO_BOILERPLATE_SCALED_FONT_H_
+#define _CAIRO_BOILERPLATE_SCALED_FONT_H_
+
+void
+cairo_boilerplate_scaled_font_set_max_glyphs_cached (cairo_scaled_font_t *scaled_font,
+ int max_glyphs);
+
+#endif
diff --git a/boilerplate/cairo-boilerplate-script.c b/boilerplate/cairo-boilerplate-script.c
new file mode 100755
index 000000000..da8ae3bbd
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-script.c
@@ -0,0 +1,141 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © Chris Wilson
+ *
+ * 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
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON 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: Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include "cairo-script.h"
+
+static cairo_user_data_key_t script_closure_key;
+
+typedef struct _script_target_closure {
+ char *filename;
+ double width;
+ double height;
+} script_target_closure_t;
+
+static cairo_surface_t *
+_cairo_boilerplate_script_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ script_target_closure_t *ptc;
+ cairo_device_t *ctx;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ *closure = ptc = xmalloc (sizeof (script_target_closure_t));
+
+ ptc->width = width;
+ ptc->height = height;
+
+ xasprintf (&ptc->filename, "%s.out.cs", name);
+ xunlink (ptc->filename);
+
+ ctx = cairo_script_create (ptc->filename);
+ surface = cairo_script_surface_create (ctx, content, width, height);
+ cairo_device_destroy (ctx);
+
+ status = cairo_surface_set_user_data (surface,
+ &script_closure_key, ptc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+ surface = cairo_boilerplate_surface_create_in_error (status);
+
+ free (ptc->filename);
+ free (ptc);
+ return surface;
+}
+
+static cairo_status_t
+_cairo_boilerplate_script_finish_surface (cairo_surface_t *surface)
+{
+ cairo_surface_finish (surface);
+ return cairo_surface_status (surface);
+}
+
+static cairo_status_t
+_cairo_boilerplate_script_surface_write_to_png (cairo_surface_t *surface,
+ const char *filename)
+{
+ return CAIRO_STATUS_WRITE_ERROR;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_script_convert_to_image (cairo_surface_t *surface,
+ int page)
+{
+ script_target_closure_t *ptc = cairo_surface_get_user_data (surface,
+ &script_closure_key);
+ return cairo_boilerplate_convert_to_image (ptc->filename, page);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_script_get_image_surface (cairo_surface_t *surface,
+ int page,
+ int width,
+ int height)
+{
+ cairo_surface_t *image;
+
+ image = _cairo_boilerplate_script_convert_to_image (surface, page);
+ cairo_surface_set_device_offset (image,
+ cairo_image_surface_get_width (image) - width,
+ cairo_image_surface_get_height (image) - height);
+ surface = _cairo_boilerplate_get_image_surface (image, 0, width, height);
+ cairo_surface_destroy (image);
+
+ return surface;
+}
+
+static void
+_cairo_boilerplate_script_cleanup (void *closure)
+{
+ script_target_closure_t *ptc = closure;
+ free (ptc->filename);
+ free (ptc);
+}
+
+static const cairo_boilerplate_target_t target[] = {{
+ "script", "script", ".cs", NULL,
+ CAIRO_SURFACE_TYPE_SCRIPT, CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "cairo_script_surface_create",
+ _cairo_boilerplate_script_create_surface,
+ cairo_surface_create_similar,
+ NULL,
+ _cairo_boilerplate_script_finish_surface,
+ _cairo_boilerplate_script_get_image_surface,
+ _cairo_boilerplate_script_surface_write_to_png,
+ _cairo_boilerplate_script_cleanup,
+ NULL, NULL, FALSE, FALSE, FALSE
+}};
+CAIRO_BOILERPLATE (script, target)
diff --git a/boilerplate/cairo-boilerplate-skia.c b/boilerplate/cairo-boilerplate-skia.c
new file mode 100755
index 000000000..c06e7f054
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-skia.c
@@ -0,0 +1,55 @@
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-skia.h>
+
+static cairo_surface_t *
+_cairo_boilerplate_skia_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_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 {
+ return NULL;
+ }
+
+ return cairo_skia_surface_create (format, width, height);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "skia", "skia", NULL, NULL,
+ CAIRO_SURFACE_TYPE_SKIA, CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "cairo_skia_surface_create",
+ _cairo_boilerplate_skia_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, TRUE, FALSE, FALSE
+ },
+ {
+ "skia", "skia", NULL, NULL,
+ CAIRO_SURFACE_TYPE_SKIA, CAIRO_CONTENT_COLOR, 0,
+ "cairo_skia_surface_create",
+ _cairo_boilerplate_skia_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, FALSE, FALSE, FALSE
+ },
+};
+CAIRO_BOILERPLATE (skia, targets)
diff --git a/boilerplate/cairo-boilerplate-svg.c b/boilerplate/cairo-boilerplate-svg.c
new file mode 100755
index 000000000..797106ea6
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-svg.c
@@ -0,0 +1,344 @@
+/* -*- 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 <cworth@cworth.org>
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#if CAIRO_CAN_TEST_SVG_SURFACE
+
+#include <cairo-svg.h>
+#include <cairo-svg-surface-private.h>
+#include <cairo-paginated-surface-private.h>
+
+#if HAVE_SIGNAL_H
+#include <stdlib.h>
+#include <signal.h>
+#endif
+
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#if ! CAIRO_HAS_RECORDING_SURFACE
+#define CAIRO_SURFACE_TYPE_RECORDING CAIRO_INTERNAL_SURFACE_TYPE_RECORDING
+#endif
+
+static const cairo_user_data_key_t svg_closure_key;
+
+typedef struct _svg_target_closure {
+ char *filename;
+ int width, height;
+ cairo_surface_t *target;
+} svg_target_closure_t;
+
+static cairo_surface_t *
+_cairo_boilerplate_svg_create_surface (const char *name,
+ cairo_content_t content,
+ cairo_svg_version_t version,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ svg_target_closure_t *ptc;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ *closure = ptc = xmalloc (sizeof (svg_target_closure_t));
+
+ ptc->width = ceil (width);
+ ptc->height = ceil (height);
+
+ xasprintf (&ptc->filename, "%s.out.svg", name);
+ xunlink (ptc->filename);
+
+ surface = cairo_svg_surface_create (ptc->filename, width, height);
+ if (cairo_surface_status (surface))
+ goto CLEANUP_FILENAME;
+
+ cairo_svg_surface_restrict_to_version (surface, version);
+ cairo_surface_set_fallback_resolution (surface, 72., 72.);
+
+ if (content == CAIRO_CONTENT_COLOR) {
+ ptc->target = surface;
+ surface = cairo_surface_create_similar (ptc->target,
+ CAIRO_CONTENT_COLOR,
+ ptc->width, ptc->height);
+ if (cairo_surface_status (surface))
+ goto CLEANUP_TARGET;
+ } else
+ ptc->target = NULL;
+
+ status = cairo_surface_set_user_data (surface, &svg_closure_key, ptc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+ surface = cairo_boilerplate_surface_create_in_error (status);
+
+ CLEANUP_TARGET:
+ cairo_surface_destroy (ptc->target);
+ CLEANUP_FILENAME:
+ free (ptc->filename);
+ free (ptc);
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_svg11_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ /* current default, but be explicit in case the default changes */
+ return _cairo_boilerplate_svg_create_surface (name, content,
+ CAIRO_SVG_VERSION_1_1,
+ width, height,
+ max_width, max_height,
+ mode,
+ closure);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_svg12_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ return _cairo_boilerplate_svg_create_surface (name, content,
+ CAIRO_SVG_VERSION_1_2,
+ width, height,
+ max_width, max_height,
+ mode,
+ closure);
+}
+
+static cairo_status_t
+_cairo_boilerplate_svg_finish_surface (cairo_surface_t *surface)
+{
+ svg_target_closure_t *ptc = cairo_surface_get_user_data (surface,
+ &svg_closure_key);
+ cairo_status_t status;
+
+ /* Both surface and ptc->target were originally created at the
+ * same dimensions. We want a 1:1 copy here, so we first clear any
+ * device offset on surface.
+ *
+ * In a more realistic use case of device offsets, the target of
+ * this copying would be of a different size than the source, and
+ * the offset would be desirable during the copy operation. */
+ cairo_surface_set_device_offset (surface, 0, 0);
+
+ if (ptc->target) {
+ cairo_t *cr;
+ cr = cairo_create (ptc->target);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_show_page (cr);
+ status = cairo_status (cr);
+ cairo_destroy (cr);
+
+ if (status)
+ return status;
+
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ if (status)
+ return status;
+
+ surface = ptc->target;
+ }
+
+ cairo_surface_finish (surface);
+ status = cairo_surface_status (surface);
+ if (status)
+ return status;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_boilerplate_svg_surface_write_to_png (cairo_surface_t *surface,
+ const char *filename)
+{
+ svg_target_closure_t *ptc = cairo_surface_get_user_data (surface,
+ &svg_closure_key);
+ char command[4096];
+ int exitstatus;
+
+ sprintf (command, "./svg2png %s %s",
+ ptc->filename, filename);
+
+ exitstatus = system (command);
+#if _XOPEN_SOURCE && HAVE_SIGNAL_H
+ if (WIFSIGNALED (exitstatus))
+ raise (WTERMSIG (exitstatus));
+#endif
+ if (exitstatus)
+ return CAIRO_STATUS_WRITE_ERROR;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_svg_convert_to_image (cairo_surface_t *surface)
+{
+ svg_target_closure_t *ptc = cairo_surface_get_user_data (surface,
+ &svg_closure_key);
+
+ return cairo_boilerplate_convert_to_image (ptc->filename, 0);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_svg_get_image_surface (cairo_surface_t *surface,
+ int page,
+ int width,
+ int height)
+{
+ cairo_surface_t *image;
+
+ if (page != 0)
+ return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+
+ image = _cairo_boilerplate_svg_convert_to_image (surface);
+ cairo_surface_set_device_offset (image,
+ cairo_image_surface_get_width (image) - width,
+ cairo_image_surface_get_height (image) - height);
+ surface = _cairo_boilerplate_get_image_surface (image, 0, width, height);
+ cairo_surface_destroy (image);
+
+ return surface;
+}
+
+static void
+_cairo_boilerplate_svg_cleanup (void *closure)
+{
+ svg_target_closure_t *ptc = closure;
+ if (ptc->target != NULL) {
+ cairo_surface_finish (ptc->target);
+ cairo_surface_destroy (ptc->target);
+ }
+ free (ptc->filename);
+ free (ptc);
+}
+
+static void
+_cairo_boilerplate_svg_force_fallbacks (cairo_surface_t *abstract_surface,
+ double x_pixels_per_inch,
+ double y_pixels_per_inch)
+{
+ svg_target_closure_t *ptc = cairo_surface_get_user_data (abstract_surface,
+ &svg_closure_key);
+
+ cairo_paginated_surface_t *paginated;
+ cairo_svg_surface_t *surface;
+
+ if (ptc->target)
+ abstract_surface = ptc->target;
+
+ paginated = (cairo_paginated_surface_t*) abstract_surface;
+ surface = (cairo_svg_surface_t*) paginated->target;
+ surface->force_fallbacks = TRUE;
+ cairo_surface_set_fallback_resolution (&paginated->base,
+ x_pixels_per_inch,
+ y_pixels_per_inch);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ /* 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", ".svg", NULL,
+ CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_svg_surface_create",
+ _cairo_boilerplate_svg11_create_surface,
+ cairo_surface_create_similar,
+ _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, NULL, FALSE, TRUE, TRUE
+ },
+ {
+ "svg11", "svg", ".svg", NULL,
+ CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR, 1,
+ "cairo_svg_surface_create",
+ _cairo_boilerplate_svg11_create_surface,
+ cairo_surface_create_similar,
+ _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, NULL, FALSE, TRUE, TRUE
+ },
+ {
+ "svg12", "svg", ".svg", NULL,
+ CAIRO_SURFACE_TYPE_SVG, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_svg_surface_create",
+ _cairo_boilerplate_svg12_create_surface,
+ cairo_surface_create_similar,
+ _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, NULL, FALSE, TRUE, TRUE
+ },
+ {
+ "svg12", "svg", ".svg", NULL,
+ CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR, 1,
+ "cairo_svg_surface_create",
+ _cairo_boilerplate_svg12_create_surface,
+ cairo_surface_create_similar,
+ _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, NULL, FALSE, TRUE, TRUE
+ },
+};
+CAIRO_BOILERPLATE (svg, targets)
+
+#else
+
+CAIRO_NO_BOILERPLATE (svg)
+
+#endif
diff --git a/boilerplate/cairo-boilerplate-system.c b/boilerplate/cairo-boilerplate-system.c
new file mode 100755
index 000000000..ec23341a4
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-system.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright © 2004 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 <cworth@cworth.org>
+ */
+
+#define _GNU_SOURCE 1 /* for vasprintf */
+
+#include "cairo-boilerplate.h"
+#include "cairo-boilerplate-system.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+void *
+xmalloc (size_t size)
+{
+ void *buf;
+
+ if (size == 0)
+ return NULL;
+
+ buf = malloc (size);
+ if (buf == NULL) {
+ fprintf (stderr, "Error: Out of memory. Exiting.\n");
+ exit (1);
+ }
+
+ return buf;
+}
+
+void *
+xcalloc (size_t nmemb,
+ size_t size)
+{
+ void *buf;
+
+ if (nmemb == 0 || size == 0)
+ return NULL;
+
+ buf = calloc (nmemb, size);
+ if (buf == NULL) {
+ fprintf (stderr, "Error: Out of memory. Exiting\n");
+ exit (1);
+ }
+
+ return buf;
+}
+
+void *
+xrealloc (void *buf,
+ size_t size)
+{
+ buf = realloc (buf, size);
+ if (buf == NULL && size != 0) {
+ fprintf (stderr, "Error: Out of memory. Exiting\n");
+ exit (1);
+ }
+
+ return buf;
+}
+
+void
+xasprintf (char **strp,
+ const char *fmt,
+ ...)
+{
+#ifdef HAVE_VASPRINTF
+ va_list va;
+ int ret;
+
+ va_start (va, fmt);
+ ret = vasprintf (strp, fmt, va);
+ va_end (va);
+
+ if (ret < 0) {
+ fprintf (stderr, "Error: Out of memory. Exiting.\n");
+ exit (1);
+ }
+#else /* !HAVE_VASNPRINTF */
+#define BUF_SIZE 1024
+ va_list va;
+ char buffer[BUF_SIZE];
+ int ret, len;
+
+ va_start (va, fmt);
+ ret = vsnprintf (buffer, sizeof (buffer), fmt, va);
+ va_end (va);
+
+ if (ret < 0) {
+ fprintf (stderr, "Failure in vsnprintf\n");
+ exit (1);
+ }
+
+ len = (ret + sizeof (int)) & -sizeof (int);
+ *strp = malloc (len);
+ if (*strp == NULL) {
+ fprintf (stderr, "Out of memory\n");
+ exit (1);
+ }
+
+ if ((unsigned) ret < sizeof (buffer)) {
+ memcpy (*strp, buffer, ret);
+ } else {
+ va_start (va, fmt);
+ ret = vsnprintf (*strp, len, fmt, va);
+ va_end (va);
+
+ if (ret >= len) {
+ free (*strp);
+ fprintf (stderr, "Overflowed dynamic buffer\n");
+ exit (1);
+ }
+ }
+ memset (*strp + ret, 0, len-ret);
+#endif /* !HAVE_VASNPRINTF */
+}
+
+void
+xunlink (const char *pathname)
+{
+ if (unlink (pathname) < 0 && errno != ENOENT) {
+ fprintf (stderr, "Error: Cannot remove %s: %s\n",
+ pathname, strerror (errno));
+ exit (1);
+ }
+}
+
+char *
+xstrdup (const char *str)
+{
+ if (str == NULL)
+ return NULL;
+
+ str = strdup (str);
+ if (str == NULL) {
+ fprintf (stderr, "Error: Out of memory. Exiting.\n");
+ exit (1);
+ }
+
+ return (char *) str;
+}
diff --git a/boilerplate/cairo-boilerplate-system.h b/boilerplate/cairo-boilerplate-system.h
new file mode 100755
index 000000000..28165671b
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-system.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2004 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 <cworth@cworth.org>
+ */
+
+#ifndef _XMALLOC_H_
+#define _XMALLOC_H_
+
+#include "cairo-boilerplate.h"
+
+#define xmalloc cairo_boilerplate_xmalloc
+void *
+xmalloc (size_t size);
+
+#define xcalloc cairo_boilerplate_xcalloc
+void *
+xcalloc (size_t nmemb,
+ size_t size);
+
+#define xrealloc cairo_boilerplate_xrealloc
+void *
+xrealloc (void *buf,
+ size_t size);
+
+#define xasprintf cairo_boilerplate_xasprintf
+void
+xasprintf (char **strp,
+ const char *fmt,
+ ...) CAIRO_BOILERPLATE_PRINTF_FORMAT(2, 3);
+
+#define xunlink cairo_boilerplate_xunlink
+void
+xunlink (const char *path);
+
+#define xstrdup cairo_boilerplate_xstrdup
+char *
+xstrdup (const char *str);
+
+#endif
diff --git a/boilerplate/cairo-boilerplate-test-surfaces.c b/boilerplate/cairo-boilerplate-test-surfaces.c
new file mode 100755
index 000000000..293b77fff
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-test-surfaces.c
@@ -0,0 +1,462 @@
+/* -*- 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 <cworth@cworth.org>
+ */
+
+#include "../cairo-version.h"
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-types-private.h>
+
+#include <test-compositor-surface.h>
+#include <test-null-compositor-surface.h>
+#if CAIRO_HAS_TEST_PAGINATED_SURFACE
+#include <test-paginated-surface.h>
+#endif
+
+static cairo_surface_t *
+_cairo_boilerplate_test_base_compositor_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ *closure = NULL;
+ return _cairo_test_base_compositor_surface_create (content, ceil (width), ceil (height));
+}
+
+
+static cairo_surface_t *
+_cairo_boilerplate_test_fallback_compositor_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ *closure = NULL;
+ return _cairo_test_fallback_compositor_surface_create (content, ceil (width), ceil (height));
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_test_mask_compositor_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ *closure = NULL;
+ return _cairo_test_mask_compositor_surface_create (content, ceil (width), ceil (height));
+}
+
+
+static cairo_surface_t *
+_cairo_boilerplate_test_traps_compositor_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ *closure = NULL;
+ return _cairo_test_traps_compositor_surface_create (content, ceil (width), ceil (height));
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_test_spans_compositor_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ *closure = NULL;
+ return _cairo_test_spans_compositor_surface_create (content, ceil (width), ceil (height));
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_test_no_fallback_compositor_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ if (mode == CAIRO_BOILERPLATE_MODE_TEST)
+ return NULL;
+
+ *closure = NULL;
+ return _cairo_test_no_fallback_compositor_surface_create (content, ceil (width), ceil (height));
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_test_no_traps_compositor_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ if (mode == CAIRO_BOILERPLATE_MODE_TEST)
+ return NULL;
+
+ *closure = NULL;
+ return _cairo_test_no_traps_compositor_surface_create (content, ceil (width), ceil (height));
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_test_no_spans_compositor_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ if (mode == CAIRO_BOILERPLATE_MODE_TEST)
+ return NULL;
+
+ *closure = NULL;
+ return _cairo_test_no_spans_compositor_surface_create (content, ceil (width), ceil (height));
+}
+
+#if CAIRO_HAS_TEST_PAGINATED_SURFACE
+static const cairo_user_data_key_t test_paginated_closure_key;
+
+typedef struct {
+ cairo_surface_t *target;
+} test_paginated_closure_t;
+
+static cairo_surface_t *
+_cairo_boilerplate_test_paginated_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ test_paginated_closure_t *tpc;
+ cairo_format_t format;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ *closure = tpc = xmalloc (sizeof (test_paginated_closure_t));
+
+ format = cairo_boilerplate_format_from_content (content);
+ tpc->target = cairo_image_surface_create (format,
+ ceil (width), ceil (height));
+
+ surface = _cairo_test_paginated_surface_create (tpc->target);
+ if (cairo_surface_status (surface))
+ goto CLEANUP;
+
+ status = cairo_surface_set_user_data (surface,
+ &test_paginated_closure_key,
+ tpc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+ surface = cairo_boilerplate_surface_create_in_error (status);
+
+ cairo_surface_destroy (tpc->target);
+
+ CLEANUP:
+ free (tpc);
+ return surface;
+}
+
+/* The only reason we go through all these machinations to write a PNG
+ * image is to _really ensure_ that the data actually landed in our
+ * buffer through the paginated surface to the test_paginated_surface.
+ *
+ * If we didn't implement this function then the default
+ * cairo_surface_write_to_png would result in the paginated_surface's
+ * acquire_source_image function replaying the recording-surface to an
+ * intermediate image surface. And in that case the
+ * test_paginated_surface would not be involved and wouldn't be
+ * tested.
+ */
+static cairo_status_t
+_cairo_boilerplate_test_paginated_surface_write_to_png (cairo_surface_t *surface,
+ const char *filename)
+{
+ test_paginated_closure_t *tpc;
+ cairo_status_t status;
+
+ /* show page first. the automatic show_page is too late for us */
+ cairo_surface_show_page (surface);
+ status = cairo_surface_status (surface);
+ if (status)
+ return status;
+
+ tpc = cairo_surface_get_user_data (surface, &test_paginated_closure_key);
+ return cairo_surface_write_to_png (tpc->target, filename);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_test_paginated_get_image_surface (cairo_surface_t *surface,
+ int page,
+ int width,
+ int height)
+{
+ test_paginated_closure_t *tpc;
+ cairo_status_t status;
+
+ /* XXX separate finish as per PDF */
+ if (page != 0)
+ return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+
+ /* show page first. the automatic show_page is too late for us */
+ cairo_surface_show_page (surface);
+ status = cairo_surface_status (surface);
+ if (status)
+ return cairo_boilerplate_surface_create_in_error (status);
+
+ tpc = cairo_surface_get_user_data (surface, &test_paginated_closure_key);
+ return _cairo_boilerplate_get_image_surface (tpc->target, 0, width, height);
+}
+
+static void
+_cairo_boilerplate_test_paginated_cleanup (void *closure)
+{
+ test_paginated_closure_t *tpc = closure;
+
+ cairo_surface_destroy (tpc->target);
+ free (tpc);
+}
+#endif
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "test-base", "base", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "_cairo_test_base_compositor_surface_create",
+ _cairo_boilerplate_test_base_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, TRUE, FALSE, FALSE
+ },
+ {
+ "test-base", "base", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR, 0,
+ "_cairo_test_base_compositor_surface_create",
+ _cairo_boilerplate_test_base_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, FALSE, FALSE, FALSE
+ },
+
+ {
+ "test-fallback", "image", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "_cairo_test_fallback_compositor_surface_create",
+ _cairo_boilerplate_test_fallback_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, FALSE, FALSE, FALSE
+ },
+ {
+ "test-fallback", "image", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR, 0,
+ "_cairo_test_fallback_compositor_surface_create",
+ _cairo_boilerplate_test_fallback_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, FALSE, FALSE, FALSE
+ },
+
+ {
+ "test-mask", "mask", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "_cairo_test_mask_compositor_surface_create",
+ _cairo_boilerplate_test_mask_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, TRUE, FALSE, FALSE
+ },
+ {
+ "test-mask", "mask", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR, 0,
+ "_cairo_test_mask_compositor_surface_create",
+ _cairo_boilerplate_test_mask_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, FALSE, FALSE, FALSE
+ },
+
+ {
+ "test-traps", "traps", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "_cairo_test_traps_compositor_surface_create",
+ _cairo_boilerplate_test_traps_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, TRUE, FALSE, FALSE
+ },
+ {
+ "test-traps", "traps", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR, 0,
+ "_cairo_test_traps_compositor_surface_create",
+ _cairo_boilerplate_test_traps_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, FALSE, FALSE, FALSE
+ },
+
+ {
+ "test-spans", "spans", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "_cairo_test_spans_compositor_surface_create",
+ _cairo_boilerplate_test_spans_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, TRUE, FALSE, FALSE
+ },
+ {
+ "test-spans", "spans", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR, 0,
+ "_cairo_test_spans_compositor_surface_create",
+ _cairo_boilerplate_test_spans_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, FALSE, FALSE, FALSE
+ },
+
+ {
+ "no-fallback", "image", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "_cairo_test_no_fallback_compositor_surface_create",
+ _cairo_boilerplate_test_no_fallback_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, FALSE, FALSE, FALSE
+ },
+ {
+ "no-traps", "traps", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "_cairo_test_no_traps_compositor_surface_create",
+ _cairo_boilerplate_test_no_traps_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, TRUE, FALSE, FALSE
+ },
+ {
+ "no-spans", "spans", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE,
+ CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "_cairo_test_no_spans_compositor_surface_create",
+ _cairo_boilerplate_test_no_spans_compositor_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, TRUE, FALSE, FALSE
+ },
+#if CAIRO_HAS_TEST_PAGINATED_SURFACE
+ {
+ "test-paginated", "image", NULL, NULL,
+ CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
+ CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "_cairo_test_paginated_surface_create",
+ _cairo_boilerplate_test_paginated_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_test_paginated_get_image_surface,
+ _cairo_boilerplate_test_paginated_surface_write_to_png,
+ _cairo_boilerplate_test_paginated_cleanup,
+ NULL, NULL, FALSE, TRUE, FALSE
+ },
+ {
+ "test-paginated", "image", NULL, NULL,
+ CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
+ CAIRO_CONTENT_COLOR, 0,
+ "_cairo_test_paginated_surface_create",
+ _cairo_boilerplate_test_paginated_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_test_paginated_get_image_surface,
+ _cairo_boilerplate_test_paginated_surface_write_to_png,
+ _cairo_boilerplate_test_paginated_cleanup,
+ NULL, NULL, FALSE, TRUE, FALSE
+ },
+#endif
+};
+CAIRO_BOILERPLATE (test, targets)
diff --git a/boilerplate/cairo-boilerplate-tg.c b/boilerplate/cairo-boilerplate-tg.c
new file mode 100755
index 000000000..018f7be9f
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-tg.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2012 SCore Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * Author: Taekyun Kim (podain77@gmail.com)
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-tg.h>
+#include <assert.h>
+
+static cairo_surface_t *
+_cairo_boilerplate_tg_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ cairo_format_t format;
+
+ if (content == CAIRO_CONTENT_COLOR_ALPHA)
+ {
+ format = CAIRO_FORMAT_ARGB32;
+ }
+ else if (content == CAIRO_CONTENT_COLOR)
+ {
+ format = CAIRO_FORMAT_RGB24;
+ }
+ else
+ {
+ assert (0);
+ return NULL;
+ }
+
+ *closure = NULL;
+
+ return cairo_tg_surface_create (format, ceil (width), ceil (height));
+}
+
+static const cairo_boilerplate_target_t targets[] =
+{
+ {
+ "tg", "tg", NULL, NULL,
+ CAIRO_SURFACE_TYPE_TG, CAIRO_CONTENT_COLOR_ALPHA, 0,
+ NULL,
+ _cairo_boilerplate_tg_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL,
+ TRUE, FALSE, FALSE
+ }
+};
+CAIRO_BOILERPLATE (tg, targets)
diff --git a/boilerplate/cairo-boilerplate-vg.c b/boilerplate/cairo-boilerplate-vg.c
new file mode 100755
index 000000000..ee32b3c62
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-vg.c
@@ -0,0 +1,363 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Chris Wilson.
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-vg.h>
+
+ /* XXX Not sure how to handle library specific context initialization */
+//#define USE_SHIVA
+//#define USE_AMANITH
+
+#if CAIRO_HAS_GLX_FUNCTIONS
+
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+
+typedef struct _vg_closure {
+ Display *dpy;
+ int screen;
+ Window win;
+
+ GLXContext ctx;
+ cairo_surface_t *surface;
+} vg_closure_glx_t;
+
+static void
+_cairo_boilerplate_vg_cleanup_glx (void *closure)
+{
+ vg_closure_glx_t *vgc = closure;
+
+#ifdef USE_AMANITH
+ vgDestroyContextAM ();
+#endif
+#ifdef USE_SHIVA
+ vgDestroyContextSH ();
+#endif
+
+ glXDestroyContext (vgc->dpy, vgc->ctx);
+ XDestroyWindow (vgc->dpy, vgc->win);
+ XCloseDisplay (vgc->dpy);
+ free (vgc);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_vg_create_surface_glx (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ int rgba_attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None
+ };
+ int rgb_attribs[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None
+ };
+ XVisualInfo *vi;
+ Display *dpy;
+ Colormap cmap;
+ XSetWindowAttributes swa;
+ cairo_surface_t *surface;
+ cairo_vg_context_t *context;
+ vg_closure_glx_t *vgc;
+
+ vgc = malloc (sizeof (vg_closure_glx_t));
+ *closure = vgc;
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ dpy = XOpenDisplay (NULL);
+ vgc->dpy = dpy;
+ if (vgc->dpy == NULL) {
+ fprintf (stderr, "Failed to open display: %s\n", XDisplayName(0));
+ free (vgc);
+ return NULL;
+ }
+
+ if (content == CAIRO_CONTENT_COLOR)
+ vi = glXChooseVisual (dpy, DefaultScreen (dpy), rgb_attribs);
+ else
+ vi = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
+
+ if (vi == NULL) {
+ fprintf (stderr, "Failed to create RGB, double-buffered visual\n");
+ XCloseDisplay (dpy);
+ free (vgc);
+ return NULL;
+ }
+
+ vgc->ctx = glXCreateContext (dpy, vi, NULL, True);
+ cmap = XCreateColormap (dpy,
+ RootWindow (dpy, vi->screen),
+ vi->visual,
+ AllocNone);
+ swa.colormap = cmap;
+ swa.border_pixel = 0;
+ vgc->win = XCreateWindow (dpy, RootWindow (dpy, vi->screen),
+ -1, -1, 1, 1, 0,
+ vi->depth,
+ InputOutput,
+ vi->visual,
+ CWBorderPixel | CWColormap, &swa);
+ XFreeColormap (dpy, cmap);
+ XFree (vi);
+
+ XMapWindow (dpy, vgc->win);
+
+ /* we need an active context to initialise VG */
+ glXMakeContextCurrent (dpy, vgc->win, vgc->win, vgc->ctx);
+
+#ifdef USE_AMANITH
+ vgInitContextAM (width, height, VG_FALSE, VG_TRUE);
+#endif
+#ifdef USE_SHIVA
+ vgCreateContextSH (width, height);
+#endif
+
+ context = cairo_vg_context_create_for_glx (dpy, vgc->ctx);
+ vgc->surface = cairo_vg_surface_create (context, content, width, height);
+ cairo_vg_context_destroy (context);
+
+ surface = vgc->surface;
+ if (cairo_surface_status (surface))
+ _cairo_boilerplate_vg_cleanup_glx (vgc);
+
+ return surface;
+}
+#endif
+
+#if CAIRO_HAS_EGL_FUNCTIONS
+typedef struct _vg_closure_egl {
+ EGLDisplay *dpy;
+ EGLContext *ctx;
+ EGLSurface *dummy;
+} vg_closure_egl_t;
+
+static void
+_cairo_boilerplate_vg_cleanup_egl (void *closure)
+{
+ vg_closure_egl_t *vgc = closure;
+
+#ifdef USE_AMANITH
+ vgDestroyContextAM ();
+#endif
+#ifdef USE_SHIVA
+ vgDestroyContextSH ();
+#endif
+
+ eglDestroyContext (vgc->dpy, vgc->ctx);
+ eglDestroySurface (vgc->dpy, vgc->dummy);
+ eglTerminate (vgc->dpy);
+ free (vgc);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_vg_create_surface_egl (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ int rgba_attribs[] = {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
+ None
+ };
+ int rgb_attribs[] = {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE_BIT,
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
+ None
+ };
+ int dummy_attribs[] = {
+ EGL_WIDTH, 8, EGL_HEIGHT, 8,
+ EGL_NONE
+ };
+ EGLDisplay *dpy;
+ int major, minor;
+ EGLConfig config;
+ int num_configs;
+ EGLContext *egl_context;
+ EGLSurface *dummy;
+ cairo_vg_context_t *context;
+ cairo_surface_t *surface;
+ vg_closure_egl_t *vgc;
+
+ dpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
+
+ if (! eglInitialize (dpy, &major, &minor))
+ return NULL;
+
+ eglBindAPI (EGL_OPENVG_API);
+
+ if (! eglChooseConfig (dpy,
+ content == CAIRO_CONTENT_COLOR_ALPHA ?
+ rgba_attribs : rgb_attribs,
+ &config, 1, &num_configs) ||
+ num_configs != 1)
+ {
+ return NULL;
+ }
+
+ egl_context = eglCreateContext (dpy, config, NULL, NULL);
+ if (egl_context == NULL)
+ return NULL;
+
+ /* Create a dummy surface in order to enable a context to initialise VG */
+ dummy = eglCreatePbufferSurface (dpy, config, dummy_attribs);
+ if (dummy == NULL)
+ return NULL;
+ if (! eglMakeCurrent (dpy, dummy, dummy, egl_context))
+ return NULL;
+
+#ifdef USE_AMANITH
+ vgInitContextAM (width, height, VG_FALSE, VG_TRUE);
+#endif
+#ifdef USE_SHIVA
+ vgCreateContextSH (width, height);
+#endif
+
+ vgc = xmalloc (sizeof (vg_closure_egl_t));
+ vgc->dpy = dpy;
+ vgc->ctx = egl_context;
+ vgc->dummy = dummy;
+ *closure = vgc;
+
+ context = cairo_vg_context_create_for_egl (vgc->dpy, vgc->ctx);
+ surface = cairo_vg_surface_create (context, content, width, height);
+ cairo_vg_context_destroy (context);
+
+ if (cairo_surface_status (surface))
+ _cairo_boilerplate_vg_cleanup_egl (vgc);
+
+ return surface;
+}
+#endif
+
+static void
+_cairo_boilerplate_vg_synchronize (void *closure)
+{
+ vgFinish ();
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+#if CAIRO_HAS_GLX_FUNCTIONS
+ {
+ "vg-glx", "vg", NULL, NULL,
+ CAIRO_SURFACE_TYPE_VG, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_vg_context_create_for_glx",
+ _cairo_boilerplate_vg_create_surface_glx,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_vg_cleanup_glx,
+ _cairo_boilerplate_vg_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ },
+ {
+ "vg-glx", "vg", NULL, NULL,
+ CAIRO_SURFACE_TYPE_VG, CAIRO_CONTENT_COLOR, 1,
+ "cairo_vg_context_create_for_glx",
+ _cairo_boilerplate_vg_create_surface_glx,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_vg_cleanup_glx,
+ _cairo_boilerplate_vg_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+#endif
+#if CAIRO_HAS_EGL_FUNCTIONS
+ {
+ "vg-egl", "vg", NULL, NULL,
+ CAIRO_SURFACE_TYPE_VG, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_vg_context_create_for_egl",
+ _cairo_boilerplate_vg_create_surface_egl,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_vg_cleanup_egl,
+ _cairo_boilerplate_vg_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ },
+ {
+ "vg-egl", "vg", NULL, NULL,
+ CAIRO_SURFACE_TYPE_VG, CAIRO_CONTENT_COLOR, 1,
+ "cairo_vg_context_create_for_egl",
+ _cairo_boilerplate_vg_create_surface_egl,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_vg_cleanup_egl,
+ _cairo_boilerplate_vg_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+#endif
+};
+CAIRO_BOILERPLATE (vg, targets)
diff --git a/boilerplate/cairo-boilerplate-wgl.c b/boilerplate/cairo-boilerplate-wgl.c
new file mode 100755
index 000000000..908817788
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-wgl.c
@@ -0,0 +1,239 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Chris Wilson.
+ *
+ * Contributor(s):
+ * Zoxc <zoxc32@gmail.com>
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-gl.h>
+
+static const cairo_user_data_key_t gl_closure_key;
+
+typedef struct _wgl_target_closure {
+ HWND wnd;
+ HDC dc;
+ HGLRC rc;
+ cairo_device_t *device;
+ cairo_surface_t *surface;
+} wgl_target_closure_t;
+
+static void
+_cairo_boilerplate_wgl_cleanup (void *closure)
+{
+ wgl_target_closure_t *wgltc = closure;
+
+ cairo_device_finish (wgltc->device);
+ cairo_device_destroy (wgltc->device);
+
+ wglDeleteContext(wgltc->rc);
+
+ ReleaseDC(wgltc->wnd, wgltc->dc);
+ DestroyWindow (wgltc->wnd);
+
+ free (wgltc);
+}
+
+static void
+_cairo_boilerplate_wgl_create_window (int width,
+ int height,
+ wgl_target_closure_t *wgltc)
+{
+ WNDCLASSEXA wincl;
+ PIXELFORMATDESCRIPTOR pfd;
+ int format;
+ cairo_surface_t *surface;
+
+ ZeroMemory (&wincl, sizeof (WNDCLASSEXA));
+ wincl.cbSize = sizeof (WNDCLASSEXA);
+ wincl.hInstance = GetModuleHandle (0);
+ wincl.lpszClassName = "cairo_boilerplate_wgl_dummy";
+ wincl.lpfnWndProc = DefWindowProcA;
+ wincl.style = CS_OWNDC;
+
+ RegisterClassExA (&wincl);
+
+ wgltc->wnd = CreateWindow ("cairo_boilerplate_wgl_dummy", 0, WS_POPUP, 0, 0, width, height, 0, 0, 0, 0);
+ wgltc->dc = GetDC (wgltc->wnd);
+
+ ZeroMemory (&pfd, sizeof (PIXELFORMATDESCRIPTOR));
+ pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 24;
+ pfd.cDepthBits = 16;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ format = ChoosePixelFormat (wgltc->dc, &pfd);
+ SetPixelFormat (wgltc->dc, format, &pfd);
+
+ wgltc->rc = wglCreateContext (wgltc->dc);
+ wgltc->device = cairo_wgl_device_create (wgltc->rc);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_wgl_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ wgl_target_closure_t *wgltc;
+ cairo_surface_t *surface;
+
+ wgltc = calloc (1, sizeof (wgl_target_closure_t));
+
+ *closure = wgltc;
+
+ _cairo_boilerplate_wgl_create_window(0, 0, wgltc);
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ wgltc->surface = surface = cairo_gl_surface_create (wgltc->device,
+ content,
+ ceil (width),
+ ceil (height));
+ if (cairo_surface_status (surface)) {
+ _cairo_boilerplate_wgl_cleanup (wgltc);
+ return NULL;
+ }
+
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_wgl_for_create_window (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ wgl_target_closure_t *wgltc;
+ cairo_surface_t *surface;
+
+ wgltc = calloc (1, sizeof (wgl_target_closure_t));
+
+ *closure = wgltc;
+
+ _cairo_boilerplate_wgl_create_window(width, height, wgltc);
+
+ wgltc->surface = surface = cairo_gl_surface_create_for_dc (wgltc->device,
+ wgltc->dc,
+ ceil (width),
+ ceil (height));
+
+ if (cairo_surface_status (surface)) {
+ _cairo_boilerplate_wgl_cleanup (wgltc);
+ return NULL;
+ }
+
+ return surface;
+}
+
+static cairo_status_t
+_cairo_boilerplate_wgl_finish_window (cairo_surface_t *surface)
+{
+ wgl_target_closure_t *wgltc = cairo_surface_get_user_data (surface,
+ &gl_closure_key);
+
+ if (wgltc != NULL && wgltc->surface != NULL) {
+ cairo_t *cr;
+
+ cr = cairo_create (wgltc->surface);
+ cairo_surface_set_device_offset (surface, 0, 0);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ surface = wgltc->surface;
+ }
+
+ cairo_gl_surface_swapbuffers (surface);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_boilerplate_wgl_synchronize (void *closure)
+{
+ wgl_target_closure_t *wgltc = closure;
+
+ if (cairo_device_acquire (wgltc->device))
+ return;
+
+ glFinish ();
+
+ cairo_device_release (wgltc->device);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "gl", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_gl_surface_create",
+ _cairo_boilerplate_wgl_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_wgl_cleanup,
+ _cairo_boilerplate_wgl_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ },
+ {
+ "gl-dc", "gl", NULL, NULL,
+ CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_gl_surface_create_for_dc",
+ _cairo_boilerplate_wgl_for_create_window,
+ NULL,
+ _cairo_boilerplate_wgl_finish_window,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_wgl_cleanup,
+ _cairo_boilerplate_wgl_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+};
+
+CAIRO_BOILERPLATE (wgl, targets)
diff --git a/boilerplate/cairo-boilerplate-win32-printing.c b/boilerplate/cairo-boilerplate-win32-printing.c
new file mode 100755
index 000000000..625d52c53
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-win32-printing.c
@@ -0,0 +1,407 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © 2004,2006 Red Hat, Inc.
+ * Copyright © 2007, Adrian Johnson
+ *
+ * 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.
+ *
+ * Authors: Carl D. Worth <cworth@cworth.org>
+ * Adrian Johnson <ajohnson@redneon.com>
+ */
+
+/* We require Windows 2000 features such as GetDefaultPrinter() */
+#if !defined(WINVER) || (WINVER < 0x0500)
+# define WINVER 0x0500
+#endif
+#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
+# define _WIN32_WINNT 0x0500
+#endif
+
+#include "cairo-boilerplate-private.h"
+
+#if CAIRO_CAN_TEST_WIN32_PRINTING_SURFACE
+
+#include <cairo-win32.h>
+#include <cairo-paginated-surface-private.h>
+
+#include <windows.h>
+
+#if !defined(POSTSCRIPT_IDENTIFY)
+# define POSTSCRIPT_IDENTIFY 0x1015
+#endif
+
+#if !defined(PSIDENT_GDICENTRIC)
+# define PSIDENT_GDICENTRIC 0x0000
+#endif
+
+#if !defined(GET_PS_FEATURESETTING)
+# define GET_PS_FEATURESETTING 0x1019
+#endif
+
+#if !defined(FEATURESETTING_PSLEVEL)
+# define FEATURESETTING_PSLEVEL 0x0002
+#endif
+
+static cairo_status_t
+_cairo_win32_print_gdi_error (const char *context)
+{
+ void *lpMsgBuf;
+ DWORD last_error = GetLastError ();
+
+ if (!FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ last_error,
+ MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPWSTR) &lpMsgBuf,
+ 0, NULL)) {
+ fprintf (stderr, "%s: Unknown GDI error", context);
+ } else {
+ fprintf (stderr, "%s: %S", context, (wchar_t *)lpMsgBuf);
+
+ LocalFree (lpMsgBuf);
+ }
+
+ fflush (stderr);
+
+ /* We should switch off of last_status, but we'd either return
+ * CAIRO_STATUS_NO_MEMORY or CAIRO_STATUS_UNKNOWN_ERROR and there
+ * is no CAIRO_STATUS_UNKNOWN_ERROR.
+ */
+ return CAIRO_STATUS_NO_MEMORY;
+}
+
+static cairo_user_data_key_t win32_closure_key;
+
+typedef struct _win32_target_closure {
+ char *filename;
+ int width;
+ int height;
+ cairo_surface_t *target;
+ HDC dc;
+ int left_margin;
+ int bottom_margin;
+} win32_target_closure_t;
+
+static cairo_bool_t
+printer_is_postscript_level_3 (HDC dc)
+{
+ DWORD word;
+ INT ps_feature, ps_level;
+
+ word = PSIDENT_GDICENTRIC;
+ if (ExtEscape (dc, POSTSCRIPT_IDENTIFY, sizeof(DWORD), (char *)&word, 0, (char *)NULL) <= 0)
+ return FALSE;
+
+ ps_feature = FEATURESETTING_PSLEVEL;
+ if (ExtEscape (dc, GET_PS_FEATURESETTING, sizeof(INT),
+ (char *)&ps_feature, sizeof(INT), (char *)&ps_level) <= 0)
+ return FALSE;
+
+ if (ps_level >= 3)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+create_printer_dc (win32_target_closure_t *ptc)
+{
+ char *printer_name;
+ DWORD size;
+ int x_dpi, y_dpi, left_margin, top_margin, page_height, printable_height;
+ XFORM xform;
+
+ ptc->dc = NULL;
+ GetDefaultPrinter (NULL, &size);
+ printer_name = malloc (size);
+
+ if (printer_name == NULL)
+ return;
+
+ if (GetDefaultPrinter (printer_name, &size) == 0) {
+ free (printer_name);
+ return;
+ }
+
+ /* printf("\nPrinting to : %s\n", printer_name); */
+ ptc->dc = CreateDC (NULL, printer_name, NULL, NULL);
+ free (printer_name);
+
+ if (!printer_is_postscript_level_3 (ptc->dc)) {
+ printf("The default printer driver must be a color PostScript level 3 printer\n");
+ ptc->dc = NULL;
+ return;
+ }
+
+ /* The printer device units on win32 are 1 unit == 1 dot and the
+ * origin is the start of the printable area. We transform the
+ * cordinate space to 1 unit is 1 point as expected by the
+ * tests. As the page size is larger than the test surface, the
+ * origin is translated down so that the each test is drawn at the
+ * bottom left corner of the page. This is because the bottom left
+ * corner of the PNG image that ghostscript creates is positioned
+ * at origin of the PS coordinates (ie the bottom left of the
+ * page). The left and bottom margins are stored in
+ * win32_target_closure as size of the PNG image needs to be
+ * increased because the test output is offset from the bottom
+ * left by the non printable margins. After the PNG is created the
+ * margins will be chopped off so the image matches the reference
+ * image.
+ */
+ printable_height = GetDeviceCaps (ptc->dc, VERTRES);
+ x_dpi = GetDeviceCaps (ptc->dc, LOGPIXELSX);
+ y_dpi = GetDeviceCaps (ptc->dc, LOGPIXELSY);
+ left_margin = GetDeviceCaps (ptc->dc, PHYSICALOFFSETX);
+ top_margin = GetDeviceCaps (ptc->dc, PHYSICALOFFSETY);
+ page_height = GetDeviceCaps (ptc->dc, PHYSICALHEIGHT);
+
+ SetGraphicsMode (ptc->dc, GM_ADVANCED);
+ xform.eM11 = x_dpi/72.0;
+ xform.eM12 = 0;
+ xform.eM21 = 0;
+ xform.eM22 = y_dpi/72.0;
+ xform.eDx = 0;
+ xform.eDy = printable_height - ptc->height*y_dpi/72.0;
+ if (!SetWorldTransform (ptc->dc, &xform)) {
+ _cairo_win32_print_gdi_error ("cairo-boilerplate-win32-printing:SetWorldTransform");
+ return;
+ }
+
+ ptc->left_margin = 72.0*left_margin/x_dpi;
+ ptc->bottom_margin = 72.0*(page_height - printable_height - top_margin)/y_dpi;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_win32_printing_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ win32_target_closure_t *ptc;
+ cairo_surface_t *surface;
+ DOCINFO di;
+
+ if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
+ content = CAIRO_CONTENT_COLOR_ALPHA;
+
+ *closure = ptc = xmalloc (sizeof (win32_target_closure_t));
+
+ xasprintf (&ptc->filename, "%s.out.ps", name);
+ xunlink (ptc->filename);
+
+ memset (&di, 0, sizeof (DOCINFO));
+ di.cbSize = sizeof (DOCINFO);
+ di.lpszDocName = ptc->filename;
+ di.lpszOutput = ptc->filename;
+
+ ptc->width = width;
+ ptc->height = height;
+
+ create_printer_dc (ptc);
+ if (ptc->dc == NULL) {
+ printf("\nFailed to create printer\n");
+ free (ptc->filename);
+ free (ptc);
+ return NULL;
+ }
+ StartDoc (ptc->dc, &di);
+ StartPage (ptc->dc);
+ surface = cairo_win32_printing_surface_create (ptc->dc);
+ if (cairo_surface_status (surface)) {
+ free (ptc->filename);
+ free (ptc);
+ return NULL;
+ }
+ cairo_surface_set_fallback_resolution (surface, 72., 72.);
+
+ if (content == CAIRO_CONTENT_COLOR) {
+ ptc->target = surface;
+ surface = cairo_surface_create_similar (ptc->target,
+ CAIRO_CONTENT_COLOR,
+ width, height);
+ } else {
+ ptc->target = NULL;
+ }
+
+ if (cairo_surface_set_user_data (surface,
+ &win32_closure_key,
+ ptc,
+ NULL) != CAIRO_STATUS_SUCCESS) {
+ cairo_surface_destroy (surface);
+ if (ptc->target != NULL)
+ cairo_surface_destroy (ptc->target);
+ free (ptc->filename);
+ free (ptc);
+ return NULL;
+ }
+
+ return surface;
+}
+
+static cairo_status_t
+_cairo_boilerplate_win32_printing_surface_write_to_png (cairo_surface_t *surface,
+ const char *filename)
+{
+ win32_target_closure_t *ptc = cairo_surface_get_user_data (surface, &win32_closure_key);
+ char command[4096];
+ cairo_surface_t *src_image, *dst_image;
+ cairo_t *cr;
+ cairo_status_t status;
+
+ /* Both surface and ptc->target were originally created at the
+ * same dimensions. We want a 1:1 copy here, so we first clear any
+ * device offset on surface.
+ *
+ * In a more realistic use case of device offsets, the target of
+ * this copying would be of a different size than the source, and
+ * the offset would be desirable during the copy operation. */
+ cairo_surface_set_device_offset (surface, 0, 0);
+
+ if (ptc->target) {
+ cairo_t *cr;
+ cr = cairo_create (ptc->target);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_show_page (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_finish (surface);
+ surface = ptc->target;
+ }
+
+ cairo_surface_finish (surface);
+ EndPage (ptc->dc);
+ EndDoc (ptc->dc);
+ sprintf (command, "gs -q -r72 -g%dx%d -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pngalpha -sOutputFile=%s %s",
+ ptc->width + ptc->left_margin, ptc->height + ptc->bottom_margin, filename, ptc->filename);
+
+ if (system (command) != 0)
+ return CAIRO_STATUS_WRITE_ERROR;
+
+ /* Create a new image from the ghostscript image that has the
+ * left and bottom margins removed */
+
+ src_image = cairo_image_surface_create_from_png (filename);
+ status = cairo_surface_status (src_image);
+ if (status)
+ return status;
+
+ dst_image = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ ptc->width,
+ ptc->height);
+ cr = cairo_create (dst_image);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, src_image, -ptc->left_margin, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_write_to_png (dst_image, filename);
+ status = cairo_surface_status (dst_image);
+ if (status)
+ return status;
+
+ cairo_surface_destroy (src_image);
+ cairo_surface_destroy (dst_image);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_win32_printing_get_image_surface (cairo_surface_t *surface,
+ int page,
+ int width,
+ int height)
+{
+ win32_target_closure_t *ptc = cairo_surface_get_user_data (surface,
+ &win32_closure_key);
+ char *filename;
+ cairo_status_t status;
+
+ /* XXX test paginated interface */
+ if (page != 0)
+ return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+
+ xasprintf (&filename, "%s.png", ptc->filename);
+ status = _cairo_boilerplate_win32_printing_surface_write_to_png (surface, filename);
+ if (status)
+ return cairo_boilerplate_surface_create_in_error (status);
+
+ surface = cairo_boilerplate_get_image_surface_from_png (filename,
+ width,
+ height,
+ ptc->target == NULL);
+
+ remove (filename);
+ free (filename);
+
+ return surface;
+}
+
+static void
+_cairo_boilerplate_win32_printing_cleanup (void *closure)
+{
+ win32_target_closure_t *ptc = closure;
+
+ if (ptc->target)
+ cairo_surface_destroy (ptc->target);
+ free (ptc->filename);
+ free (ptc);
+ DeleteDC (ptc->dc);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "win32-printing", "win32", ".ps", NULL,
+ CAIRO_SURFACE_TYPE_WIN32_PRINTING,
+ CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED, 0,
+ "cairo_win32_printing_surface_create",
+ _cairo_boilerplate_win32_printing_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_win32_printing_get_image_surface,
+ _cairo_boilerplate_win32_printing_surface_write_to_png,
+ _cairo_boilerplate_win32_printing_cleanup,
+ NULL, NULL, FALSE, TRUE, TRUE
+ },
+ {
+ "win32-printing", "win32", ".ps", NULL,
+ CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR, 0,
+ "cairo_win32_printing_surface_create",
+ _cairo_boilerplate_win32_printing_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_win32_printing_get_image_surface,
+ _cairo_boilerplate_win32_printing_surface_write_to_png,
+ _cairo_boilerplate_win32_printing_cleanup,
+ NULL, NULL, FALSE, TRUE, TRUE
+ },
+};
+CAIRO_BOILERPLATE (win32_printing, targets)
+
+#else
+
+CAIRO_NO_BOILERPLATE (win32_printing)
+
+#endif
diff --git a/boilerplate/cairo-boilerplate-win32.c b/boilerplate/cairo-boilerplate-win32.c
new file mode 100755
index 000000000..7469cc749
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-win32.c
@@ -0,0 +1,77 @@
+/* -*- 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 <cworth@cworth.org>
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-win32.h>
+
+static cairo_surface_t *
+_cairo_boilerplate_win32_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ cairo_format_t format;
+
+ format = cairo_boilerplate_format_from_content (content);
+
+ *closure = NULL;
+
+ return cairo_win32_surface_create_with_dib (format, width, height);
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ {
+ "win32", "win32", NULL, NULL,
+ CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR, 0,
+ "cairo_win32_surface_create_with_dib",
+ _cairo_boilerplate_win32_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, TRUE, FALSE, FALSE
+ },
+ /* Testing the win32 surface isn't interesting, since for
+ * ARGB images it just chains to the image backend
+ */
+ {
+ "win32", "win32", NULL, NULL,
+ CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "cairo_win32_surface_create_with_dib",
+ _cairo_boilerplate_win32_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL, NULL, FALSE, FALSE, FALSE
+ },
+};
+CAIRO_BOILERPLATE (win32, targets)
diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c
new file mode 100755
index 000000000..ffefecb93
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-xcb.c
@@ -0,0 +1,876 @@
+/* -*- 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 <cworth@cworth.org>
+ */
+
+#include "cairo-boilerplate-private.h"
+
+#include <cairo-xcb.h>
+
+#include <assert.h>
+
+/* Errors have response_type == 0 */
+#define CAIRO_XCB_ERROR 0
+
+static const cairo_user_data_key_t xcb_closure_key;
+
+typedef struct _xcb_target_closure {
+ xcb_connection_t *c;
+ cairo_device_t *device;
+ uint32_t drawable;
+ cairo_bool_t is_pixmap;
+ cairo_surface_t *surface;
+} xcb_target_closure_t;
+
+static cairo_status_t
+_cairo_boilerplate_xcb_handle_errors (xcb_target_closure_t *xtc)
+{
+ xcb_generic_event_t *ev = NULL;
+
+ /* Ignore all MappingNotify events; those might happen without us causing them */
+ do {
+ free(ev);
+ ev = xcb_poll_for_event(xtc->c);
+ } while (ev != NULL && ev->response_type == XCB_MAPPING_NOTIFY);
+
+ if (ev != NULL) {
+ if (ev->response_type == CAIRO_XCB_ERROR) {
+ xcb_generic_error_t *error = (xcb_generic_error_t *) ev;
+
+ fprintf (stderr,
+ "Detected error during xcb run: error=%d, "
+ "seqno=0x%02x, major=%d, minor=%d\n",
+ error->error_code, error->sequence,
+ error->major_code, error->minor_code);
+ } else {
+ fprintf (stderr,
+ "Detected unexpected event during xcb run: type=%d, seqno=0x%02x\n",
+ ev->response_type, ev->sequence);
+ }
+ free (ev);
+
+ /* Silently discard all following errors */
+ while ((ev = xcb_poll_for_event (xtc->c)) != NULL)
+ free (ev);
+
+ return CAIRO_STATUS_WRITE_ERROR;
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_boilerplate_xcb_sync_server (xcb_target_closure_t *xtc)
+{
+ free (xcb_get_input_focus_reply (xtc->c,
+ xcb_get_input_focus (xtc->c), NULL));
+}
+
+static void
+_cairo_boilerplate_xcb_setup_test_surface (cairo_surface_t *surface)
+{
+
+ /* For testing purposes, tell the X server to strictly adhere to the
+ * Render specification.
+ */
+ cairo_xcb_device_debug_set_precision(cairo_surface_get_device(surface),
+ XCB_RENDER_POLY_MODE_PRECISE);
+}
+
+static void
+_cairo_boilerplate_xcb_cleanup (void *closure)
+{
+ xcb_target_closure_t *xtc = closure;
+ cairo_status_t status;
+
+ cairo_surface_finish (xtc->surface);
+ if (xtc->is_pixmap)
+ xcb_free_pixmap (xtc->c, xtc->drawable);
+ else
+ xcb_destroy_window (xtc->c, xtc->drawable);
+ cairo_surface_destroy (xtc->surface);
+
+ cairo_device_finish (xtc->device);
+ cairo_device_destroy (xtc->device);
+
+ /* First synchronize with the X server to make sure there are no more errors
+ * in-flight which we would miss otherwise */
+ _cairo_boilerplate_xcb_sync_server (xtc);
+ status = _cairo_boilerplate_xcb_handle_errors (xtc);
+ assert (status == CAIRO_STATUS_SUCCESS);
+
+ xcb_disconnect (xtc->c);
+
+ free (xtc);
+}
+
+static void
+_cairo_boilerplate_xcb_synchronize (void *closure)
+{
+ xcb_target_closure_t *xtc = closure;
+ cairo_status_t status;
+ free (xcb_get_image_reply (xtc->c,
+ xcb_get_image (xtc->c, XCB_IMAGE_FORMAT_Z_PIXMAP,
+ xtc->drawable, 0, 0, 1, 1, /* AllPlanes */ -1),
+ 0));
+
+ status = _cairo_boilerplate_xcb_handle_errors (xtc);
+ assert (status == CAIRO_STATUS_SUCCESS);
+}
+
+static xcb_render_pictforminfo_t *
+find_depth (xcb_connection_t *connection,
+ int depth,
+ void **formats_out)
+{
+ xcb_render_query_pict_formats_reply_t *formats;
+ xcb_render_query_pict_formats_cookie_t cookie;
+ xcb_render_pictforminfo_iterator_t i;
+
+ cookie = xcb_render_query_pict_formats (connection);
+ xcb_flush (connection);
+
+ formats = xcb_render_query_pict_formats_reply (connection, cookie, 0);
+ if (formats == NULL)
+ return NULL;
+
+ for (i = xcb_render_query_pict_formats_formats_iterator (formats);
+ i.rem;
+ xcb_render_pictforminfo_next (&i))
+ {
+ if (XCB_RENDER_PICT_TYPE_DIRECT != i.data->type)
+ continue;
+
+ if (depth != i.data->depth)
+ continue;
+
+ *formats_out = formats;
+ return i.data;
+ }
+
+ free (formats);
+ return NULL;
+}
+
+static const cairo_user_data_key_t key;
+
+struct similar {
+ xcb_connection_t *connection;
+ xcb_drawable_t pixmap;
+};
+
+static void _destroy_similar (void *closure)
+{
+ struct similar *similar = closure;
+
+ xcb_free_pixmap (similar->connection, similar->pixmap);
+ free (similar);
+}
+
+struct xcb_info {
+ xcb_render_query_pict_formats_reply_t *formats;
+ xcb_render_pictforminfo_t *render_format[3];
+};
+
+static cairo_surface_t *
+_cairo_boilerplate_xcb_create_similar (cairo_surface_t *other,
+ cairo_content_t content,
+ int width, int height)
+{
+ cairo_device_t *device = cairo_surface_get_device (other);
+ struct xcb_info *info = cairo_device_get_user_data (device, &key);
+ xcb_screen_t *root;
+ cairo_surface_t *surface;
+ struct similar *similar;
+ xcb_render_pictforminfo_t *render_format;
+ int depth;
+
+ similar = malloc (sizeof (*similar));
+
+ switch (content) {
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ depth = 32;
+ render_format = info->render_format[0];
+ break;
+ case CAIRO_CONTENT_COLOR:
+ depth = 24;
+ render_format = info->render_format[1];
+ break;
+ case CAIRO_CONTENT_ALPHA:
+ depth = 8;
+ render_format = info->render_format[2];
+ break;
+ }
+
+ similar->connection =
+ cairo_xcb_device_get_connection (cairo_surface_get_device(other));
+ similar->pixmap = xcb_generate_id (similar->connection);
+
+ root = xcb_setup_roots_iterator(xcb_get_setup(similar->connection)).data;
+ xcb_create_pixmap (similar->connection, depth,
+ similar->pixmap, root->root,
+ width, height);
+
+ surface = cairo_xcb_surface_create_with_xrender_format (similar->connection,
+ root,
+ similar->pixmap,
+ render_format,
+ width, height);
+ cairo_surface_set_user_data (surface, &key, similar, _destroy_similar);
+
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xcb_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ xcb_screen_t *root;
+ xcb_target_closure_t *xtc;
+ xcb_connection_t *c;
+ xcb_render_query_pict_formats_cookie_t formats_cookie;
+ xcb_render_pictforminfo_t *render_format;
+ xcb_render_pictforminfo_iterator_t i;
+ struct xcb_info *info;
+ int depth;
+ xcb_void_cookie_t cookie;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+
+ *closure = xtc = xmalloc (sizeof (xcb_target_closure_t));
+ info = xcalloc (1, sizeof (struct xcb_info));
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ xtc->c = c = xcb_connect(NULL,NULL);
+ if (c == NULL || xcb_connection_has_error(c)) {
+ free (xtc);
+ return NULL;
+ }
+
+ root = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
+ formats_cookie = xcb_render_query_pict_formats (c);
+
+ xtc->surface = NULL;
+ xtc->is_pixmap = TRUE;
+ xtc->drawable = xcb_generate_id (c);
+ switch (content) {
+ case CAIRO_CONTENT_COLOR:
+ depth = 24;
+ break;
+
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ depth = 32;
+ break;
+
+ case CAIRO_CONTENT_ALPHA: /* would be XCB_PICT_STANDARD_A_8 */
+ default:
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+
+ cookie = xcb_create_pixmap_checked (c, depth,
+ xtc->drawable, root->root,
+ width, height);
+
+ /* slow, but sure */
+ if (xcb_request_check (c, cookie) != NULL) {
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+
+ info->formats = xcb_render_query_pict_formats_reply (c, formats_cookie, 0);
+ if (info->formats == NULL)
+ return NULL;
+
+ for (i = xcb_render_query_pict_formats_formats_iterator (info->formats);
+ i.rem;
+ xcb_render_pictforminfo_next (&i))
+ {
+ if (XCB_RENDER_PICT_TYPE_DIRECT != i.data->type)
+ continue;
+
+ if (i.data->depth == 32) {
+ if (info->render_format[0] == 0)
+ info->render_format[0] = i.data;
+ } else if (i.data->depth == 24) {
+ if (info->render_format[1] == 0)
+ info->render_format[1] = i.data;
+ } else if (i.data->depth == 8) {
+ if (info->render_format[2] == 0)
+ info->render_format[2] = i.data;
+ }
+ }
+
+ assert (info->render_format[0]);
+ assert (info->render_format[1]);
+ assert (info->render_format[2]);
+
+ switch (content) {
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ render_format = info->render_format[0];
+ break;
+
+ case CAIRO_CONTENT_COLOR:
+ render_format = info->render_format[1];
+ break;
+
+ case CAIRO_CONTENT_ALPHA: /* would be XCB_PICT_STANDARD_A_8 */
+ render_format = info->render_format[2];
+ break;
+ }
+
+ surface = cairo_xcb_surface_create_with_xrender_format (c, root,
+ xtc->drawable,
+ render_format,
+ width, height);
+ cairo_device_set_user_data (cairo_surface_get_device (surface), &key, info, free);
+ if (mode != CAIRO_BOILERPLATE_MODE_PERF)
+ _cairo_boilerplate_xcb_setup_test_surface(surface);
+
+ xtc->device = cairo_device_reference (cairo_surface_get_device (surface));
+ status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+
+ _cairo_boilerplate_xcb_cleanup (xtc);
+ return cairo_boilerplate_surface_create_in_error (status);
+}
+
+static xcb_visualtype_t *
+lookup_visual (xcb_screen_t *s,
+ xcb_visualid_t visual)
+{
+ xcb_depth_iterator_t d;
+
+ d = xcb_screen_allowed_depths_iterator (s);
+ for (; d.rem; xcb_depth_next (&d)) {
+ xcb_visualtype_iterator_t v = xcb_depth_visuals_iterator (d.data);
+ for (; v.rem; xcb_visualtype_next (&v)) {
+ if (v.data->visual_id == visual)
+ return v.data;
+ }
+ }
+
+ return 0;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xcb_create_window (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ xcb_target_closure_t *xtc;
+ xcb_connection_t *c;
+ xcb_screen_t *s;
+ xcb_void_cookie_t cookie;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+ uint32_t values[] = { 1 };
+
+ *closure = xtc = xmalloc (sizeof (xcb_target_closure_t));
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ xtc->c = c = xcb_connect(NULL,NULL);
+ if (xcb_connection_has_error(c)) {
+ free (xtc);
+ return NULL;
+ }
+
+ xtc->surface = NULL;
+
+ s = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
+ if (width > s->width_in_pixels || height > s->height_in_pixels) {
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+
+ xtc->is_pixmap = FALSE;
+ xtc->drawable = xcb_generate_id (c);
+ cookie = xcb_create_window_checked (c,
+ s->root_depth,
+ xtc->drawable,
+ s->root,
+ 0, 0, width, height, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ s->root_visual,
+ XCB_CW_OVERRIDE_REDIRECT,
+ values);
+ xcb_map_window (c, xtc->drawable);
+
+ /* slow, but sure */
+ if (xcb_request_check (c, cookie) != NULL) {
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+
+ surface = cairo_xcb_surface_create (c,
+ xtc->drawable,
+ lookup_visual (s, s->root_visual),
+ width, height);
+
+ xtc->device = cairo_device_reference (cairo_surface_get_device (surface));
+ status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+
+ _cairo_boilerplate_xcb_cleanup (xtc);
+ return cairo_boilerplate_surface_create_in_error (status);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xcb_create_window_db (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ xcb_target_closure_t *xtc;
+ xcb_connection_t *c;
+ xcb_screen_t *s;
+ xcb_void_cookie_t cookie;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+ uint32_t values[] = { 1 };
+
+ *closure = xtc = xmalloc (sizeof (xcb_target_closure_t));
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ xtc->c = c = xcb_connect(NULL,NULL);
+ if (xcb_connection_has_error(c)) {
+ free (xtc);
+ return NULL;
+ }
+
+ xtc->surface = NULL;
+
+ s = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
+ if (width > s->width_in_pixels || height > s->height_in_pixels) {
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+
+ xtc->is_pixmap = FALSE;
+ xtc->drawable = xcb_generate_id (c);
+ cookie = xcb_create_window_checked (c,
+ s->root_depth,
+ xtc->drawable,
+ s->root,
+ 0, 0, width, height, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ s->root_visual,
+ XCB_CW_OVERRIDE_REDIRECT,
+ values);
+ xcb_map_window (c, xtc->drawable);
+
+ /* slow, but sure */
+ if (xcb_request_check (c, cookie) != NULL) {
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+
+ xtc->surface = cairo_xcb_surface_create (c,
+ xtc->drawable,
+ lookup_visual (s, s->root_visual),
+ width, height);
+ surface = cairo_surface_create_similar (xtc->surface, content, width, height);
+
+ xtc->device = cairo_device_reference (cairo_surface_get_device (surface));
+ status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+
+ _cairo_boilerplate_xcb_cleanup (xtc);
+ return cairo_boilerplate_surface_create_in_error (status);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xcb_create_render_0_0 (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ xcb_screen_t *root;
+ xcb_target_closure_t *xtc;
+ xcb_connection_t *c;
+ xcb_render_pictforminfo_t *render_format;
+ int depth;
+ xcb_void_cookie_t cookie;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+ void *formats;
+
+ *closure = xtc = xmalloc (sizeof (xcb_target_closure_t));
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ xtc->c = c = xcb_connect(NULL,NULL);
+ if (xcb_connection_has_error(c)) {
+ free (xtc);
+ return NULL;
+ }
+
+ root = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
+
+ xtc->surface = NULL;
+ xtc->is_pixmap = TRUE;
+ xtc->drawable = xcb_generate_id (c);
+ switch (content) {
+ case CAIRO_CONTENT_COLOR:
+ depth = 24;
+ cookie = xcb_create_pixmap_checked (c, depth,
+ xtc->drawable, root->root,
+ width, height);
+ break;
+
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ depth = 32;
+ cookie = xcb_create_pixmap_checked (c, depth,
+ xtc->drawable, root->root,
+ width, height);
+ break;
+
+ case CAIRO_CONTENT_ALPHA: /* would be XCB_PICT_STANDARD_A_8 */
+ default:
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+
+ /* slow, but sure */
+ if (xcb_request_check (c, cookie) != NULL) {
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+ xcb_flush (c);
+
+ render_format = find_depth (c, depth, &formats);
+ if (render_format == NULL) {
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+
+ surface = cairo_xcb_surface_create_with_xrender_format (c, root,
+ xtc->drawable,
+ render_format,
+ width, height);
+ if (cairo_surface_status (surface)) {
+ free (formats);
+ xcb_disconnect (c);
+ free (xtc);
+ return surface;
+ }
+
+ xtc->device = cairo_device_reference (cairo_surface_get_device (surface));
+ cairo_xcb_device_debug_cap_xrender_version (xtc->device, 0, 0);
+
+ assert (cairo_surface_get_device (surface) == xtc->device);
+
+ status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+
+ _cairo_boilerplate_xcb_cleanup (xtc);
+ return cairo_boilerplate_surface_create_in_error (status);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xcb_create_fallback (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ xcb_target_closure_t *xtc;
+ xcb_connection_t *c;
+ xcb_screen_t *s;
+ xcb_void_cookie_t cookie;
+ cairo_surface_t *surface;
+ cairo_status_t status;
+ uint32_t values[] = { 1 };
+
+ *closure = xtc = xmalloc (sizeof (xcb_target_closure_t));
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
+ xtc->c = c = xcb_connect (NULL,NULL);
+ if (xcb_connection_has_error(c)) {
+ free (xtc);
+ return NULL;
+ }
+
+ s = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
+ if (width > s->width_in_pixels || height > s->height_in_pixels) {
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+
+ xtc->surface = NULL;
+ xtc->is_pixmap = FALSE;
+ xtc->drawable = xcb_generate_id (c);
+ cookie = xcb_create_window_checked (c,
+ s->root_depth,
+ xtc->drawable,
+ s->root,
+ 0, 0, width, height, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ s->root_visual,
+ XCB_CW_OVERRIDE_REDIRECT,
+ values);
+ xcb_map_window (c, xtc->drawable);
+
+ /* slow, but sure */
+ if (xcb_request_check (c, cookie) != NULL) {
+ xcb_disconnect (c);
+ free (xtc);
+ return NULL;
+ }
+
+ surface = cairo_xcb_surface_create (c,
+ xtc->drawable,
+ lookup_visual (s, s->root_visual),
+ width, height);
+ if (cairo_surface_status (surface)) {
+ xcb_disconnect (c);
+ free (xtc);
+ return surface;
+ }
+
+ cairo_xcb_device_debug_cap_xrender_version (cairo_surface_get_device (surface),
+ -1, -1);
+
+ xtc->device = cairo_device_reference (cairo_surface_get_device (surface));
+ status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL);
+ if (status == CAIRO_STATUS_SUCCESS)
+ return surface;
+
+ cairo_surface_destroy (surface);
+
+ _cairo_boilerplate_xcb_cleanup (xtc);
+ return cairo_boilerplate_surface_create_in_error (status);
+}
+
+static cairo_status_t
+_cairo_boilerplate_xcb_finish_surface (cairo_surface_t *surface)
+{
+ xcb_target_closure_t *xtc = cairo_surface_get_user_data (surface,
+ &xcb_closure_key);
+ cairo_status_t status;
+
+ if (xtc->surface != NULL) {
+ cairo_t *cr;
+
+ cr = cairo_create (xtc->surface);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ surface = xtc->surface;
+ }
+
+ cairo_surface_flush (surface);
+ if (cairo_surface_status (surface))
+ return cairo_surface_status (surface);
+
+ /* First synchronize with the X server to make sure there are no more errors
+ * in-flight which we would miss otherwise */
+ _cairo_boilerplate_xcb_sync_server (xtc);
+ status = _cairo_boilerplate_xcb_handle_errors (xtc);
+ if (status)
+ return status;
+
+ if (xcb_connection_has_error (xtc->c))
+ return CAIRO_STATUS_WRITE_ERROR;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static const cairo_boilerplate_target_t targets[] = {
+ /* Acceleration architectures may make the results differ by a
+ * bit, so we set the error tolerance to 1. */
+ {
+ "xcb", "traps", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_xcb_surface_create_with_xrender_format",
+ _cairo_boilerplate_xcb_create_surface,
+ _cairo_boilerplate_xcb_create_similar,
+ NULL,
+ _cairo_boilerplate_xcb_finish_surface,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xcb_cleanup,
+ _cairo_boilerplate_xcb_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ },
+ {
+ "xcb", "traps", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
+ "cairo_xcb_surface_create_with_xrender_format",
+ _cairo_boilerplate_xcb_create_surface,
+ _cairo_boilerplate_xcb_create_similar,
+ NULL,
+ _cairo_boilerplate_xcb_finish_surface,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xcb_cleanup,
+ _cairo_boilerplate_xcb_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "xcb-window", "traps", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
+ "cairo_xcb_surface_create_with_xrender_format",
+ _cairo_boilerplate_xcb_create_window,
+ _cairo_boilerplate_xcb_create_similar,
+ NULL,
+ _cairo_boilerplate_xcb_finish_surface,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xcb_cleanup,
+ _cairo_boilerplate_xcb_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "xcb-window&", "traps", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
+ "cairo_xcb_surface_create_with_xrender_format",
+ _cairo_boilerplate_xcb_create_window_db,
+ _cairo_boilerplate_xcb_create_similar,
+ NULL,
+ _cairo_boilerplate_xcb_finish_surface,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xcb_cleanup,
+ _cairo_boilerplate_xcb_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "xcb-render-0.0", "xlib-fallback", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_xcb_surface_create_with_xrender_format",
+ _cairo_boilerplate_xcb_create_render_0_0,
+ cairo_surface_create_similar,
+ NULL,
+ _cairo_boilerplate_xcb_finish_surface,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xcb_cleanup,
+ _cairo_boilerplate_xcb_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "xcb-render-0.0", "xlib-fallback", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
+ "cairo_xcb_surface_create_with_xrender_format",
+ _cairo_boilerplate_xcb_create_render_0_0,
+ cairo_surface_create_similar,
+ NULL,
+ _cairo_boilerplate_xcb_finish_surface,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xcb_cleanup,
+ _cairo_boilerplate_xcb_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "xcb-fallback", "xlib-fallback", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1,
+ "cairo_xcb_surface_create_with_xrender_format",
+ _cairo_boilerplate_xcb_create_fallback,
+ cairo_surface_create_similar,
+ NULL,
+ _cairo_boilerplate_xcb_finish_surface,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xcb_cleanup,
+ _cairo_boilerplate_xcb_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+};
+CAIRO_BOILERPLATE (xcb, targets)
diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c
new file mode 100755
index 000000000..aed075f67
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-xlib.c
@@ -0,0 +1,632 @@
+/* -*- 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 <cworth@cworth.org>
+ */
+
+#include "cairo-boilerplate-private.h"
+#include "cairo-boilerplate-xlib.h"
+
+#include <cairo-xlib.h>
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
+#include <cairo-xlib-xrender.h>
+#endif
+
+#include <X11/Xutil.h> /* for XDestroyImage */
+
+#if !CAIRO_HAS_XLIB_XRENDER_SURFACE
+#define PolyModePrecise 0
+#endif
+
+static const cairo_user_data_key_t key;
+
+typedef struct _xlib_target_closure {
+ Display *dpy;
+ Drawable drawable;
+ cairo_bool_t drawable_is_pixmap;
+} xlib_target_closure_t;
+
+static void
+_cairo_boilerplate_xlib_cleanup (void *closure)
+{
+ xlib_target_closure_t *xtc = closure;
+
+ if (xtc->drawable) {
+ if (xtc->drawable_is_pixmap)
+ XFreePixmap (xtc->dpy, xtc->drawable);
+ else
+ XDestroyWindow (xtc->dpy, xtc->drawable);
+ }
+ XCloseDisplay (xtc->dpy);
+ free (xtc);
+}
+
+static void
+_cairo_boilerplate_xlib_synchronize (void *closure)
+{
+ xlib_target_closure_t *xtc = closure;
+ XImage *ximage;
+
+ ximage = XGetImage (xtc->dpy, xtc->drawable,
+ 0, 0, 1, 1, AllPlanes, ZPixmap);
+ if (ximage != NULL)
+ XDestroyImage (ximage);
+}
+
+static cairo_bool_t
+_cairo_boilerplate_xlib_check_screen_size (Display *dpy,
+ int screen,
+ int width,
+ int height)
+{
+ Screen *scr = XScreenOfDisplay (dpy, screen);
+ return width <= WidthOfScreen (scr) && height <= HeightOfScreen (scr);
+}
+
+static void
+_cairo_boilerplate_xlib_setup_test_surface (cairo_surface_t *surface)
+{
+
+ /* For testing purposes, tell the X server to strictly adhere to the
+ * Render specification.
+ */
+ cairo_xlib_device_debug_set_precision(cairo_surface_get_device(surface),
+ PolyModePrecise);
+}
+
+
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
+/* For the xlib backend we distinguish between TEST and PERF mode in a
+ * couple of ways.
+ *
+ * For TEST, we always test against pixmaps of depth 32 (for
+ * COLOR_ALPHA) or 24 (for COLOR) and we use XSynchronize to make it
+ * easier to debug problems.
+ *
+ * For PERF, we test against 32-bit pixmaps for COLOR_ALPHA, but for
+ * COLOR we test against _windows_ at the depth of the default visual.
+ * For obvious reasons, we don't use XSynchronize.
+ */
+static cairo_surface_t *
+_cairo_boilerplate_xlib_test_create_surface (Display *dpy,
+ cairo_content_t content,
+ int width,
+ int height,
+ xlib_target_closure_t *xtc)
+{
+ XRenderPictFormat *xrender_format;
+ cairo_surface_t *surface;
+
+ /* This kills performance, but it makes debugging much
+ * easier. That's why we have it here when in TEST mode, but not
+ * over in PERF mode. */
+ XSynchronize (xtc->dpy, 1);
+
+ /* XXX: Currently we don't do any xlib testing when the X server
+ * doesn't have the Render extension. We could do better here,
+ * (perhaps by converting the tests from ARGB32 to RGB24). One
+ * step better would be to always test the non-Render fallbacks
+ * for each test even if the server does have the Render
+ * extension. That would probably be through another
+ * cairo_boilerplate_target which would use an extended version of
+ * cairo_test_xlib_disable_render. */
+ switch (content) {
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ xrender_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
+ break;
+ case CAIRO_CONTENT_COLOR:
+ xrender_format = XRenderFindStandardFormat (dpy, PictStandardRGB24);
+ break;
+ case CAIRO_CONTENT_ALPHA:
+ default:
+ CAIRO_BOILERPLATE_DEBUG (("Invalid content for xlib test: %d\n", content));
+ return NULL;
+ }
+ if (xrender_format == NULL) {
+ CAIRO_BOILERPLATE_DEBUG (("X server does not have the Render extension.\n"));
+ return NULL;
+ }
+
+ xtc->drawable = XCreatePixmap (dpy, DefaultRootWindow (dpy),
+ width, height, xrender_format->depth);
+ xtc->drawable_is_pixmap = TRUE;
+
+ surface = cairo_xlib_surface_create_with_xrender_format (dpy, xtc->drawable,
+ DefaultScreenOfDisplay (dpy),
+ xrender_format,
+ width, height);
+
+ _cairo_boilerplate_xlib_setup_test_surface(surface);
+
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xlib_perf_create_surface (Display *dpy,
+ cairo_content_t content,
+ int width,
+ int height,
+ xlib_target_closure_t *xtc)
+{
+ XSetWindowAttributes attr;
+ XRenderPictFormat *xrender_format;
+ Visual *visual;
+
+ switch (content) {
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ xrender_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
+ if (xrender_format == NULL) {
+ CAIRO_BOILERPLATE_DEBUG (("X server does not have the Render extension.\n"));
+ return NULL;
+ }
+
+ xtc->drawable = XCreatePixmap (dpy, DefaultRootWindow (dpy),
+ width, height, xrender_format->depth);
+ xtc->drawable_is_pixmap = TRUE;
+ break;
+
+ case CAIRO_CONTENT_COLOR:
+ if (! _cairo_boilerplate_xlib_check_screen_size (dpy,
+ DefaultScreen (dpy),
+ width, height)) {
+ CAIRO_BOILERPLATE_DEBUG (("Surface is larger than the Screen.\n"));
+ return NULL;
+ }
+
+ visual = DefaultVisual (dpy, DefaultScreen (dpy));
+ xrender_format = XRenderFindVisualFormat (dpy, visual);
+ if (xrender_format == NULL) {
+ CAIRO_BOILERPLATE_DEBUG (("X server does not have the Render extension.\n"));
+ return NULL;
+ }
+
+ attr.override_redirect = True;
+ xtc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0,
+ width, height, 0, xrender_format->depth,
+ InputOutput, visual, CWOverrideRedirect, &attr);
+ XMapWindow (dpy, xtc->drawable);
+ xtc->drawable_is_pixmap = FALSE;
+ break;
+
+ case CAIRO_CONTENT_ALPHA:
+ default:
+ CAIRO_BOILERPLATE_DEBUG (("Invalid content for xlib test: %d\n", content));
+ return NULL;
+ }
+
+ return cairo_xlib_surface_create_with_xrender_format (dpy, xtc->drawable,
+ DefaultScreenOfDisplay (dpy),
+ xrender_format,
+ width, height);
+}
+
+struct similar {
+ Display *dpy;
+ Pixmap pixmap;
+};
+
+static void _destroy_similar (void *closure)
+{
+ struct similar *similar = closure;
+
+ XFreePixmap (similar->dpy, similar->pixmap);
+ free (similar);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xlib_create_similar (cairo_surface_t *other,
+ cairo_content_t content,
+ int width,
+ int height)
+{
+ XRenderPictFormat *xrender_format;
+ uint32_t format;
+ struct similar *similar;
+ cairo_surface_t *surface;
+
+ similar = malloc (sizeof (*similar));
+ similar->dpy = cairo_xlib_surface_get_display (other);
+
+ switch (content) {
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA: format = PictStandardARGB32; break;
+ case CAIRO_CONTENT_COLOR: format = PictStandardRGB24; break;
+ case CAIRO_CONTENT_ALPHA: format = PictStandardA8; break;
+ }
+
+ xrender_format = XRenderFindStandardFormat (similar->dpy, format);
+ similar->pixmap = XCreatePixmap (similar->dpy,
+ DefaultRootWindow (similar->dpy),
+ width, height,
+ xrender_format->depth);
+
+ surface =
+ cairo_xlib_surface_create_with_xrender_format (similar->dpy,
+ similar->pixmap,
+ DefaultScreenOfDisplay (similar->dpy),
+ xrender_format,
+ width, height);
+
+ cairo_surface_set_user_data (surface, &key, similar, _destroy_similar);
+
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xlib_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ xlib_target_closure_t *xtc;
+ Display *dpy;
+ cairo_surface_t *surface;
+
+ *closure = xtc = xcalloc (1, sizeof (xlib_target_closure_t));
+
+ width = ceil (width);
+ if (width < 1)
+ width = 1;
+
+ height = ceil (height);
+ if (height < 1)
+ height = 1;
+
+ xtc->dpy = dpy = XOpenDisplay (NULL);
+ if (xtc->dpy == NULL) {
+ free (xtc);
+ CAIRO_BOILERPLATE_DEBUG (("Failed to open display: %s\n", XDisplayName(0)));
+ return NULL;
+ }
+
+ if (mode == CAIRO_BOILERPLATE_MODE_TEST)
+ surface = _cairo_boilerplate_xlib_test_create_surface (dpy, content, width, height, xtc);
+ else /* mode == CAIRO_BOILERPLATE_MODE_PERF */
+ surface = _cairo_boilerplate_xlib_perf_create_surface (dpy, content, width, height, xtc);
+
+ if (surface == NULL || cairo_surface_status (surface))
+ _cairo_boilerplate_xlib_cleanup (xtc);
+
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xlib_render_0_0_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ xlib_target_closure_t *xtc;
+ Display *dpy;
+ int screen;
+ Pixmap pixmap;
+ cairo_surface_t *surface, *dummy;
+
+ *closure = xtc = xcalloc (1, sizeof (xlib_target_closure_t));
+
+ width = ceil (width);
+ if (width < 1)
+ width = 1;
+
+ height = ceil (height);
+ if (height < 1)
+ height = 1;
+
+ xtc->dpy = dpy = XOpenDisplay (NULL);
+ if (xtc->dpy == NULL) {
+ free (xtc);
+ CAIRO_BOILERPLATE_DEBUG (("Failed to open display: %s\n", XDisplayName(0)));
+ return NULL;
+ }
+
+
+ screen = DefaultScreen (dpy);
+ pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy), 1, 1,
+ DefaultDepth (dpy, screen));
+ dummy = cairo_xlib_surface_create (dpy, pixmap,
+ DefaultVisual (dpy, screen),
+ 1, 1);
+ cairo_xlib_device_debug_cap_xrender_version (cairo_surface_get_device (dummy),
+ 0, 0);
+
+ if (mode == CAIRO_BOILERPLATE_MODE_TEST)
+ surface = _cairo_boilerplate_xlib_test_create_surface (dpy, content, width, height, xtc);
+ else /* mode == CAIRO_BOILERPLATE_MODE_PERF */
+ surface = _cairo_boilerplate_xlib_perf_create_surface (dpy, content, width, height, xtc);
+
+ cairo_surface_destroy (dummy);
+ XFreePixmap (dpy, pixmap);
+
+ if (surface == NULL || cairo_surface_status (surface))
+ _cairo_boilerplate_xlib_cleanup (xtc);
+
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_xlib_window_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ xlib_target_closure_t *xtc;
+ Display *dpy;
+ int screen;
+ XSetWindowAttributes attr;
+ cairo_surface_t *surface;
+
+ /* We're not yet bothering to support perf mode for the
+ * xlib-fallback surface. */
+ if (mode == CAIRO_BOILERPLATE_MODE_PERF)
+ return NULL;
+
+ /* We also don't support drawing with destination-alpha in the
+ * xlib-fallback surface. */
+ if (content == CAIRO_CONTENT_COLOR_ALPHA)
+ return NULL;
+
+ *closure = xtc = xmalloc (sizeof (xlib_target_closure_t));
+
+ width = ceil (width);
+ if (width < 1)
+ width = 1;
+
+ height = ceil (height);
+ if (height < 1)
+ height = 1;
+
+ xtc->dpy = dpy = XOpenDisplay (NULL);
+ if (xtc->dpy == NULL) {
+ CAIRO_BOILERPLATE_DEBUG (("Failed to open display: %s\n", XDisplayName(0)));
+ free (xtc);
+ return NULL;
+ }
+
+ /* This kills performance, but it makes debugging much
+ * easier. That's why we have it here only after explicitly not
+ * supporting PERF mode.*/
+ XSynchronize (dpy, 1);
+
+ screen = DefaultScreen (dpy);
+ if (! _cairo_boilerplate_xlib_check_screen_size (dpy, screen,
+ width, height)) {
+ CAIRO_BOILERPLATE_DEBUG (("Surface is larger than the Screen.\n"));
+ XCloseDisplay (dpy);
+ free (xtc);
+ return NULL;
+ }
+
+ attr.override_redirect = True;
+ xtc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy),
+ 0, 0,
+ width, height, 0,
+ DefaultDepth (dpy, screen),
+ InputOutput,
+ DefaultVisual (dpy, screen),
+ CWOverrideRedirect, &attr);
+ XMapWindow (dpy, xtc->drawable);
+ xtc->drawable_is_pixmap = FALSE;
+
+ surface = cairo_xlib_surface_create (dpy, xtc->drawable,
+ DefaultVisual (dpy, screen),
+ width, height);
+ if (cairo_surface_status (surface))
+ _cairo_boilerplate_xlib_cleanup (xtc);
+
+ _cairo_boilerplate_xlib_setup_test_surface(surface);
+
+ return surface;
+}
+#endif
+
+
+#if CAIRO_HAS_XLIB_SURFACE
+/* The xlib-fallback target differs from the xlib target in two ways:
+ *
+ * 1. It creates its surfaces without relying on the Render extension
+ *
+ * 2. It disables use of the Render extension for its surfaces
+ *
+ * This provides testing of the non-Render fallback paths we have in
+ * cairo-xlib-surface.c
+ */
+static cairo_surface_t *
+_cairo_boilerplate_xlib_fallback_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ xlib_target_closure_t *xtc;
+ Display *dpy;
+ int screen;
+ XSetWindowAttributes attr;
+ cairo_surface_t *surface, *dummy;
+
+ /* We're not yet bothering to support perf mode for the
+ * xlib-fallback surface. */
+ if (mode == CAIRO_BOILERPLATE_MODE_PERF)
+ return NULL;
+
+ /* We also don't support drawing with destination-alpha in the
+ * xlib-fallback surface. */
+ if (content == CAIRO_CONTENT_COLOR_ALPHA)
+ return NULL;
+
+ *closure = xtc = xmalloc (sizeof (xlib_target_closure_t));
+
+ width = ceil (width);
+ if (width < 1)
+ width = 1;
+
+ height = ceil (height);
+ if (height < 1)
+ height = 1;
+
+ xtc->dpy = dpy = XOpenDisplay (NULL);
+ if (xtc->dpy == NULL) {
+ CAIRO_BOILERPLATE_DEBUG (("Failed to open display: %s\n", XDisplayName(0)));
+ free (xtc);
+ return NULL;
+ }
+
+ /* This kills performance, but it makes debugging much
+ * easier. That's why we have it here only after explicitly not
+ * supporting PERF mode.*/
+ XSynchronize (dpy, 1);
+
+ screen = DefaultScreen (dpy);
+ if (! _cairo_boilerplate_xlib_check_screen_size (dpy, screen,
+ width, height)) {
+ CAIRO_BOILERPLATE_DEBUG (("Surface is larger than the Screen.\n"));
+ XCloseDisplay (dpy);
+ free (xtc);
+ return NULL;
+ }
+
+ attr.override_redirect = True;
+ xtc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy),
+ 0, 0,
+ width, height, 0,
+ DefaultDepth (dpy, screen),
+ InputOutput,
+ DefaultVisual (dpy, screen),
+ CWOverrideRedirect, &attr);
+ XMapWindow (dpy, xtc->drawable);
+ xtc->drawable_is_pixmap = FALSE;
+
+ dummy = cairo_xlib_surface_create (dpy, xtc->drawable,
+ DefaultVisual (dpy, screen),
+ width, height);
+ cairo_xlib_device_debug_cap_xrender_version (cairo_surface_get_device (dummy),
+ -1, -1);
+
+ surface = cairo_xlib_surface_create (dpy, xtc->drawable,
+ DefaultVisual (dpy, screen),
+ width, height);
+ cairo_surface_destroy (dummy);
+ if (cairo_surface_status (surface))
+ _cairo_boilerplate_xlib_cleanup (xtc);
+
+ _cairo_boilerplate_xlib_setup_test_surface(surface);
+
+ return surface;
+}
+#endif
+
+static const cairo_boilerplate_target_t targets[] = {
+#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", "traps", NULL, "xlib-fallback",
+ CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1,
+ "cairo_xlib_surface_create_with_xrender_format",
+ _cairo_boilerplate_xlib_create_surface,
+ _cairo_boilerplate_xlib_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xlib_cleanup,
+ _cairo_boilerplate_xlib_synchronize,
+ NULL,
+ TRUE, FALSE, FALSE
+ },
+ {
+ "xlib", "traps", NULL, "xlib-fallback",
+ CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
+ "cairo_xlib_surface_create_with_xrender_format",
+ _cairo_boilerplate_xlib_create_surface,
+ _cairo_boilerplate_xlib_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xlib_cleanup,
+ _cairo_boilerplate_xlib_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "xlib-window", "traps", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
+ "cairo_xlib_surface_create",
+ _cairo_boilerplate_xlib_window_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xlib_cleanup,
+ _cairo_boilerplate_xlib_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "xlib-render-0_0", "mask", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
+ "cairo_xlib_surface_create",
+ _cairo_boilerplate_xlib_render_0_0_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xlib_cleanup,
+ _cairo_boilerplate_xlib_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+#endif
+#if CAIRO_HAS_XLIB_SURFACE
+ /* This is a fallback surface which uses xlib fallbacks instead of
+ * the Render extension. */
+ {
+ "xlib-fallback", "image", NULL, NULL,
+ CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1,
+ "cairo_xlib_surface_create",
+ _cairo_boilerplate_xlib_fallback_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_xlib_cleanup,
+ _cairo_boilerplate_xlib_synchronize,
+ NULL,
+ FALSE, FALSE, FALSE
+ },
+#endif
+};
+CAIRO_BOILERPLATE (xlib, targets)
diff --git a/boilerplate/cairo-boilerplate-xlib.h b/boilerplate/cairo-boilerplate-xlib.h
new file mode 100755
index 000000000..9a6391812
--- /dev/null
+++ b/boilerplate/cairo-boilerplate-xlib.h
@@ -0,0 +1,33 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/*
+ * Copyright © 2007 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: Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#ifndef _CAIRO_BOILERPLATE_XLIB_H_
+#define _CAIRO_BOILERPLATE_XLIB_H_
+
+cairo_status_t
+cairo_boilerplate_xlib_surface_disable_render (cairo_surface_t *surface);
+
+#endif
diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
new file mode 100755
index 000000000..41db8b887
--- /dev/null
+++ b/boilerplate/cairo-boilerplate.c
@@ -0,0 +1,989 @@
+/* -*- 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 <cworth@cworth.org>
+ */
+
+#define CAIRO_VERSION_H 1
+
+#include "cairo-boilerplate-private.h"
+#include "cairo-boilerplate-scaled-font.h"
+
+#include <pixman.h>
+
+#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"
+
+#include <stdlib.h>
+#include <ctype.h>
+#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>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#define HAS_DAEMON 1
+#define SOCKET_PATH "./.any2ppm"
+#endif
+
+cairo_content_t
+cairo_boilerplate_content (cairo_content_t content)
+{
+ if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
+ content = CAIRO_CONTENT_COLOR_ALPHA;
+
+ return content;
+}
+
+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.
+ */
+ switch (cairo_boilerplate_content (content)) {
+ case CAIRO_CONTENT_COLOR:
+ return "rgb24";
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ return "argb32";
+ case CAIRO_CONTENT_ALPHA:
+ default:
+ assert (0); /* not reached */
+ return "---";
+ }
+}
+
+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)
+{
+ 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_INVALID;
+ break;
+ }
+
+ return format;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_image_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_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, ceil (width), ceil (height));
+}
+
+static const cairo_user_data_key_t key;
+
+static cairo_surface_t *
+_cairo_boilerplate_image_create_similar (cairo_surface_t *other,
+ cairo_content_t content,
+ int width, int height)
+{
+ cairo_format_t format;
+ cairo_surface_t *surface;
+ int stride;
+ void *ptr;
+
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
+ case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break;
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+ }
+
+ stride = cairo_format_stride_for_width(format, width);
+ ptr = malloc (stride* height);
+
+ surface = cairo_image_surface_create_for_data (ptr, format,
+ width, height, stride);
+ cairo_surface_set_user_data (surface, &key, ptr, free);
+
+ return surface;
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_image16_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ *closure = NULL;
+
+ /* XXX force CAIRO_CONTENT_COLOR */
+ return cairo_image_surface_create (CAIRO_FORMAT_RGB16_565, ceil (width), ceil (height));
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_image16_create_similar (cairo_surface_t *other,
+ cairo_content_t content,
+ int width, int height)
+{
+ cairo_format_t format;
+ cairo_surface_t *surface;
+ int stride;
+ void *ptr;
+
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break;
+ case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB16_565; break;
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break;
+ }
+
+ stride = cairo_format_stride_for_width(format, width);
+ ptr = malloc (stride* height);
+
+ surface = cairo_image_surface_create_for_data (ptr, format,
+ width, height, stride);
+ cairo_surface_set_user_data (surface, &key, ptr, free);
+
+ return surface;
+}
+
+static char *
+_cairo_boilerplate_image_describe (void *closure)
+{
+ char *s;
+
+ xasprintf (&s, "pixman %s", pixman_version_string ());
+
+ return s;
+}
+
+#if CAIRO_HAS_RECORDING_SURFACE
+static cairo_surface_t *
+_cairo_boilerplate_recording_create_surface (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure)
+{
+ cairo_rectangle_t extents;
+
+ extents.x = 0;
+ extents.y = 0;
+ extents.width = width;
+ extents.height = height;
+ return *closure = cairo_surface_reference (cairo_recording_surface_create (content, &extents));
+}
+
+static void
+_cairo_boilerplate_recording_surface_cleanup (void *closure)
+{
+ cairo_surface_finish (closure);
+ cairo_surface_destroy (closure);
+}
+#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, *image;
+ cairo_t *cr;
+ cairo_status_t status;
+ cairo_format_t format;
+
+ if (cairo_surface_status (src))
+ return cairo_surface_reference (src);
+
+ if (page != 0)
+ return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+
+ /* extract sub-surface */
+ switch (cairo_surface_get_content (src)) {
+ case CAIRO_CONTENT_ALPHA:
+ format = CAIRO_FORMAT_A8;
+ break;
+ case CAIRO_CONTENT_COLOR:
+ format = CAIRO_FORMAT_RGB24;
+ break;
+ default:
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ format = CAIRO_FORMAT_ARGB32;
+ break;
+ }
+ surface = cairo_image_surface_create (format, width, height);
+ assert (cairo_surface_get_content (surface) == cairo_surface_get_content (src));
+ image = cairo_surface_reference (surface);
+
+ /* open a logging channel (only interesting for recording surfaces) */
+#if CAIRO_HAS_SCRIPT_SURFACE && CAIRO_HAS_RECORDING_SURFACE
+ if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_RECORDING) {
+ const char *test_name;
+
+ test_name = cairo_surface_get_user_data (src,
+ &cairo_boilerplate_output_basename_key);
+ if (test_name != NULL) {
+ cairo_device_t *ctx;
+ char *filename;
+
+ cairo_surface_destroy (surface);
+
+ xasprintf (&filename, "%s.out.trace", test_name);
+ ctx = cairo_script_create (filename);
+ surface = cairo_script_surface_create_for_target (ctx, image);
+ cairo_device_destroy (ctx);
+ free (filename);
+ }
+ }
+#endif
+
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+ cairo_set_source_surface (cr, src, 0, 0);
+ cairo_paint (cr);
+
+ status = cairo_status (cr);
+ if (status) {
+ cairo_surface_destroy (image);
+ image = cairo_surface_reference (cairo_get_target (cr));
+ }
+ cairo_destroy (cr);
+
+ return image;
+}
+
+cairo_surface_t *
+cairo_boilerplate_get_image_surface_from_png (const char *filename,
+ int width,
+ int height,
+ cairo_bool_t flatten)
+{
+ cairo_surface_t *surface;
+
+ surface = cairo_image_surface_create_from_png (filename);
+ if (cairo_surface_status (surface))
+ return surface;
+
+ if (flatten) {
+ cairo_t *cr;
+ cairo_surface_t *flattened;
+
+ flattened = cairo_image_surface_create (cairo_image_surface_get_format (surface),
+ width,
+ height);
+ cr = cairo_create (flattened);
+ cairo_surface_destroy (flattened);
+
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_paint (cr);
+
+ cairo_set_source_surface (cr, surface,
+ width - cairo_image_surface_get_width (surface),
+ height - cairo_image_surface_get_height (surface));
+ cairo_paint (cr);
+
+ cairo_surface_destroy (surface);
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+ } else if (cairo_image_surface_get_width (surface) != width ||
+ cairo_image_surface_get_height (surface) != height)
+ {
+ cairo_t *cr;
+ cairo_surface_t *sub;
+
+ sub = cairo_image_surface_create (cairo_image_surface_get_format (surface),
+ width,
+ height);
+ cr = cairo_create (sub);
+ cairo_surface_destroy (sub);
+
+ cairo_set_source_surface (cr, surface,
+ width - cairo_image_surface_get_width (surface),
+ height - cairo_image_surface_get_height (surface));
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (surface);
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+ }
+
+ return surface;
+}
+
+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, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA, 0,
+ NULL,
+ _cairo_boilerplate_image_create_surface,
+ _cairo_boilerplate_image_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL,
+ _cairo_boilerplate_image_describe,
+ TRUE, FALSE, FALSE
+ },
+ {
+ "image", "image", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
+ NULL,
+ _cairo_boilerplate_image_create_surface,
+ _cairo_boilerplate_image_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL,
+ _cairo_boilerplate_image_describe,
+ FALSE, FALSE, FALSE
+ },
+ {
+ "image16", "image", NULL, NULL,
+ CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0,
+ NULL,
+ _cairo_boilerplate_image16_create_surface,
+ _cairo_boilerplate_image16_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ NULL, NULL,
+ _cairo_boilerplate_image_describe,
+ TRUE, FALSE, FALSE
+ },
+#if CAIRO_HAS_RECORDING_SURFACE
+ {
+ "recording", "image", NULL, NULL,
+ CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR_ALPHA, 0,
+ "cairo_recording_surface_create",
+ _cairo_boilerplate_recording_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_recording_surface_cleanup,
+ NULL, NULL,
+ FALSE, FALSE, TRUE
+ },
+ {
+ "recording", "image", NULL, NULL,
+ CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR, 0,
+ "cairo_recording_surface_create",
+ _cairo_boilerplate_recording_create_surface,
+ cairo_surface_create_similar,
+ NULL, NULL,
+ _cairo_boilerplate_get_image_surface,
+ cairo_surface_write_to_png,
+ _cairo_boilerplate_recording_surface_cleanup,
+ NULL, NULL,
+ FALSE, FALSE, TRUE
+ },
+#endif
+};
+CAIRO_BOILERPLATE (builtin, builtin_targets)
+
+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;
+
+ /* 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;
+ 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 */
+ 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 (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++] = 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 (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", target->name);
+ last_name = target->name;
+ }
+ fprintf (stderr, "\n");
+ exit(-1);
+ }
+
+ if (*end)
+ end++;
+ tname = end;
+ }
+ } else {
+ /* check all compiled in targets */
+ 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);
+ 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;
+ }
+ }
+
+ /* exclude targets as specified by the user */
+ if ((tname = getenv ("CAIRO_TEST_TARGET_EXCLUDE")) != NULL && *tname) {
+ limited_targets = TRUE;
+
+ while (*tname) {
+ int j;
+ 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++) {
+ 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];
+ }
+ }
+ 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;
+}
+
+const cairo_boilerplate_target_t *
+cairo_boilerplate_get_image_target (cairo_content_t content)
+{
+ if (cairo_boilerplate_targets == NULL)
+ _cairo_boilerplate_register_all ();
+
+ switch (content) {
+ default:
+ case CAIRO_CONTENT_ALPHA: return NULL;
+ case CAIRO_CONTENT_COLOR: return &builtin_targets[1];
+ case CAIRO_CONTENT_COLOR_ALPHA: return &builtin_targets[0];
+ }
+}
+
+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 (const cairo_boilerplate_target_t **targets)
+{
+ free (targets);
+}
+
+cairo_surface_t *
+cairo_boilerplate_surface_create_in_error (cairo_status_t status)
+{
+ cairo_surface_t *surface = NULL;
+ int loop = 5;
+
+ do {
+ cairo_surface_t *intermediate;
+ cairo_t *cr;
+ cairo_path_t path;
+
+ intermediate = cairo_image_surface_create (CAIRO_FORMAT_A8, 0, 0);
+ cr = cairo_create (intermediate);
+ cairo_surface_destroy (intermediate);
+
+ path.status = status;
+ cairo_append_path (cr, &path);
+
+ cairo_surface_destroy (surface);
+ surface = cairo_surface_reference (cairo_get_target (cr));
+ cairo_destroy (cr);
+ } while (cairo_surface_status (surface) != status && --loop);
+
+ return surface;
+}
+
+void
+cairo_boilerplate_scaled_font_set_max_glyphs_cached (cairo_scaled_font_t *scaled_font,
+ int max_glyphs)
+{
+ /* XXX CAIRO_DEBUG */
+}
+
+#if HAS_DAEMON
+static int
+any2ppm_daemon_exists (void)
+{
+ struct stat st;
+ int fd;
+ char buf[80];
+ int pid;
+ int ret;
+
+ if (stat (SOCKET_PATH, &st) < 0)
+ return 0;
+
+ fd = open (SOCKET_PATH ".pid", O_RDONLY);
+ if (fd < 0)
+ return 0;
+
+ pid = 0;
+ ret = read (fd, buf, sizeof (buf) - 1);
+ if (ret > 0) {
+ buf[ret] = '\0';
+ pid = atoi (buf);
+ }
+ close (fd);
+
+ return pid > 0 && kill (pid, 0) != -1;
+}
+#endif
+
+FILE *
+cairo_boilerplate_open_any2ppm (const char *filename,
+ int page,
+ unsigned int flags,
+ int (**close_cb) (FILE *))
+{
+ char command[4096];
+ const char *any2ppm;
+#if HAS_DAEMON
+ int sk;
+ struct sockaddr_un addr;
+ int len;
+#endif
+
+ any2ppm = getenv ("ANY2PPM");
+ if (any2ppm == NULL)
+ any2ppm = "./any2ppm";
+
+#if HAS_DAEMON
+ if (flags & CAIRO_BOILERPLATE_OPEN_NO_DAEMON)
+ goto POPEN;
+
+ if (! any2ppm_daemon_exists ()) {
+ if (system (any2ppm) != 0)
+ goto POPEN;
+ }
+
+ sk = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (sk == -1)
+ goto POPEN;
+
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ strcpy (addr.sun_path, SOCKET_PATH);
+
+ if (connect (sk, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
+ close (sk);
+ goto POPEN;
+ }
+
+ len = sprintf (command, "%s %d\n", filename, page);
+ if (write (sk, command, len) != len) {
+ close (sk);
+ goto POPEN;
+ }
+
+ *close_cb = fclose;
+ return fdopen (sk, "r");
+
+POPEN:
+#endif
+
+ *close_cb = pclose;
+ sprintf (command, "%s %s %d", any2ppm, filename, page);
+ return popen (command, "r");
+}
+
+static cairo_bool_t
+freadn (unsigned char *buf,
+ int len,
+ FILE *file)
+{
+ int ret;
+
+ while (len) {
+ ret = fread (buf, 1, len, file);
+ if (ret != len) {
+ if (ferror (file) || feof (file))
+ return FALSE;
+ }
+ len -= ret;
+ buf += len;
+ }
+
+ return TRUE;
+}
+
+cairo_surface_t *
+cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file)
+{
+ char format;
+ int width, height, stride;
+ int x, y;
+ unsigned char *data;
+ cairo_surface_t *image = NULL;
+
+ if (fscanf (file, "P%c %d %d 255\n", &format, &width, &height) != 3)
+ goto FAIL;
+
+ switch (format) {
+ case '7': /* XXX */
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ break;
+ case '6':
+ image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+ break;
+ case '5':
+ image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
+ break;
+ default:
+ goto FAIL;
+ }
+ if (cairo_surface_status (image))
+ return image;
+
+ 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;
+ switch (format) {
+ case '7':
+ if (! freadn (buf, 4 * width, file))
+ goto FAIL;
+ break;
+ case '6':
+ 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);
+ }
+ break;
+ case '5':
+ if (! freadn (buf, width, file))
+ goto FAIL;
+ break;
+ }
+ }
+ cairo_surface_mark_dirty (image);
+
+ return image;
+
+FAIL:
+ cairo_surface_destroy (image);
+ return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
+}
+
+cairo_surface_t *
+cairo_boilerplate_convert_to_image (const char *filename,
+ int page)
+{
+ FILE *file;
+ unsigned int flags = 0;
+ cairo_surface_t *image;
+ int (*close_cb) (FILE *);
+ int ret;
+
+ RETRY:
+ file = cairo_boilerplate_open_any2ppm (filename, page, flags, &close_cb);
+ if (file == NULL) {
+ switch (errno) {
+ case ENOMEM:
+ return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
+ default:
+ return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
+ }
+ }
+
+ image = cairo_boilerplate_image_surface_create_from_ppm_stream (file);
+ ret = close_cb (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 (ret == 0 && cairo_surface_status (image) == CAIRO_STATUS_READ_ERROR) {
+ if (flags == 0) {
+ /* Try again in a standalone process. */
+ cairo_surface_destroy (image);
+ flags = CAIRO_BOILERPLATE_OPEN_NO_DAEMON;
+ goto RETRY;
+ }
+ }
+
+ return image;
+}
+
+int
+cairo_boilerplate_version (void)
+{
+ return CAIRO_VERSION;
+}
+
+const char*
+cairo_boilerplate_version_string (void)
+{
+ return CAIRO_VERSION_STRING;
+}
+
+void
+cairo_boilerplate_fini (void)
+{
+ while (cairo_boilerplate_targets != NULL) {
+ struct cairo_boilerplate_target_list *next;
+
+ next = cairo_boilerplate_targets->next;
+
+ free (cairo_boilerplate_targets);
+ cairo_boilerplate_targets = next;
+ }
+}
diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h
new file mode 100755
index 000000000..461b98b69
--- /dev/null
+++ b/boilerplate/cairo-boilerplate.h
@@ -0,0 +1,243 @@
+/*
+ * 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 <cworth@cworth.org>
+ */
+
+#ifndef _CAIRO_BOILERPLATE_H_
+#define _CAIRO_BOILERPLATE_H_
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <cairo.h>
+#include <string.h>
+
+#include "cairo-compiler-private.h"
+
+#if HAVE_STDINT_H
+# include <stdint.h>
+#elif HAVE_INTTYPES_H
+# include <inttypes.h>
+#elif HAVE_SYS_INT_TYPES_H
+# include <sys/int_types.h>
+#elif defined(_MSC_VER)
+# include <stdint.h>
+ typedef __int8 int8_t;
+ typedef unsigned __int8 uint8_t;
+ typedef __int16 int16_t;
+ typedef unsigned __int16 uint16_t;
+ typedef __int32 int32_t;
+ typedef unsigned __int32 uint32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+#else
+#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
+#endif
+
+#ifndef HAVE_UINT64_T
+# define HAVE_UINT64_T 1
+#endif
+#ifndef INT16_MIN
+# define INT16_MIN (-32767-1)
+#endif
+#ifndef INT16_MAX
+# define INT16_MAX (32767)
+#endif
+#ifndef UINT16_MAX
+# define UINT16_MAX (65535)
+#endif
+
+#ifndef CAIRO_BOILERPLATE_DEBUG
+#define CAIRO_BOILERPLATE_DEBUG(x)
+#endif
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#define CAIRO_BOILERPLATE_PRINTF_FORMAT(fmt_index, va_index) \
+ __attribute__((__format__(__printf__, fmt_index, va_index)))
+#else
+#define CAIRO_BOILERPLATE_PRINTF_FORMAT(fmt_index, va_index)
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+CAIRO_BEGIN_DECLS
+
+/* A fake format we use for the flattened ARGB output of the PS and
+ * PDF surfaces. */
+#define CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED ((unsigned int) -1)
+
+extern const cairo_user_data_key_t cairo_boilerplate_output_basename_key;
+
+cairo_content_t
+cairo_boilerplate_content (cairo_content_t content);
+
+const char *
+cairo_boilerplate_content_name (cairo_content_t content);
+
+cairo_format_t
+cairo_boilerplate_format_from_content (cairo_content_t content);
+
+typedef enum {
+ CAIRO_BOILERPLATE_MODE_TEST,
+ CAIRO_BOILERPLATE_MODE_PERF
+} cairo_boilerplate_mode_t;
+
+typedef cairo_surface_t *
+(*cairo_boilerplate_create_surface_t) (const char *name,
+ cairo_content_t content,
+ double width,
+ double height,
+ double max_width,
+ double max_height,
+ cairo_boilerplate_mode_t mode,
+ void **closure);
+
+typedef cairo_surface_t *
+(*cairo_boilerplate_create_similar_t) (cairo_surface_t *other,
+ cairo_content_t content,
+ int width,
+ int height);
+
+typedef void
+(*cairo_boilerplate_force_fallbacks_t) (cairo_surface_t *surface,
+ double x_pixels_per_inch,
+ double y_pixels_per_inch);
+
+typedef cairo_status_t
+(*cairo_boilerplate_finish_surface_t) (cairo_surface_t *surface);
+
+typedef cairo_surface_t *
+(*cairo_boilerplate_get_image_surface_t) (cairo_surface_t *surface,
+ int page,
+ int width,
+ int height);
+
+typedef cairo_status_t
+(*cairo_boilerplate_write_to_png_t) (cairo_surface_t *surface,
+ const char *filename);
+
+typedef void
+(*cairo_boilerplate_cleanup_t) (void *closure);
+
+typedef void
+(*cairo_boilerplate_wait_t) (void *closure);
+
+typedef char *
+(*cairo_boilerplate_describe_t) (void *closure);
+
+typedef struct _cairo_boilerplate_target {
+ const char *name;
+ const char *basename;
+ const char *file_extension;
+ const char *reference_target;
+ cairo_surface_type_t expected_type;
+ cairo_content_t content;
+ unsigned int error_tolerance;
+ const char *probe; /* runtime dl check */
+ cairo_boilerplate_create_surface_t create_surface;
+ cairo_boilerplate_create_similar_t create_similar;
+ cairo_boilerplate_force_fallbacks_t force_fallbacks;
+ cairo_boilerplate_finish_surface_t finish_surface;
+ cairo_boilerplate_get_image_surface_t get_image_surface;
+ cairo_boilerplate_write_to_png_t write_to_png;
+ cairo_boilerplate_cleanup_t cleanup;
+ cairo_boilerplate_wait_t synchronize;
+ cairo_boilerplate_describe_t describe;
+ cairo_bool_t is_measurable;
+ cairo_bool_t is_vector;
+ cairo_bool_t is_recording;
+} cairo_boilerplate_target_t;
+
+const cairo_boilerplate_target_t *
+cairo_boilerplate_get_image_target (cairo_content_t content);
+
+const cairo_boilerplate_target_t *
+cairo_boilerplate_get_target_by_name (const char *name,
+ cairo_content_t content);
+
+const cairo_boilerplate_target_t **
+cairo_boilerplate_get_targets (int *num_targets,
+ cairo_bool_t *limited_targets);
+
+void
+cairo_boilerplate_free_targets (const cairo_boilerplate_target_t **targets);
+
+cairo_surface_t *
+_cairo_boilerplate_get_image_surface (cairo_surface_t *src,
+ int page,
+ int width,
+ int height);
+cairo_surface_t *
+cairo_boilerplate_get_image_surface_from_png (const char *filename,
+ int width,
+ int height,
+ cairo_bool_t flatten);
+
+cairo_surface_t *
+cairo_boilerplate_surface_create_in_error (cairo_status_t status);
+
+enum {
+ CAIRO_BOILERPLATE_OPEN_NO_DAEMON = 0x1,
+};
+
+FILE *
+cairo_boilerplate_open_any2ppm (const char *filename,
+ int page,
+ unsigned int flags,
+ int (**close_cb) (FILE *));
+
+cairo_surface_t *
+cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file);
+
+cairo_surface_t *
+cairo_boilerplate_convert_to_image (const char *filename,
+ int page);
+
+int
+cairo_boilerplate_version (void);
+
+const char*
+cairo_boilerplate_version_string (void);
+
+void
+cairo_boilerplate_fini (void);
+
+#include "cairo-boilerplate-system.h"
+
+CAIRO_END_DECLS
+
+#endif
diff --git a/boilerplate/check-link.c b/boilerplate/check-link.c
new file mode 100755
index 000000000..f16444878
--- /dev/null
+++ b/boilerplate/check-link.c
@@ -0,0 +1,24 @@
+#define CAIRO_VERSION_H 1
+
+#include <cairo-boilerplate.h>
+
+/* get the "real" version info instead of dummy cairo-version.h */
+#undef CAIRO_VERSION_H
+#include "../cairo-version.h"
+
+#include <stdio.h>
+
+int
+main (void)
+{
+ printf ("Check linking to the just built cairo boilerplate library\n");
+ if (cairo_boilerplate_version () == CAIRO_VERSION) {
+ return 0;
+ } else {
+ fprintf (stderr,
+ "Error: linked to cairo boilerplate version %s instead of %s\n",
+ cairo_boilerplate_version_string (),
+ CAIRO_VERSION_STRING);
+ return 1;
+ }
+}
diff --git a/boilerplate/make-cairo-boilerplate-constructors.sh b/boilerplate/make-cairo-boilerplate-constructors.sh
new file mode 100755
index 000000000..09716ca9e
--- /dev/null
+++ b/boilerplate/make-cairo-boilerplate-constructors.sh
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+if test $# -eq 0; then
+ echo "$0: no input files." >&2
+ exit 0
+fi
+
+cat <<HERE
+/* WARNING: Autogenerated file - see $0! */
+
+#include "cairo-boilerplate-private.h"
+
+void _cairo_boilerplate_register_all (void);
+
+HERE
+
+cat "$@" | sed '/^CAIRO_BOILERPLATE/!d; s/CAIRO_BOILERPLATE.*(\(.*\),.*/extern void _register_\1 (void);/'
+
+cat <<HERE
+
+void
+_cairo_boilerplate_register_all (void)
+{
+HERE
+
+cat "$@" | sed '/^CAIRO_BOILERPLATE/!d; s/CAIRO_BOILERPLATE.*(\(.*\),.*/ _register_\1 ();/'
+
+echo "}"
+