From d49fa3d2bb3d051aa1a8fb5864f8bb60bc080da2 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 20 Nov 2008 14:35:18 +0100 Subject: [examples] Add cairogears. Add cairogears in examples, its a good test for cairo/glitz interactions. --- configure.in | 12 ++ examples/Makefile.am | 5 + examples/cairogears/Makefile.am | 35 ++++ examples/cairogears/bg.png | Bin 0 -> 191640 bytes examples/cairogears/cairogears-agl.c | 197 +++++++++++++++++ examples/cairogears/cairogears-glx.c | 370 ++++++++++++++++++++++++++++++++ examples/cairogears/cairogears.h | 57 +++++ examples/cairogears/common.c | 118 +++++++++++ examples/cairogears/comp.c | 179 ++++++++++++++++ examples/cairogears/desktop.png | Bin 0 -> 59793 bytes examples/cairogears/fakewin.png | Bin 0 -> 2557 bytes examples/cairogears/fdface.c | 87 ++++++++ examples/cairogears/fdface.h | 32 +++ examples/cairogears/fdhand.c | 136 ++++++++++++ examples/cairogears/fdhand.h | 33 +++ examples/cairogears/fdlogo.c | 173 +++++++++++++++ examples/cairogears/fdlogo.h | 33 +++ examples/cairogears/fg.png | Bin 0 -> 71226 bytes examples/cairogears/glider.png | Bin 0 -> 921 bytes examples/cairogears/orion.png | Bin 0 -> 286253 bytes examples/cairogears/read_png.c | 144 +++++++++++++ examples/cairogears/read_png.h | 6 + examples/cairogears/shadow.c | 396 +++++++++++++++++++++++++++++++++++ examples/cairogears/text.c | 191 +++++++++++++++++ examples/cairogears/trap.c | 264 +++++++++++++++++++++++ 25 files changed, 2468 insertions(+) create mode 100644 examples/cairogears/Makefile.am create mode 100644 examples/cairogears/bg.png create mode 100644 examples/cairogears/cairogears-agl.c create mode 100644 examples/cairogears/cairogears-glx.c create mode 100644 examples/cairogears/cairogears.h create mode 100644 examples/cairogears/common.c create mode 100644 examples/cairogears/comp.c create mode 100644 examples/cairogears/desktop.png create mode 100644 examples/cairogears/fakewin.png create mode 100644 examples/cairogears/fdface.c create mode 100644 examples/cairogears/fdface.h create mode 100644 examples/cairogears/fdhand.c create mode 100644 examples/cairogears/fdhand.h create mode 100644 examples/cairogears/fdlogo.c create mode 100644 examples/cairogears/fdlogo.h create mode 100644 examples/cairogears/fg.png create mode 100644 examples/cairogears/glider.png create mode 100644 examples/cairogears/orion.png create mode 100644 examples/cairogears/read_png.c create mode 100644 examples/cairogears/read_png.h create mode 100644 examples/cairogears/shadow.c create mode 100644 examples/cairogears/text.c create mode 100644 examples/cairogears/trap.c 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 Binary files /dev/null and b/examples/cairogears/bg.png 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 + * Peter Nilsson + */ + +#include "cairogears.h" +#include +#include + +#include +#include +#include +#include +#include +#include + +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 + * Peter Nilsson + */ + +#include "cairogears.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +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 +#include +#include + +#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 +#include +#include +#include +#include +#include + +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 + * Peter Nilsson + */ + +#include +#include +#include +#include + +#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 Binary files /dev/null and b/examples/cairogears/desktop.png differ diff --git a/examples/cairogears/fakewin.png b/examples/cairogears/fakewin.png new file mode 100644 index 0000000..a21fd94 Binary files /dev/null and b/examples/cairogears/fakewin.png 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 +#include +#include + +#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 + +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 +#include + +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 Binary files /dev/null and b/examples/cairogears/fg.png differ diff --git a/examples/cairogears/glider.png b/examples/cairogears/glider.png new file mode 100644 index 0000000..1569678 Binary files /dev/null and b/examples/cairogears/glider.png differ diff --git a/examples/cairogears/orion.png b/examples/cairogears/orion.png new file mode 100644 index 0000000..bce26c4 Binary files /dev/null and b/examples/cairogears/orion.png 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 +#include +#include +#include +#include + +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 + * Peter Nilsson + */ + +#include +#include +#include +#include + +#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 + * Peter Nilsson + */ + +#include +#include +#include +#include + +#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 + * Peter Nilsson + */ + +#include + +#include +#include + +#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); +} -- cgit v1.2.3