summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2008-11-20 14:35:18 +0100
committerNicolas Bruguier <nicolas.bruguier@supersonicimagine.fr>2008-11-29 14:06:31 +0100
commitd49fa3d2bb3d051aa1a8fb5864f8bb60bc080da2 (patch)
tree9dd2a99e3384b75603eca78847001da6a625b3b5
parent2aaf900b89cd12fc8d698b984588513479543dd2 (diff)
[examples] Add cairogears.
Add cairogears in examples, its a good test for cairo/glitz interactions.
-rw-r--r--configure.in12
-rw-r--r--examples/Makefile.am5
-rw-r--r--examples/cairogears/Makefile.am35
-rw-r--r--examples/cairogears/bg.pngbin0 -> 191640 bytes
-rw-r--r--examples/cairogears/cairogears-agl.c197
-rw-r--r--examples/cairogears/cairogears-glx.c370
-rw-r--r--examples/cairogears/cairogears.h57
-rw-r--r--examples/cairogears/common.c118
-rw-r--r--examples/cairogears/comp.c179
-rw-r--r--examples/cairogears/desktop.pngbin0 -> 59793 bytes
-rw-r--r--examples/cairogears/fakewin.pngbin0 -> 2557 bytes
-rw-r--r--examples/cairogears/fdface.c87
-rw-r--r--examples/cairogears/fdface.h32
-rw-r--r--examples/cairogears/fdhand.c136
-rw-r--r--examples/cairogears/fdhand.h33
-rw-r--r--examples/cairogears/fdlogo.c173
-rw-r--r--examples/cairogears/fdlogo.h33
-rw-r--r--examples/cairogears/fg.pngbin0 -> 71226 bytes
-rw-r--r--examples/cairogears/glider.pngbin0 -> 921 bytes
-rw-r--r--examples/cairogears/orion.pngbin0 -> 286253 bytes
-rw-r--r--examples/cairogears/read_png.c144
-rw-r--r--examples/cairogears/read_png.h6
-rw-r--r--examples/cairogears/shadow.c396
-rw-r--r--examples/cairogears/text.c191
-rw-r--r--examples/cairogears/trap.c264
25 files changed, 2468 insertions, 0 deletions
diff --git a/configure.in b/configure.in
index 2a0f9c2..7e8461f 100644
--- a/configure.in
+++ b/configure.in
@@ -104,15 +104,26 @@ dnl ===========================================================================
PKG_PROG_PKG_CONFIG
PKG_CHECK_EXISTS([libpng12], [enable_png=yes], [enable_png=no])
+PKG_CHECK_EXISTS([cairo-glitz], [enable_cairogears=$enable_png], [enable_cairogears=no])
if test $enable_png = yes ; then
PKG_CHECK_MODULES(LIBPNG, [libpng12])
fi
+if test $enable_cairogears = yes ; then
+ dnl Check cairo here, we do not want the -lglitz option.
+ dnl However, we have to remove -I.../glitz manually.
+ PKG_CHECK_MODULES(CAIRO, [cairo])
+ CAIRO_CFLAGS=`echo " $CAIRO_CFLAGS" | sed 's, -I[[^ ]]*/glitz *,,' `
+fi
+
AM_CONDITIONAL(HAVE_LIBPNG, [test "x$enable_png" = xyes])
+AM_CONDITIONAL(HAVE_CAIRO, [test "x$enable_cairogears" = xyes])
AC_SUBST(LIBPNG_CFLAGS)
AC_SUBST(LIBPNG_LIBS)
+AC_SUBST(CAIRO_CFLAGS)
+AC_SUBST(CAIRO_LIBS)
dnl ===========================================================================
@@ -323,6 +334,7 @@ src/agl/glitz-agl.pc
src/egl/glitz-egl.pc
src/wgl/glitz-wgl.pc
examples/Makefile
+examples/cairogears/Makefile
examples/glitzinfo/Makefile
examples/renderer-test/Makefile
])
diff --git a/examples/Makefile.am b/examples/Makefile.am
index cb9891f..3cdf963 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1 +1,6 @@
+DIST_SUBDIRS = glitzinfo renderer-test cairogears
SUBDIRS = glitzinfo renderer-test
+
+if HAVE_CAIRO
+SUBDIRS += cairogears
+endif
diff --git a/examples/cairogears/Makefile.am b/examples/cairogears/Makefile.am
new file mode 100644
index 0000000..adc9782
--- /dev/null
+++ b/examples/cairogears/Makefile.am
@@ -0,0 +1,35 @@
+INCLUDES = $(GLITZ_INC)
+
+noinst_PROGRAMS =
+
+CAIROGEARS_SRC = trap.c comp.c text.c shadow.c read_png.c \
+ fdface.c fdhand.c fdlogo.c common.c
+
+cairogears: $(OBJS)
+ gcc -o $@ $(OBJS) $(LDFLAGS)
+
+all: $(PROGS)
+
+clean:
+ rm -f $(PROGS) *.o
+
+
+if GLITZ_BUILD_AGL_BACKEND
+noinst_PROGRAMS += cairogears-agl
+
+cairogears_agl_CFLAGS = $(GLITZ_AGL_CFLAGS) $(CAIRO_CFLAGS)
+
+cairogears_agl_SOURCES = cairogears-agl.c $(CAIROGEARS_SRC)
+
+cairogears_agl_LDADD = $(GLITZ_LIB) $(GLITZ_AGL_LIBS) $(CARBON_LIBS) $(CAIRO_LIBS)
+endif
+
+if GLITZ_BUILD_GLX_BACKEND
+noinst_PROGRAMS += cairogears-glx
+
+cairogears_glx_CFLAGS = $(GLITZ_GLX_CFLAGS) $(CAIRO_CFLAGS)
+
+cairogears_glx_SOURCES = cairogears-glx.c $(CAIROGEARS_SRC)
+
+cairogears_glx_LDADD = $(GLITZ_LIB) $(GLITZ_GLX_LIBS) $(CAIRO_LIBS)
+endif
diff --git a/examples/cairogears/bg.png b/examples/cairogears/bg.png
new file mode 100644
index 0000000..30b1902
--- /dev/null
+++ b/examples/cairogears/bg.png
Binary files differ
diff --git a/examples/cairogears/cairogears-agl.c b/examples/cairogears/cairogears-agl.c
new file mode 100644
index 0000000..2f3078b
--- /dev/null
+++ b/examples/cairogears/cairogears-agl.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * 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 names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON 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: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include "cairogears.h"
+#include <glitz-agl.h>
+#include <OpenGL/gl.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <math.h>
+#include <strings.h>
+
+static WindowRef window;
+static cairo_surface_t *surface = NULL;
+static int test_type = 0;
+static int aa = -1;
+
+int
+main (int argc, char **argv)
+{
+ Rect window_bounds;
+ CFStringRef title;
+ EventRecord event;
+ RgnHandle region_handler;
+
+ glitz_drawable_format_t templ;
+ glitz_drawable_format_t *dformat;
+ glitz_drawable_t *drawable = NULL;
+ unsigned long mask = 0;
+
+ unsigned int width, height, window_width, window_height;
+ int i;
+
+ program_name = argv[0];
+
+ for (i = 1; i < argc; i++) {
+ if (!strcasecmp ("-agl", argv[i])) {
+ ;
+ } else if (!strcasecmp ("-noaa", argv[i])) {
+ aa = 0;
+ } else if (!strcasecmp ("-swaa", argv[i])) {
+ aa = 1;
+ } else if (!strcasecmp ("-hwaa", argv[i])) {
+ aa = 3;
+ } else {
+ test_type = get_test_type (argv[i]);
+ }
+ }
+
+ if (!test_type) {
+ usage();
+ exit(1);
+ }
+
+ window_width = width = WINDOW_WIDTH;
+ window_height = height = WINDOW_HEIGHT;
+
+ if (aa == 3)
+ templ.samples = 4;
+ else
+ templ.samples = 1;
+
+ mask |= GLITZ_FORMAT_SAMPLES_MASK;
+
+ SetRect (&window_bounds, 100, 100, 100 + WINDOW_WIDTH,
+ 100 + WINDOW_HEIGHT);
+
+ InitCursor();
+
+ CreateNewWindow (kDocumentWindowClass,
+ kWindowStandardDocumentAttributes,
+ &window_bounds,
+ &window);
+
+ SetPortWindowPort (window);
+
+ title = CFSTR (PACKAGE);
+ SetWindowTitleWithCFString (window, title);
+ CFRelease (title);
+
+ SelectWindow (window);
+
+ dformat = glitz_agl_find_window_format (mask, &templ, 0);
+ if (!dformat) {
+ fprintf (stderr, "Error: couldn't find window format\n");
+ exit (1);
+ }
+
+ drawable = glitz_agl_create_drawable_for_window (dformat, window,
+ width, height);
+ if (!drawable) {
+ printf ("failed to create glitz drawable\n");
+ exit (1);
+ }
+
+ if (aa == 3 && dformat->samples < 2) {
+ fprintf (stderr, "hardware multi-sampling not available\n");
+ exit (1);
+ }
+
+ if (drawable) {
+ surface = resize_glitz_drawable (drawable, dformat, width, height);
+ }
+
+ cr = cairo_create (surface);
+ cairo_set_tolerance (cr, 0.5);
+
+ switch (test_type) {
+ case STROKE_AND_FILL_TYPE:
+ case STROKE_AND_FILL_TYPE_GRADIENT:
+ trap_setup (cr, width, height);
+ break;
+ case COMPOSITE_AND_TRANSFORM_TYPE:
+ comp_setup (cr, width, height);
+ break;
+ case TEXT_PATH_TYPE:
+ text_setup (cr, width, height);
+ break;
+ case SHADOW_TYPE:
+ shadow_setup (cr, width, height);
+ break;
+ }
+
+ signal (SIGALRM, alarmhandler);
+ alarm (5);
+
+ ShowWindow (window);
+
+ region_handler = NewRgn ();
+
+ for (;;) {
+ if (WaitNextEvent (everyEvent, &event, 0, region_handler)) {
+ WindowPartCode part_code = FindWindow (event.where, &window);
+
+ switch (event.what) {
+ case mouseDown:
+ if (window != FrontWindow ())
+ SelectWindow (window);
+
+ switch (part_code) {
+ case inDrag:
+ DragWindow (window, event.where, NULL);
+ break;
+ }
+ break;
+ }
+ } else {
+ switch (test_type) {
+ case STROKE_AND_FILL_TYPE:
+ case STROKE_AND_FILL_TYPE_GRADIENT:
+ trap_render (width, height, test_type == STROKE_AND_FILL_TYPE_GRADIENT);
+ break;
+ case COMPOSITE_AND_TRANSFORM_TYPE:
+ comp_render (width, height);
+ break;
+ case TEXT_PATH_TYPE:
+ text_render (width, height);
+ break;
+ case SHADOW_TYPE:
+ shadow_render (width, height);
+ break;
+ }
+
+ glitz_drawable_swap_buffers (drawable);
+
+ frame_cnt++;
+ }
+ }
+
+ exit (1);
+}
diff --git a/examples/cairogears/cairogears-glx.c b/examples/cairogears/cairogears-glx.c
new file mode 100644
index 0000000..f4e69d9
--- /dev/null
+++ b/examples/cairogears/cairogears-glx.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * 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 names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON 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: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include "cairogears.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <glitz-glx.h>
+#include <cairo-xlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <math.h>
+#include <strings.h>
+
+static Display *dpy;
+static Window win;
+static Pixmap pixmap = None;
+static XWMHints xwmh = {
+ (InputHint|StateHint),
+ False,
+ NormalState,
+ 0,
+ 0,
+ 0, 0,
+ 0,
+ 0,
+};
+
+static unsigned char *image = NULL;
+static cairo_surface_t *surface = NULL;
+static int output_type = IMAGE_TYPE;
+static int test_type = 0;
+static int aa = -1;
+
+void
+resize_image (int w, int h)
+{
+ if (surface)
+ cairo_surface_destroy (surface);
+
+ if (image)
+ free (image);
+
+ image = (unsigned char *) malloc (w * h * 4);
+
+ surface = cairo_image_surface_create_for_data (image,
+ CAIRO_FORMAT_ARGB32,
+ w, h, w * 4);
+}
+
+#ifdef CAIRO_HAS_XLIB_SURFACE
+void
+resize_pixmap (int w, int h)
+{
+ if (surface)
+ cairo_surface_destroy (surface);
+
+ if (pixmap)
+ XFreePixmap (dpy, pixmap);
+
+ pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy), w, h,
+ DefaultDepth (dpy, DefaultScreen (dpy)));
+
+ surface = cairo_xlib_surface_create (dpy,
+ pixmap,
+ DefaultVisual (dpy, DefaultScreen (dpy)),
+ w, h);
+}
+#endif
+
+int
+main (int argc, char **argv) {
+
+ XEvent event;
+ XSizeHints xsh;
+ XSetWindowAttributes xswa;
+ XVisualInfo *vinfo;
+
+ glitz_drawable_format_t templ;
+ glitz_drawable_format_t *dformat;
+ glitz_drawable_t *drawable = NULL;
+ unsigned long mask = 0;
+
+ unsigned int width, height, window_width, window_height;
+ int i;
+
+ program_name = argv[0];
+
+ for (i = 1; i < argc; i++) {
+ if (!strcasecmp ("-image", argv[i]))
+ output_type = IMAGE_TYPE;
+
+#ifdef CAIRO_HAS_XLIB_SURFACE
+ else if (!strcasecmp ("-xrender", argv[i])) {
+ output_type = XRENDER_TYPE;
+ }
+#endif
+
+ else if (!strcasecmp ("-glx", argv[i])) {
+ output_type = GLX_TYPE;
+ } else if (!strcasecmp ("-noaa", argv[i])) {
+ aa = 0;
+ } else if (!strcasecmp ("-swaa", argv[i])) {
+ aa = 1;
+ } else if (!strcasecmp ("-hwaa", argv[i])) {
+ aa = 3;
+ } else {
+ test_type = get_test_type (argv[i]);
+ }
+ }
+
+ if (!test_type) {
+ usage();
+ exit(1);
+ }
+
+ window_width = width = WINDOW_WIDTH;
+ window_height = height = WINDOW_HEIGHT;
+
+ if (aa == 3)
+ templ.samples = 4;
+ else
+ templ.samples = 1;
+
+ mask |= GLITZ_FORMAT_SAMPLES_MASK;
+
+ if ((dpy = XOpenDisplay (NULL)) == NULL) {
+ fprintf(stderr, "%s: can't open display: %s\n", argv[0],
+ XDisplayName (NULL));
+ exit(1);
+ }
+
+ if (output_type != GLX_TYPE) {
+ xsh.flags = PSize;
+ xsh.width = width;
+ xsh.height = height;
+ xsh.x = 0;
+ xsh.y = 0;
+
+ win = XCreateWindow (dpy, RootWindow (dpy, DefaultScreen (dpy)),
+ xsh.x, xsh.y, xsh.width, xsh.height,
+ 0, CopyFromParent, CopyFromParent,
+ CopyFromParent, 0, &xswa);
+
+ XSetStandardProperties (dpy, win, PACKAGE, PACKAGE, None,
+ argv, argc, &xsh);
+ XSetWMHints (dpy, win, &xwmh);
+
+ XSelectInput (dpy, win, StructureNotifyMask);
+
+ } else {
+ int i;
+
+ xsh.flags = PSize;
+ xsh.width = width;
+ xsh.height = height;
+ xsh.x = 0;
+ xsh.y = 0;
+
+ mask = 0;
+
+ templ.doublebuffer = 1;
+ mask |= GLITZ_FORMAT_DOUBLEBUFFER_MASK;
+
+ i = 0;
+ do {
+ dformat = glitz_glx_find_window_format (dpy, DefaultScreen (dpy),
+ mask, &templ, i++);
+ if (!dformat) {
+ dformat = glitz_glx_find_window_format (dpy, DefaultScreen (dpy),
+ mask, &templ, 0);
+ i = -1;
+ }
+ vinfo = glitz_glx_get_visual_info_from_format (dpy,
+ DefaultScreen (dpy),
+ dformat);
+ } while ((!vinfo || vinfo->depth != 32) && i != -1);
+
+ xswa.colormap =
+ XCreateColormap (dpy,
+ RootWindow (dpy, DefaultScreen (dpy)),
+ vinfo->visual, AllocNone);
+ win = XCreateWindow (dpy, RootWindow (dpy, DefaultScreen (dpy)),
+ xsh.x, xsh.y, xsh.width, xsh.height,
+ 0, vinfo->depth, CopyFromParent,
+ vinfo->visual, CWColormap, &xswa);
+
+ XSetStandardProperties (dpy, win, PACKAGE, PACKAGE, None,
+ argv, argc, &xsh);
+ XSetWMHints (dpy, win, &xwmh);
+
+ XSelectInput (dpy, win, StructureNotifyMask);
+ }
+
+ switch (output_type) {
+
+ case XRENDER_TYPE:
+ resize_pixmap (width, height);
+ break;
+
+ case IMAGE_TYPE:
+ resize_image (width, height);
+ break;
+ case GLX_TYPE:
+ drawable =
+ glitz_glx_create_drawable_for_window (dpy, 0, dformat, win,
+ width, height);
+ if (!drawable) {
+ printf ("failed to create glitz drawable\n");
+ exit (1);
+ }
+ break;
+ }
+
+ if (aa == 3 && dformat->samples < 2) {
+ fprintf (stderr, "hardware multi-sampling not available\n");
+ exit (1);
+ }
+
+ if (drawable) {
+ surface = resize_glitz_drawable (drawable, dformat, width, height);
+ }
+
+ cr = cairo_create (surface);
+ cairo_set_tolerance (cr, 0.5);
+
+ switch (test_type) {
+ case STROKE_AND_FILL_TYPE:
+ trap_setup (cr, width, height);
+ break;
+ case COMPOSITE_AND_TRANSFORM_TYPE:
+ comp_setup (cr, width, height);
+ break;
+ case TEXT_PATH_TYPE:
+ text_setup (cr, width, height);
+ break;
+ case SHADOW_TYPE:
+ shadow_setup (cr, width, height);
+ break;
+ }
+
+ signal (SIGALRM, alarmhandler);
+ alarm (5);
+
+ XMapWindow (dpy, win);
+
+ for (;;) {
+ if (XPending (dpy)) {
+ XNextEvent (dpy, &event);
+ if (event.type == ConfigureNotify) {
+ width = event.xconfigure.width;
+ height = event.xconfigure.height;
+
+ switch (output_type) {
+
+#ifdef CAIRO_HAS_XLIB_SURFACE
+ case XRENDER_TYPE:
+ resize_pixmap (width, height);
+ cairo_destroy (cr);
+ cr = cairo_create (surface);
+ cairo_set_tolerance (cr, 0.5);
+ break;
+#endif
+
+ case IMAGE_TYPE:
+ resize_image (width, height);
+ cairo_destroy (cr);
+ cr = cairo_create (surface);
+ cairo_set_tolerance (cr, 0.5);
+ break;
+ case GLX_TYPE:
+ cairo_surface_destroy (surface);
+ surface = resize_glitz_drawable (drawable, dformat,
+ width, height);
+ cairo_destroy (cr);
+ cr = cairo_create (surface);
+ cairo_set_tolerance (cr, 0.5);
+ break;
+ }
+ }
+ } else {
+
+ switch (test_type) {
+ case STROKE_AND_FILL_TYPE:
+ case STROKE_AND_FILL_TYPE_GRADIENT:
+ trap_render (width, height, test_type == STROKE_AND_FILL_TYPE_GRADIENT);
+ break;
+ case COMPOSITE_AND_TRANSFORM_TYPE:
+ comp_render (width, height);
+ break;
+ case TEXT_PATH_TYPE:
+ text_render (width, height);
+ break;
+ case SHADOW_TYPE:
+ shadow_render (width, height);
+ break;
+ } switch (output_type) {
+
+#ifdef CAIRO_HAS_XLIB_SURFACE
+ case XRENDER_TYPE:
+ XSetWindowBackgroundPixmap (dpy, win, pixmap);
+ XClearWindow (dpy, win);
+ break;
+#endif
+
+ case IMAGE_TYPE: {
+ GC gc;
+ XImage *xim;
+
+ pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy),
+ width, height,
+ DefaultDepth (dpy,
+ DefaultScreen (dpy)));
+ xim = XCreateImage(dpy, DefaultVisual (dpy,
+ DefaultScreen (dpy)),
+ DefaultDepth(dpy, DefaultScreen (dpy)),
+ ZPixmap, 0, (char *) image,
+ width, height, 32, 0);
+ gc = XCreateGC (dpy, pixmap, 0, NULL);
+ XPutImage (dpy, pixmap, gc, xim, 0, 0, 0, 0, width, height);
+
+ XFreeGC (dpy, gc);
+ xim->data = NULL;
+ XDestroyImage (xim);
+
+ XSetWindowBackgroundPixmap (dpy, win, pixmap);
+ XClearWindow (dpy, win);
+ XFreePixmap (dpy, pixmap);
+ } break;
+ case GLX_TYPE:
+ glitz_drawable_swap_buffers (drawable);
+
+ break;
+ }
+
+ XSync (dpy, 0);
+
+ frame_cnt++;
+ }
+ }
+
+ exit (1);
+}
diff --git a/examples/cairogears/cairogears.h b/examples/cairogears/cairogears.h
new file mode 100644
index 0000000..2ae4bfe
--- /dev/null
+++ b/examples/cairogears/cairogears.h
@@ -0,0 +1,57 @@
+#ifndef _CAIROGEARS_H
+#define _CAIROGEARS_H 1
+
+#include <cairo.h>
+#include <glitz.h>
+#include <cairo-glitz.h>
+
+#define PACKAGE "cairogears"
+
+#define WINDOW_WIDTH 512
+#define WINDOW_HEIGHT 512
+
+extern cairo_t *cr;
+extern unsigned int frame_cnt;
+extern char *program_name;
+
+void trap_setup (cairo_t *cr, int w, int h);
+void trap_render (int w, int h, int fill_gradient);
+
+void comp_setup (cairo_t *cr, int w, int h);
+void comp_render (int w, int h);
+
+void text_setup (cairo_t *cr, int w, int h);
+void text_render (int w, int h);
+
+void text2_setup (cairo_t *cr, int w, int h);
+void text2_render (int w, int h);
+
+void shadow_setup (cairo_t *cr, int w, int h);
+void shadow_render (int w, int h);
+
+enum {
+ IMAGE_TYPE = 1,
+ XRENDER_TYPE,
+ GLX_TYPE,
+ AGL_TYPE
+};
+
+enum {
+ STROKE_AND_FILL_TYPE = 1,
+ STROKE_AND_FILL_TYPE_GRADIENT,
+ COMPOSITE_AND_TRANSFORM_TYPE,
+ TEXT_PATH_TYPE,
+ SHADOW_TYPE
+};
+
+void usage(void);
+void resize_image (int w, int h);
+void alarmhandler (int sig);
+int get_test_type (const char *arg);
+glitz_format_t *get_glitz_format (glitz_drawable_format_t* dformat,
+ glitz_drawable_t* drawable);
+cairo_surface_t * resize_glitz_drawable (glitz_drawable_t *drawable,
+ glitz_drawable_format_t *dformat,
+ int width, int height);
+
+#endif
diff --git a/examples/cairogears/common.c b/examples/cairogears/common.c
new file mode 100644
index 0000000..ec0a101
--- /dev/null
+++ b/examples/cairogears/common.c
@@ -0,0 +1,118 @@
+#include "cairogears.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <math.h>
+#include <strings.h>
+
+cairo_t *cr;
+unsigned int frame_cnt = 0;
+char *program_name;
+
+void
+usage(void) {
+
+ printf ("Usage: %s ["
+ "-image | "
+ "-xrender | "
+ "{-glx | -agl} [-noaa|-swaa|-hwaa]"
+ "] TEST\n\n\tThe following tests are available:\n\n"
+ "\tTRAP Trapezoid fill test\n"
+ "\tGRAD Trapezoid gradient test\n"
+ "\tCOMP Composite and transform test\n"
+ "\tTEXT Text path test\n"
+ "\tSHADOW Composite with mask and convolution filter test\n\n",
+ program_name);
+}
+
+void alarmhandler (int sig) {
+ if (sig == SIGALRM) {
+ {
+ printf ("%d frames in 5.0 seconds = %.3f FPS\n", frame_cnt,
+ frame_cnt / 5.0);
+ }
+ frame_cnt = 0;
+ }
+ signal (SIGALRM, alarmhandler);
+ alarm(5);
+}
+
+glitz_format_t*
+get_glitz_format (glitz_drawable_format_t* dformat,
+ glitz_drawable_t* drawable)
+{
+ glitz_format_t* format = NULL;
+ glitz_format_t formatTemplate;
+
+ formatTemplate.color = dformat->color;
+ formatTemplate.color.fourcc = GLITZ_FOURCC_RGB;
+
+ format = glitz_find_format (drawable,
+ GLITZ_FORMAT_RED_SIZE_MASK |
+ GLITZ_FORMAT_GREEN_SIZE_MASK |
+ GLITZ_FORMAT_BLUE_SIZE_MASK |
+ GLITZ_FORMAT_ALPHA_SIZE_MASK |
+ GLITZ_FORMAT_FOURCC_MASK,
+ &formatTemplate,
+ 0);
+
+ if (!format)
+ {
+ puts ("Could not find glitz-surface-format!");
+ return NULL;
+ }
+
+ return format;
+}
+
+cairo_surface_t *
+resize_glitz_drawable (glitz_drawable_t *drawable,
+ glitz_drawable_format_t *dformat,
+ int width,
+ int height)
+{
+ glitz_surface_t *surface;
+ glitz_format_t *format;
+ cairo_surface_t *crsurface;
+
+ glitz_drawable_update_size (drawable, width, height);
+
+ format = get_glitz_format (dformat, drawable);
+ surface = glitz_surface_create (drawable, format, width, height, 0, NULL);
+ if (!surface) {
+ fprintf (stderr, "Error: couldn't create glitz surface\n");
+ exit (1);
+ }
+
+ if (dformat->doublebuffer)
+ glitz_surface_attach (surface, drawable, GLITZ_DRAWABLE_BUFFER_BACK_COLOR);
+ else
+ glitz_surface_attach (surface, drawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
+
+ crsurface = cairo_glitz_surface_create (surface);
+
+ return crsurface;
+}
+
+
+int
+get_test_type (const char *arg)
+{
+ if (!strcasecmp ("TRAP", arg)) {
+ return STROKE_AND_FILL_TYPE;
+ } else if (!strcasecmp ("GRAD", arg)) {
+ return STROKE_AND_FILL_TYPE_GRADIENT;
+ } else if (!strcasecmp ("COMP", arg)) {
+ return COMPOSITE_AND_TRANSFORM_TYPE;
+ } else if (!strcasecmp ("TEXT", arg)) {
+ return TEXT_PATH_TYPE;
+ } else if (!strcasecmp ("SHADOW", arg)) {
+ return SHADOW_TYPE;
+ } else {
+ fprintf (stderr, "%s: unrecognized option `%s'\n",
+ program_name, arg);
+ usage();
+ exit(1);
+ }
+}
diff --git a/examples/cairogears/comp.c b/examples/cairogears/comp.c
new file mode 100644
index 0000000..cc08b6d
--- /dev/null
+++ b/examples/cairogears/comp.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * 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 names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON 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: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cairo.h>
+#include <math.h>
+
+#include "read_png.h"
+
+cairo_surface_t *bg_surface;
+cairo_surface_t *comp_surface;
+int bg_width, bg_height;
+int comp_width, comp_height;
+
+cairo_t *cr;
+
+void
+comp_setup (cairo_t *_cr, int w, int h)
+{
+ int image_width, image_height;
+ char *image_data;
+ cairo_surface_t *image;
+
+ if (read_png ("bg.png", &image_data, &image_width, &image_height)) {
+ printf ("error reading bg.png\n");
+ exit(1);
+ }
+
+ bg_width = image_width;
+ bg_height = image_height;
+
+ image = cairo_image_surface_create_for_data (image_data,
+ CAIRO_FORMAT_ARGB32,
+ image_width, image_height,
+ image_width * 4);
+
+ bg_surface = cairo_surface_create_similar (cairo_get_target (_cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ image_width, image_height);
+
+ cr = cairo_create (bg_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
+ free (image_data);
+
+ if (read_png ("fg.png", &image_data, &image_width, &image_height)) {
+ printf ("error reading fg.png\n");
+ exit(1);
+ }
+
+ comp_width = image_width;
+ comp_height = image_height;
+
+ image = cairo_image_surface_create_for_data (image_data,
+ CAIRO_FORMAT_ARGB32,
+ image_width, image_height,
+ image_width * 4);
+
+ comp_surface = cairo_surface_create_similar (cairo_get_target (_cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ image_width, image_height);
+
+ cr = cairo_create (comp_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
+ free (image_data);
+
+ cr = _cr;
+}
+
+double comp_x = 400 - 256 / 2;
+double comp_y = 200 - 256 / 2;
+double comp_x_dir = 5.0;
+double comp_y_dir = 5.0;
+
+double oversize = 1.0;
+double oversize_dir = 0.001;
+
+void
+comp_render (int w, int h)
+{
+ double scale_x, scale_y;
+
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_move_to (cr, 0, 0);
+
+ scale_x = ((double) w) / (double) bg_width;
+ scale_y = ((double) h) / (double) bg_height;
+
+ cairo_translate (cr,
+ -((oversize - 1.0) * (double) w) / 2.0,
+ -((oversize - 1.0) * (double) h) / 2.0);
+
+ cairo_scale (cr, scale_x * oversize, scale_y * oversize);
+
+ cairo_set_source_surface (cr, bg_surface, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ oversize += oversize_dir;
+ if (oversize >= 1.2)
+ oversize_dir = -oversize_dir;
+ if (oversize <= 1.0)
+ oversize_dir = -oversize_dir;
+
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_move_to (cr, 0, 0);
+
+ if (comp_x_dir < 0) {
+ if (comp_x_dir < -1.0)
+ comp_x_dir += 10.0 / w;
+ } else {
+ if (comp_x_dir > 1.0)
+ comp_x_dir -= 10.0 / w;
+ }
+
+ if (comp_y_dir < 0) {
+ if (comp_y_dir < -1.0)
+ comp_y_dir += 10.0 / h;
+ } else {
+ if (comp_y_dir > 1.0)
+ comp_y_dir -= 10.0 / h;
+ }
+
+ comp_x += comp_x_dir;
+ comp_y += comp_y_dir;
+
+ if (comp_x >= (w - comp_width))
+ comp_x_dir = -(drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0);
+ else if (comp_x <= 0)
+ comp_x_dir = (drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0);
+
+ if (comp_y >= (h - comp_height))
+ comp_y_dir = -(drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0);
+ else if (comp_y <= 0)
+ comp_y_dir = drand48 () * 5.0 + 1.0 + comp_x_dir / 2.0;
+
+ cairo_translate (cr, (int) comp_x, (int) comp_y);
+ cairo_move_to (cr, 0.0, 0.0);
+
+ cairo_set_source_surface (cr, comp_surface, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_restore (cr);
+}
diff --git a/examples/cairogears/desktop.png b/examples/cairogears/desktop.png
new file mode 100644
index 0000000..3b2587d
--- /dev/null
+++ b/examples/cairogears/desktop.png
Binary files differ
diff --git a/examples/cairogears/fakewin.png b/examples/cairogears/fakewin.png
new file mode 100644
index 0000000..a21fd94
--- /dev/null
+++ b/examples/cairogears/fakewin.png
Binary files differ
diff --git a/examples/cairogears/fdface.c b/examples/cairogears/fdface.c
new file mode 100644
index 0000000..8536d1d
--- /dev/null
+++ b/examples/cairogears/fdface.c
@@ -0,0 +1,87 @@
+/*
+ * $Id: fdface.c,v 1.1 2003/12/02 03:04:46 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "fdface.h"
+
+static void
+draw_fancy_tick (cairo_t *cr, double radius)
+{
+ cairo_save (cr);
+ cairo_arc (cr, 0, 0, radius, 0, 2 * M_PI);
+ cairo_set_source_rgb (cr, 0.231, 0.502, 0.682);
+ cairo_fill (cr);
+ cairo_set_source_rgb (cr, 0.73, 0.73, 0.73);
+ cairo_set_line_width (cr, radius * 2 / 3);
+ cairo_arc (cr, 0, 0, radius * 2, 0, 2 * M_PI);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+static void
+draw_plain_tick (cairo_t *cr, double radius)
+{
+ cairo_save (cr);
+ cairo_arc (cr, 0, 0, radius, 0, 2 * M_PI);
+ cairo_set_source_rgb (cr, 0.231, 0.502, 0.682);
+ cairo_fill (cr);
+ cairo_restore (cr);
+}
+
+void
+fdface_draw (cairo_t *cr, double width, double height)
+{
+ int minute;
+
+ cairo_save (cr);
+ {
+ cairo_scale (cr, width, height);
+ cairo_save (cr);
+ {
+ cairo_translate (cr, .15, .15);
+ cairo_scale (cr, .7, .7);
+ fdlogo_draw (cr, 1, 1);
+ }
+ cairo_restore (cr);
+ cairo_translate (cr, 0.5, 0.5);
+ cairo_scale (cr, 0.93, 0.93);
+ for (minute = 0; minute < 60; minute++)
+ {
+ double degrees, radians;
+ cairo_save (cr);
+ degrees = minute * 6.0;
+ radians = degrees * M_PI / 180;
+ cairo_rotate (cr, radians);
+ cairo_translate (cr, 0, 0.5);
+ if (minute % 15 == 0)
+ draw_fancy_tick (cr, 0.015);
+ else if (minute % 5 == 0)
+ draw_fancy_tick (cr, 0.01);
+ else
+ draw_plain_tick (cr, 0.01);
+ cairo_restore (cr);
+ }
+ }
+ cairo_restore (cr);
+}
+
diff --git a/examples/cairogears/fdface.h b/examples/cairogears/fdface.h
new file mode 100644
index 0000000..1bc2bc9
--- /dev/null
+++ b/examples/cairogears/fdface.h
@@ -0,0 +1,32 @@
+/*
+ * $Id: fdface.h,v 1.1 2003/12/02 03:04:46 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _FDFACE_H_
+#define _FDFACE_H_
+#include "fdlogo.h"
+
+void
+fdface_draw (cairo_t *cr, double width, double height);
+
+#endif /* _FDFACE_H_ */
diff --git a/examples/cairogears/fdhand.c b/examples/cairogears/fdhand.c
new file mode 100644
index 0000000..ece4ff6
--- /dev/null
+++ b/examples/cairogears/fdhand.c
@@ -0,0 +1,136 @@
+/*
+ * $Id: fdhand.c,v 1.3 2003/12/02 08:24:06 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "fdhand.h"
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+
+#define PI_6 (M_PI/6.0)
+
+static void
+draw_hour (cairo_t *cr, double width, double length)
+{
+ double r = width / 2;
+ cairo_move_to (cr, length, -r);
+ cairo_arc (cr, length, 0, r, -M_PI_2, M_PI_2);
+ cairo_line_to (cr, width * M_SQRT2, r);
+ cairo_arc (cr, 0, 0, r*2, PI_6, - PI_6);
+ cairo_close_path (cr);
+}
+
+static void
+draw_minute (cairo_t *cr, double width, double length)
+{
+ double r = width / 2;
+ cairo_move_to (cr, length, -r);
+ cairo_arc (cr, length, 0, r, -M_PI_2, M_PI_2);
+ cairo_line_to (cr, 0, r);
+ cairo_line_to (cr, 0, -r);
+ cairo_close_path (cr);
+}
+
+static void
+draw_second (cairo_t *cr, double width, double length)
+{
+ double r = width / 2;
+ double thick = width;
+ double back = length / 3;
+ double back_thin = length / 10;
+
+ cairo_move_to (cr, length, -r);
+ cairo_arc (cr, length, 0, r, -M_PI_2, M_PI_2);
+ cairo_line_to (cr, -back_thin, r);
+ cairo_line_to (cr, -back_thin, thick);
+ cairo_line_to (cr, -back, thick);
+ cairo_line_to (cr, -back, -thick);
+ cairo_line_to (cr, -back_thin, -thick);
+ cairo_line_to (cr, -back_thin, -r);
+ cairo_close_path (cr);
+}
+
+static void
+draw_hand (cairo_t *cr, double angle, double width, double length, double alt,
+ void (*draw) (cairo_t *cr, double width, double length))
+{
+ /* Disabled shadow
+ cairo_save (cr);
+ {
+ cairo_translate (cr, alt/2, alt);
+ cairo_rotate (cr, angle);
+ (*draw) (cr, width, length);
+ cairo_set_rgb_color (cr, 0, 0, 0);
+ cairo_set_alpha (cr, 0.3);
+ cairo_fill (cr);
+ }
+ cairo_restore (cr);
+ */
+
+ cairo_save (cr);
+ {
+ cairo_rotate (cr, angle);
+ (*draw) (cr, width, length);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_fill (cr);
+ }
+ cairo_restore (cr);
+}
+
+static void
+draw_time (cairo_t *cr, double width, double height, struct timeval *tv, int seconds)
+{
+ double hour_angle, minute_angle, second_angle;
+ struct tm tm_ret;
+ struct tm *tm;
+
+ tm = localtime_r (&tv->tv_sec, &tm_ret);
+
+ second_angle = (tm->tm_sec + tv->tv_usec / 1000000.0) * 6.0;
+ minute_angle = tm->tm_min * 6.0 + second_angle / 60.0;
+ hour_angle = tm->tm_hour * 30.0 + minute_angle / 12.0;
+
+ cairo_save (cr);
+ {
+ cairo_scale (cr, width, height);
+ cairo_translate (cr, 0.5, 0.5);
+ draw_hand (cr, hour_angle * M_PI / 180.0 - M_PI_2,
+ 0.03, 0.25, 0.010, draw_hour);
+ draw_hand (cr, minute_angle * M_PI / 180.0 - M_PI_2,
+ 0.015, 0.39, 0.020, draw_minute);
+ if (seconds)
+ draw_hand (cr, second_angle * M_PI / 180.0 - M_PI_2,
+ 0.0075, 0.32, 0.026, draw_second);
+ }
+ cairo_restore (cr);
+}
+
+void
+fdhand_draw_now (cairo_t *cr, double width, double height, int seconds)
+{
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+
+ draw_time (cr, width, height, &tv, seconds);
+}
+
diff --git a/examples/cairogears/fdhand.h b/examples/cairogears/fdhand.h
new file mode 100644
index 0000000..0eec9d7
--- /dev/null
+++ b/examples/cairogears/fdhand.h
@@ -0,0 +1,33 @@
+/*
+ * $Id: fdhand.h,v 1.1 2003/12/02 03:04:47 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _FDHAND_H_
+#define _FDHAND_H_
+
+#include <cairo.h>
+
+void
+fdhand_draw_now (cairo_t *cr, double width, double height, int seconds);
+
+#endif /* _FDHAND_H_ */
diff --git a/examples/cairogears/fdlogo.c b/examples/cairogears/fdlogo.c
new file mode 100644
index 0000000..a76b8bc
--- /dev/null
+++ b/examples/cairogears/fdlogo.c
@@ -0,0 +1,173 @@
+/*
+ * $Id: fdlogo.c,v 1.1 2003/12/02 03:04:47 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "fdlogo.h"
+
+static void
+draw_boundary (cairo_t *cr)
+{
+ cairo_move_to (cr, 63.000, 36.000);
+
+ cairo_curve_to (cr, 63.000, 43.000,
+ 58.000, 47.000,
+ 51.000, 47.000);
+
+ cairo_line_to (cr, 13.000, 47.000);
+
+ cairo_curve_to (cr, 6.000, 47.000,
+ 1.000, 43.000,
+ 1.000, 36.000);
+
+ cairo_line_to (cr, 1.000, 12.000);
+
+ cairo_curve_to (cr, 1.000, 5.000,
+ 6.000, 1.000,
+ 13.000, 1.000);
+
+ cairo_line_to (cr, 51.000, 1.000);
+
+ cairo_curve_to (cr, 58.000, 1.000,
+ 63.000, 5.000,
+ 63.000, 12.000);
+ cairo_close_path (cr);
+}
+
+static void
+draw_outline (cairo_t *cr)
+{
+ /* cairo_set_rgb_color (cr, 0.73, 0.73, 0.73); */
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_set_line_width (cr, 2);
+ draw_boundary (cr);
+ cairo_stroke (cr);
+}
+
+static void
+draw_background (cairo_t *cr)
+{
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, 0.231, 0.502, 0.682);
+ cairo_translate (cr, 3.5, 3.5);
+ cairo_scale (cr, 0.887, 0.848);
+ draw_boundary (cr);
+ cairo_fill (cr);
+ cairo_restore (cr);
+}
+
+static void
+draw_window (cairo_t *cr)
+{
+ cairo_move_to (cr, -6.00, -7.125);
+
+ cairo_line_to (cr, 6.00, -7.125);
+
+ cairo_curve_to (cr, 8.00, -7.125,
+ 9.00, -6.125,
+ 9.00, -4.125);
+
+ cairo_line_to (cr, 9.00, 4.125);
+
+ cairo_curve_to (cr, 9.00, 6.125,
+ 8.00, 7.125,
+ 6.00, 7.125);
+
+ cairo_line_to (cr, -6.00, 7.125);
+
+ cairo_curve_to (cr, -8.00, 7.125,
+ -9.00, 6.125,
+ -9.00, 4.125);
+
+ cairo_line_to (cr, -9.00, -4.125);
+
+ cairo_curve_to (cr, -9.00, -6.125,
+ -8.00, -7.125,
+ -6.00, -7.125);
+ cairo_close_path (cr);
+}
+
+static void
+draw_window_at (cairo_t *cr, double x, double y, double scale)
+{
+ cairo_save (cr);
+ {
+ cairo_translate (cr, x, y);
+ cairo_scale (cr, scale, scale);
+ draw_window (cr);
+ cairo_save (cr);
+ {
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_fill (cr);
+ }
+ cairo_restore (cr);
+ cairo_set_source_rgb (cr, 0.231, 0.502, 0.682);
+ cairo_scale (cr, 1/scale, 1/scale);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+}
+
+void
+draw_windows (cairo_t *cr)
+{
+ cairo_save (cr);
+ {
+ cairo_move_to (cr, 18.00, 16.125);
+ cairo_line_to (cr, 48.25, 20.375);
+ cairo_line_to (cr, 30.25, 35.825);
+ cairo_close_path (cr);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.5);
+ cairo_stroke (cr);
+ }
+ cairo_restore (cr);
+ draw_window_at (cr, 18.00, 16.125, 1);
+ draw_window_at (cr, 48.25, 20.375, 0.8);
+ draw_window_at (cr, 30.25, 35.825, 0.5);
+}
+
+#define FDLOGO_ROT_X_FACTOR 1.086
+#define FDLOGO_ROT_Y_FACTOR 1.213
+#define FDLOGO_WIDTH (64 * FDLOGO_ROT_X_FACTOR)
+#define FDLOGO_HEIGHT (48 * FDLOGO_ROT_Y_FACTOR)
+
+void
+fdlogo_draw (cairo_t *cr, double width, double height)
+{
+ double x_scale, y_scale, scale, x_off, y_off;
+ cairo_save (cr);
+ x_scale = width / FDLOGO_WIDTH;
+ y_scale = height / FDLOGO_HEIGHT;
+ scale = x_scale < y_scale ? x_scale : y_scale;
+ x_off = (width - (scale * FDLOGO_WIDTH)) / 2;
+ y_off = (height - (scale * FDLOGO_HEIGHT)) / 2;
+ cairo_translate (cr, x_off, y_off);
+ cairo_scale (cr, scale, scale);
+
+ cairo_translate (cr, -2.5, 14.75);
+ cairo_rotate (cr, -0.274990703529840);
+
+ draw_outline (cr);
+ draw_background (cr);
+ draw_windows (cr);
+ cairo_restore (cr);
+}
diff --git a/examples/cairogears/fdlogo.h b/examples/cairogears/fdlogo.h
new file mode 100644
index 0000000..5349bc3
--- /dev/null
+++ b/examples/cairogears/fdlogo.h
@@ -0,0 +1,33 @@
+/*
+ * $Id: fdlogo.h,v 1.1 2003/12/02 03:04:47 keithp Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _FDLOGO_H_
+#define _FDLOGO_H_
+#include <cairo.h>
+#include <math.h>
+
+void
+fdlogo_draw (cairo_t *cr, double width, double height);
+
+#endif /* _FDLOGO_H_ */
diff --git a/examples/cairogears/fg.png b/examples/cairogears/fg.png
new file mode 100644
index 0000000..bc82a91
--- /dev/null
+++ b/examples/cairogears/fg.png
Binary files differ
diff --git a/examples/cairogears/glider.png b/examples/cairogears/glider.png
new file mode 100644
index 0000000..1569678
--- /dev/null
+++ b/examples/cairogears/glider.png
Binary files differ
diff --git a/examples/cairogears/orion.png b/examples/cairogears/orion.png
new file mode 100644
index 0000000..bce26c4
--- /dev/null
+++ b/examples/cairogears/orion.png
Binary files differ
diff --git a/examples/cairogears/read_png.c b/examples/cairogears/read_png.c
new file mode 100644
index 0000000..834f26a
--- /dev/null
+++ b/examples/cairogears/read_png.c
@@ -0,0 +1,144 @@
+#ifndef PNG_H_INCLUDED
+#define PNG_H_INCLUDED
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <png.h>
+#include <setjmp.h>
+
+static void
+premultiply_data (png_structp png,
+ png_row_infop row_info,
+ png_bytep data)
+{
+ unsigned int i;
+
+ for (i = 0; i < row_info->rowbytes; i += 4) {
+ unsigned char *base = &data[i];
+ unsigned char blue = base[0];
+ unsigned char green = base[1];
+ unsigned char red = base[2];
+ unsigned char alpha = base[3];
+ int p;
+
+ red = (unsigned) red * (unsigned) alpha / 255;
+ green = (unsigned) green * (unsigned) alpha / 255;
+ blue = (unsigned) blue * (unsigned) alpha / 255;
+ p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
+ memcpy(base, &p, sizeof (int));
+ }
+}
+
+int
+read_png (const char *filename,
+ char **data,
+ unsigned int *width,
+ unsigned int *height)
+{
+ int i;
+ FILE *file;
+ static const int PNG_SIG_SIZE = 8;
+ unsigned char png_sig[PNG_SIG_SIZE];
+ int sig_bytes;
+ png_struct *png;
+ png_info *info;
+ png_uint_32 png_width, png_height;
+ int depth, color_type, interlace;
+ unsigned int pixel_size;
+ png_byte **row_pointers;
+
+ file = fopen (filename, "rb");
+ if (file == NULL)
+ return 1;
+
+ sig_bytes = fread (png_sig, 1, PNG_SIG_SIZE, file);
+ if (png_check_sig (png_sig, sig_bytes) == 0) {
+ fclose (file);
+ return 2;
+ }
+
+ /* XXX: Perhaps we'll want some other error handlers? */
+ png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
+ NULL,
+ NULL,
+ NULL);
+ if (png == NULL) {
+ fclose (file);
+ return 3;
+ }
+
+ info = png_create_info_struct (png);
+ if (info == NULL) {
+ fclose (file);
+ png_destroy_read_struct (&png, NULL, NULL);
+ return 3;
+ }
+
+ png_init_io (png, file);
+ png_set_sig_bytes (png, sig_bytes);
+
+ png_read_info (png, info);
+
+ png_get_IHDR (png, info,
+ &png_width, &png_height, &depth,
+ &color_type, &interlace, NULL, NULL);
+ *width = png_width;
+ *height = png_height;
+
+ /* convert palette/gray image to rgb */
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_palette_to_rgb (png);
+
+ /* expand gray bit depth if needed */
+ if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8)
+ png_set_gray_1_2_4_to_8 (png);
+
+ /* transform transparency to alpha */
+ if (png_get_valid(png, info, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha (png);
+
+ if (depth == 16)
+ png_set_strip_16 (png);
+
+ if (depth < 8)
+ png_set_packing (png);
+
+ /* convert grayscale to RGB */
+ if (color_type == PNG_COLOR_TYPE_GRAY
+ || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ png_set_gray_to_rgb (png);
+
+ if (interlace != PNG_INTERLACE_NONE)
+ png_set_interlace_handling (png);
+
+ png_set_bgr (png);
+ png_set_filler (png, 0xff, PNG_FILLER_AFTER);
+
+ png_set_read_user_transform_fn(png, premultiply_data);
+
+ png_read_update_info (png, info);
+
+ pixel_size = 4;
+ *data = (char *) malloc (png_width * png_height * pixel_size);
+ if (*data == NULL) {
+ fclose (file);
+ return 3;
+ }
+
+ row_pointers = (png_byte **) malloc (png_height * sizeof(char *));
+ for (i=0; i < png_height; i++)
+ row_pointers[i] = (png_byte *) (*data + i * png_width * pixel_size);
+
+ png_read_image (png, row_pointers);
+ png_read_end (png, info);
+
+ free (row_pointers);
+ fclose (file);
+
+ png_destroy_read_struct (&png, &info, NULL);
+
+ return 0;
+}
+
+#endif /* GLXC_H_INCLUDED */
diff --git a/examples/cairogears/read_png.h b/examples/cairogears/read_png.h
new file mode 100644
index 0000000..527da03
--- /dev/null
+++ b/examples/cairogears/read_png.h
@@ -0,0 +1,6 @@
+
+int
+read_png (const char *filename,
+ char **data,
+ unsigned int *width,
+ unsigned int *height);
diff --git a/examples/cairogears/shadow.c b/examples/cairogears/shadow.c
new file mode 100644
index 0000000..aefc428
--- /dev/null
+++ b/examples/cairogears/shadow.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * 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 names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON 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: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cairo.h>
+#include <math.h>
+
+#include "read_png.h"
+#include "fdface.h"
+#include "fdhand.h"
+
+cairo_surface_t *clock_bg_surface;
+cairo_surface_t *clock_surface;
+cairo_surface_t *glider_surface;
+cairo_surface_t *fakewin_surface;
+cairo_surface_t *bg_surface;
+int bg_width, bg_height;
+
+#define CLOCK_W 256
+#define CLOCK_H 245
+
+int fakewin_width;
+int fakewin_height;
+
+int glider_width;
+int glider_height;
+
+double glider_angle = 0;
+double glider_pos_x = 80;
+double glider_pos_y = 50;
+double glider_dir_x = 1;
+double glider_dir_y = 1;
+
+cairo_t *cr;
+
+static void
+render_fakewin (void)
+{
+ cairo_t *cr2;
+
+ cr2 = cairo_create (fakewin_surface);
+ cairo_set_operator (cr2, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgb (cr2, 1.0, 1.0, 1.0);
+ cairo_move_to (cr2, 0, 0);
+ cairo_rectangle (cr2, 17, 34, fakewin_width - 32, fakewin_height - 50);
+ cairo_fill (cr2);
+ cairo_set_operator (cr2, CAIRO_OPERATOR_OVER);
+ cairo_translate (cr2, (int) glider_pos_x, (int) glider_pos_y);
+
+ cairo_set_source_surface (cr2, glider_surface, 0.0, 0.0);
+ cairo_paint (cr2);
+ cairo_destroy (cr2);
+
+ glider_pos_x += glider_dir_x;
+ glider_pos_y += glider_dir_y;
+
+ if (glider_pos_x <= 18)
+ glider_dir_x = -glider_dir_x;
+
+ if (glider_pos_y <= 35)
+ glider_dir_y = -glider_dir_y;
+
+ if (glider_pos_x >= (fakewin_width - 16 - 37))
+ glider_dir_x = -glider_dir_x;
+
+ if (glider_pos_y >= (fakewin_height - 19 - 37))
+ glider_dir_y = -glider_dir_y;
+}
+
+static void
+render_clock (void)
+{
+ cairo_t *cr2;
+
+ cr2 = cairo_create (clock_surface);
+ cairo_set_operator (cr2, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr2, 0.0, 0.0, 0.0, 0.0);
+ cairo_rectangle (cr2, 0, 0, CLOCK_W, CLOCK_H);
+ cairo_fill (cr2);
+ cairo_set_operator (cr2, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgb (cr2, 0.0, 0.0, 0.0);
+ cairo_move_to (cr2, 0, 0);
+
+ cairo_set_source_surface (cr2, clock_bg_surface, 0.0, 0.0);
+ cairo_paint (cr2);
+
+ fdhand_draw_now (cr2, CLOCK_W, CLOCK_H, 1);
+ cairo_destroy (cr2);
+}
+
+void
+shadow_setup (cairo_t *_cr, int w, int h)
+{
+ int image_width, image_height;
+ char *image_data;
+ cairo_surface_t *image;
+
+ clock_surface = cairo_surface_create_similar (cairo_get_target (_cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ CLOCK_W, CLOCK_H);
+
+ clock_bg_surface = cairo_surface_create_similar (cairo_get_target (_cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ CLOCK_W, CLOCK_H);
+ if (read_png ("desktop.png", &image_data, &image_width, &image_height)) {
+ printf ("error reading desktop.png\n");
+ exit(1);
+ }
+
+ bg_width = image_width;
+ bg_height = image_height;
+
+ image = cairo_image_surface_create_for_data (image_data,
+ CAIRO_FORMAT_ARGB32,
+ image_width, image_height,
+ image_width * 4);
+
+ bg_surface = cairo_surface_create_similar (cairo_get_target (_cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ image_width, image_height);
+
+ cr = cairo_create (bg_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
+ free (image_data);
+
+ if (read_png ("fakewin.png", &image_data, &image_width, &image_height)) {
+ printf ("error reading fakewin.png\n");
+ exit(1);
+ }
+
+ fakewin_width = image_width;
+ fakewin_height = image_height;
+
+ image = cairo_image_surface_create_for_data (image_data,
+ CAIRO_FORMAT_ARGB32,
+ image_width, image_height,
+ image_width * 4);
+
+ fakewin_surface = cairo_surface_create_similar (cairo_get_target (_cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ image_width + 2,
+ image_height + 2);
+
+ cr = cairo_create (fakewin_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ if (read_png ("glider.png", &image_data, &image_width, &image_height)) {
+ printf ("error reading glider.png\n");
+ exit (1);
+ }
+
+ glider_width = image_width;
+ glider_height = image_height;
+
+ image = cairo_image_surface_create_for_data (image_data,
+ CAIRO_FORMAT_ARGB32,
+ image_width, image_height,
+ image_width * 4);
+
+ glider_surface = cairo_surface_create_similar (cairo_get_target (_cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ image_width, image_height);
+
+ cr = cairo_create (glider_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cr = cairo_create (clock_bg_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0);
+ cairo_rectangle (cr, 0, 0, CLOCK_W, CLOCK_H);
+ cairo_fill (cr);
+
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.25);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_scale (cr, CLOCK_W, CLOCK_H);
+ cairo_translate (cr, 0.5, 0.5);
+ cairo_arc (cr, 0, 0, 0.5, 0, 2 * M_PI);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ fdface_draw (cr, CLOCK_W, CLOCK_H);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
+ free (image_data);
+
+ render_clock ();
+ render_fakewin ();
+
+ cr = _cr;
+}
+
+long int shadow_cnt = 0;
+
+double fw_x = 250.0, fw_y = 20.0;
+double cl_x = 50.0, cl_y = 180.0;
+double dst_x = 20.0, dst_y = 270.0;
+double start_x = 250.0, start_y = 20.0;
+
+int which = 1;
+
+static int
+shadow_move_towards_point (double *current_x,
+ double *current_y)
+{
+ double to_go_x = dst_x - *current_x;
+ double to_go_y = dst_y - *current_y;
+ double done_x = *current_x - start_x;
+ double done_y = *current_y - start_y;
+
+ double dist_from_start = fabs (to_go_x) + fabs (to_go_y);
+ double dist_from_goal = fabs (done_x) + fabs (done_y);
+ double speed = (dist_from_start < dist_from_goal) ?
+ dist_from_start: dist_from_goal;
+ double speed_div;
+ double angle;
+
+ speed *= 10.0;
+
+ speed_div = fabs (dst_x - start_x) + fabs (dst_y - start_y);
+
+ speed /= (speed_div > 1.0)? speed_div: 1.0;
+ speed += 0.1;
+
+ angle = fabs (atan (to_go_y / to_go_x));
+
+ *current_x += speed * cos (angle) * ((dst_x > start_x)? 1.0: -1.0);
+ *current_y += speed * sin (angle) * ((dst_y > start_y)? 1.0: -1.0);
+
+ if (start_x <= dst_x) {
+ if (*current_x >= dst_x)
+ return 1;
+ } else {
+ if (*current_x <= dst_x)
+ return 1;
+ }
+
+ if (start_y <= dst_y) {
+ if (*current_y >= dst_y)
+ return 1;
+ } else {
+ if (*current_y <= dst_y)
+ return 1;
+ }
+
+ return 0;
+}
+
+double shadow_alpha = 0.4;
+double max_shadow_offset = 60.0;
+
+void
+shadow_render (int w, int h)
+{
+ double scale_x, scale_y;
+ int move_done;
+ double shadow_offset_x, shadow_offset_y;
+ double light_x, light_y;
+
+ light_x = w / 2.0;
+ light_y = h / 2.0;
+
+ cairo_save (cr);
+
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+ scale_x = ((double) w) / (double) bg_width;
+ scale_y = ((double) h) / (double) bg_height;
+
+ cairo_scale (cr, scale_x, scale_y);
+ cairo_set_source_surface (cr, bg_surface, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ if (!(shadow_cnt % 10))
+ render_clock ();
+ else
+ if (!(shadow_cnt % 5))
+ render_fakewin ();
+
+ shadow_cnt++;
+
+ if (shadow_cnt >= 1000000)
+ shadow_cnt = 0;
+
+ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ shadow_offset_x = max_shadow_offset *
+ ((fw_x + fakewin_width / 2) - light_x) / (w / 2.0);
+ shadow_offset_y = max_shadow_offset *
+ ((fw_y + fakewin_height / 2) - light_y) / (h / 2.0);
+
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, shadow_alpha);
+ cairo_mask_surface (cr, fakewin_surface,
+ fw_x + shadow_offset_x - 0.05 * fakewin_width,
+ fw_y + shadow_offset_y - 0.05 * fakewin_height);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, (int) fw_x, (int) fw_y);
+ cairo_set_source_surface (cr, fakewin_surface, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ shadow_offset_x = max_shadow_offset *
+ ((cl_x + CLOCK_W / 2) - light_x) / (w / 2.0);
+ shadow_offset_y = max_shadow_offset *
+ ((cl_y + CLOCK_H / 2) - light_y) / (h / 2.0);
+
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, shadow_alpha);
+ cairo_mask_surface (cr, clock_surface,
+ cl_x + shadow_offset_x - 0.05 * CLOCK_W,
+ cl_y + shadow_offset_y - 0.05 * CLOCK_H);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, (int) cl_x, (int) cl_y);
+ cairo_set_source_surface (cr, clock_surface, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ if (which) {
+ move_done = shadow_move_towards_point (&fw_x, &fw_y);
+ } else {
+ move_done = shadow_move_towards_point (&cl_x, &cl_y);
+ }
+
+ if (move_done) {
+ which = (int) (drand48 () + 0.5);
+
+ dst_x = drand48 () *
+ (w - ((which)? fakewin_width : CLOCK_W) -
+ max_shadow_offset);
+ dst_y = drand48 () *
+ (h - ((which)? fakewin_height: CLOCK_H) -
+ max_shadow_offset);
+
+ if (which) {
+ start_x = fw_x;
+ start_y = fw_y;
+ } else {
+ start_x = cl_x;
+ start_y = cl_y;
+ }
+ }
+
+ cairo_restore (cr);
+}
diff --git a/examples/cairogears/text.c b/examples/cairogears/text.c
new file mode 100644
index 0000000..ef2a678
--- /dev/null
+++ b/examples/cairogears/text.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * 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 names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON 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: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include <cairo.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "read_png.h"
+
+float font_scale1, font_scale2,
+ font_rotate1, font_rotate2,
+ font_alpha1, font_alpha2,
+ font_speed1, font_speed2,
+ font_x1, font_y1,
+ font_x2, font_y2;
+
+cairo_surface_t *bg_surface;
+int bg_width, bg_height;
+
+cairo_t *cr;
+
+void
+text_setup (cairo_t *_cr, int w, int h)
+{
+ int image_width, image_height;
+ char *image_data;
+ cairo_surface_t *image;
+
+ if (read_png ("orion.png", &image_data, &image_width, &image_height)) {
+ printf ("error reading orion.png\n");
+ exit(1);
+ }
+
+ bg_width = image_width;
+ bg_height = image_height;
+
+ image = cairo_image_surface_create_for_data (image_data,
+ CAIRO_FORMAT_ARGB32,
+ image_width, image_height,
+ image_width * 4);
+
+ bg_surface = cairo_surface_create_similar (cairo_get_target (_cr),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ image_width, image_height);
+
+ cr = cairo_create (bg_surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (cr, image, 0.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
+ free (image_data);
+
+ cr = _cr;
+
+ cairo_select_font_face (cr,
+ "arial",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size (cr, 1.0);
+
+ drand48 ();
+ drand48 ();
+
+ font_rotate1 = (float) (drand48 () * 3.14);
+ font_rotate2 = (float) (drand48 () * 3.14);
+ font_scale1 = (float) (drand48 () * 250.0);
+ font_scale2 = (float) (drand48 () * 250.0);
+ font_speed1 = (float) (drand48 () + 0.5);
+ font_speed2 = (float) (drand48 () + 0.5);
+ font_alpha1 = 0.0;
+ font_alpha2 = 0.0;
+ font_x1 = 200.0 + (float) (drand48 () * (w - 200.0));
+ font_y1 = 100.0 + (float) (drand48 () * (h - 100.0));
+ font_x2 = 200.0 + (float) (drand48 () * (w - 200.0));
+ font_y2 = 100.0 + (float) (drand48 () * (h - 100.0));
+}
+
+static void
+text_path_render_text1 (void)
+{
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, font_alpha1);
+
+ cairo_set_font_size (cr, font_scale1);
+
+ cairo_move_to (cr, font_x1 - font_scale1, font_y1);
+ cairo_rotate(cr, font_rotate1);
+ cairo_text_path (cr, "CAIRO");
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, 0.0, 1.0, 0.0, font_alpha1);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+static void
+text_path_render_text2 (void)
+{
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, font_alpha2);
+ cairo_set_font_size (cr, font_scale2);
+ cairo_move_to (cr, font_x2 - font_scale2, font_y2);
+ cairo_rotate(cr, font_rotate2);
+ cairo_text_path (cr, "GEARS");
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, 0.0, 1.0, 0.0, font_alpha2);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+void
+text_render (int w, int h)
+{
+ double scale_x, scale_y;
+
+ cairo_save (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_move_to (cr, 0, 0);
+
+ scale_x = ((double) w) / (double) bg_width;
+ scale_y = ((double) h) / (double) bg_height;
+
+ cairo_scale (cr, scale_x, scale_y);
+
+ cairo_set_source_surface (cr, bg_surface, 0.0, 0.0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ if (font_scale1 < font_scale2) {
+ text_path_render_text1 ();
+ text_path_render_text2 ();
+ } else {
+ text_path_render_text2 ();
+ text_path_render_text1 ();
+ }
+
+ if (font_scale1 > 250) {
+ font_scale1 = (float) (drand48 () * 50.0);
+ font_x1 = ((float) (drand48 () * (w - 400.0))) + 200.0;
+ font_y1 = ((float) (drand48 () * (h - 200.0))) + 100.0;
+ font_rotate1 = (float) (drand48 () * 3.14);
+ font_speed1 = (float) (drand48 () * 10.0);
+ font_alpha1 = 0;
+ }
+
+ if (font_scale2 > 250) {
+ font_scale2 = (float) (drand48 () * 50.0);
+ font_x2 = ((float) (drand48 () * (w - 400.0))) + 200.0;
+ font_y2 = ((float) (drand48 () * (h - 200.0))) + 100.0;
+ font_rotate2 = (float) (drand48 () * 3.14);
+ font_speed2 = (float) (drand48 () * 10.0);
+ font_alpha2 = 0;
+ }
+
+ font_scale1 > 150? font_scale1 += 2: font_scale1++;
+ font_scale2 > 150? font_scale2 += 2: font_scale2++;
+ font_scale1 < 175? (font_alpha1 += 0.01): (font_alpha1 -= 0.05);
+ font_scale2 < 175? (font_alpha2 += 0.01): (font_alpha2 -= 0.05);
+ font_scale1 += font_speed1;
+ font_scale2 += font_speed2;
+
+ cairo_restore (cr);
+}
diff --git a/examples/cairogears/trap.c b/examples/cairogears/trap.c
new file mode 100644
index 0000000..9cdab86
--- /dev/null
+++ b/examples/cairogears/trap.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * 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 names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON 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: David Reveman <c99drn@cs.umu.se>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#include <stdlib.h>
+
+#include <cairo.h>
+#include <math.h>
+
+#define LINEWIDTH 3.0
+
+#define FILL_R 0.1
+#define FILL_G 0.1
+#define FILL_B 0.75
+#define FILL_OPACITY 0.5
+
+#define STROKE_R 0.1
+#define STROKE_G 0.75
+#define STROKE_B 0.1
+#define STROKE_OPACITY 1.0
+
+#define NUMPTS 6
+
+double animpts[NUMPTS * 2];
+double deltas[NUMPTS * 2];
+
+cairo_t *cr;
+
+static void
+gear (double inner_radius,
+ double outer_radius,
+ int teeth,
+ double tooth_depth)
+{
+ int i;
+ double r0, r1, r2;
+ double angle, da;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth / 2.0;
+ r2 = outer_radius + tooth_depth / 2.0;
+
+ da = 2.0 * M_PI / (double) teeth / 4.0;
+
+ cairo_new_path (cr);
+
+ angle = 0.0;
+ cairo_move_to (cr, r1 * cos (angle + 3 * da), r1 * sin (angle + 3 * da));
+
+ for (i = 1; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / (double) teeth;
+
+ cairo_line_to (cr, r1 * cos (angle), r1 * sin (angle));
+ cairo_line_to (cr, r2 * cos (angle + da), r2 * sin (angle + da));
+ cairo_line_to (cr, r2 * cos (angle + 2 * da), r2 * sin (angle + 2 * da));
+
+ if (i < teeth)
+ cairo_line_to (cr, r1 * cos (angle + 3 * da),
+ r1 * sin (angle + 3 * da));
+ }
+
+ cairo_close_path (cr);
+
+ cairo_move_to (cr, r0 * cos (angle + 3 * da), r0 * sin (angle + 3 * da));
+
+ for (i = 1; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / (double) teeth;
+
+ cairo_line_to (cr, r0 * cos (angle), r0 * sin (angle));
+ }
+
+ cairo_close_path (cr);
+}
+
+void
+trap_setup (cairo_t *_cr, int w, int h)
+{
+ int i;
+
+ cr = cr;
+
+ //cairo_scale (cr, 3.0, 1.0);
+
+ for (i = 0; i < (NUMPTS * 2); i += 2) {
+ animpts[i + 0] = (float) (drand48 () * w);
+ animpts[i + 1] = (float) (drand48 () * h);
+ deltas[i + 0] = (float) (drand48 () * 6.0 + 4.0);
+ deltas[i + 1] = (float) (drand48 () * 6.0 + 4.0);
+ if (animpts[i + 0] > w / 2.0) {
+ deltas[i + 0] = -deltas[i + 0];
+ }
+ if (animpts[i + 1] > h / 2.0) {
+ deltas[i + 1] = -deltas[i + 1];
+ }
+ }
+}
+
+static void
+stroke_and_fill_animate (double *pts,
+ double *deltas,
+ int index,
+ int limit)
+{
+ double newpt = pts[index] + deltas[index];
+
+ if (newpt <= 0) {
+ newpt = -newpt;
+ deltas[index] = (double) (drand48 () * 4.0 + 2.0);
+ } else if (newpt >= (double) limit) {
+ newpt = 2.0 * limit - newpt;
+ deltas[index] = - (double) (drand48 () * 4.0 + 2.0);
+ }
+ pts[index] = newpt;
+}
+
+static void
+stroke_and_fill_step (int w, int h)
+{
+ int i;
+
+ for (i = 0; i < (NUMPTS * 2); i += 2) {
+ stroke_and_fill_animate (animpts, deltas, i + 0, w);
+ stroke_and_fill_animate (animpts, deltas, i + 1, h);
+ }
+}
+
+double gear1_rotation = 0.35;
+double gear2_rotation = 0.33;
+double gear3_rotation = 0.50;
+
+void
+trap_render (int w, int h, int fill_gradient)
+{
+ double *ctrlpts = animpts;
+ int len = (NUMPTS * 2);
+ double prevx = ctrlpts[len - 2];
+ double prevy = ctrlpts[len - 1];
+ double curx = ctrlpts[0];
+ double cury = ctrlpts[1];
+ double midx = (curx + prevx) / 2.0;
+ double midy = (cury + prevy) / 2.0;
+ int i;
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_rectangle (cr, 0, 0, w, h);
+ cairo_fill (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr, 0.75, 0.75, 0.75, 1.0);
+ cairo_set_line_width (cr, 1.0);
+
+ cairo_save (cr);
+ cairo_scale (cr, (double) w / 512.0, (double) h / 512.0);
+
+ cairo_save (cr);
+ cairo_translate (cr, 170.0, 330.0);
+ cairo_rotate (cr, gear1_rotation);
+ gear (30.0, 120.0, 20, 20.0);
+ cairo_set_source_rgb (cr, 0.75, 0.75, 0.75);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, 369.0, 330.0);
+ cairo_rotate (cr, gear2_rotation);
+ gear (15.0, 75.0, 12, 20.0);
+ cairo_set_source_rgb (cr, 0.75, 0.75, 0.75);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_translate (cr, 170.0, 116.0);
+ cairo_rotate (cr, gear3_rotation);
+ gear (20.0, 90.0, 14, 20.0);
+ cairo_set_source_rgb (cr, 0.75, 0.75, 0.75);
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgb (cr, 0.25, 0.25, 0.25);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ cairo_restore (cr);
+
+ gear1_rotation += 0.01;
+ gear2_rotation -= (0.01 * (20.0 / 12.0));
+ gear3_rotation -= (0.01 * (20.0 / 14.0));
+
+ stroke_and_fill_step (w, h);
+
+ cairo_new_path (cr);
+ cairo_move_to (cr, midx, midy);
+
+ for (i = 2; i <= (NUMPTS * 2); i += 2) {
+ double x2, x1 = (midx + curx) / 2.0;
+ double y2, y1 = (midy + cury) / 2.0;
+
+ prevx = curx;
+ prevy = cury;
+ if (i < (NUMPTS * 2)) {
+ curx = ctrlpts[i + 0];
+ cury = ctrlpts[i + 1];
+ } else {
+ curx = ctrlpts[0];
+ cury = ctrlpts[1];
+ }
+ midx = (curx + prevx) / 2.0;
+ midy = (cury + prevy) / 2.0;
+ x2 = (prevx + midx) / 2.0;
+ y2 = (prevy + midy) / 2.0;
+ cairo_curve_to (cr, x1, y1, x2, y2, midx, midy);
+ }
+ cairo_close_path (cr);
+
+ if (fill_gradient) {
+ double x1, y1, x2, y2;
+ cairo_pattern_t *pattern;
+
+ cairo_fill_extents (cr, &x1, &y1, &x2, &y2);
+
+ pattern = cairo_pattern_create_linear (x1, y1, x2, y2);
+ cairo_pattern_add_color_stop_rgb (pattern, 0.0, 1.0, 0.0, 0.0);
+ cairo_pattern_add_color_stop_rgb (pattern, 1.0, 0.0, 0.0, 1.0);
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_BILINEAR);
+
+ cairo_move_to (cr, 0, 0);
+ cairo_set_source (cr, pattern);
+ cairo_pattern_destroy (pattern);
+ } else {
+ cairo_set_source_rgba (cr, FILL_R, FILL_G, FILL_B, FILL_OPACITY);
+ }
+
+ cairo_fill_preserve (cr);
+ cairo_set_source_rgba (cr, STROKE_R, STROKE_G, STROKE_B, STROKE_OPACITY);
+ cairo_set_line_width (cr, LINEWIDTH);
+ cairo_stroke (cr);
+}