diff --git a/doc/tutorial/slides/.cvsignore b/doc/tutorial/slides/.cvsignore
new file mode 100644
index 000000000..02a98448c
--- /dev/null
+++ b/doc/tutorial/slides/.cvsignore
@@ -0,0 +1,7 @@
+tutorial-???.html
+tutorial-???.png
+tutorial-???.svg
+tutorial-index.xml
+tutorial.pdf
+index.html
+
diff --git a/doc/tutorial/slides/Makefile b/doc/tutorial/slides/Makefile
new file mode 100644
index 000000000..273cc3fb4
--- /dev/null
+++ b/doc/tutorial/slides/Makefile
@@ -0,0 +1,7 @@
+PROJ=tutorial
+
+all: ${PROJ}.xml
+ svgslides $^
+
+clean:
+ rm -f ${PROJ}-index.xml index.html ${PROJ}-???.html ${PROJ}-???.svg *~
diff --git a/doc/tutorial/slides/cairo-blank.svg b/doc/tutorial/slides/cairo-blank.svg
new file mode 100644
index 000000000..881198110
--- /dev/null
+++ b/doc/tutorial/slides/cairo-blank.svg
@@ -0,0 +1,487 @@
+
+
diff --git a/doc/tutorial/slides/cairo-code.svg b/doc/tutorial/slides/cairo-code.svg
new file mode 100644
index 000000000..297d4c742
--- /dev/null
+++ b/doc/tutorial/slides/cairo-code.svg
@@ -0,0 +1,508 @@
+
+
diff --git a/doc/tutorial/slides/cairo-separator.svg b/doc/tutorial/slides/cairo-separator.svg
new file mode 100644
index 000000000..4fe417643
--- /dev/null
+++ b/doc/tutorial/slides/cairo-separator.svg
@@ -0,0 +1,491 @@
+
+
diff --git a/doc/tutorial/slides/cairo-title.svg b/doc/tutorial/slides/cairo-title.svg
new file mode 100644
index 000000000..6e397e939
--- /dev/null
+++ b/doc/tutorial/slides/cairo-title.svg
@@ -0,0 +1,373 @@
+
+
diff --git a/doc/tutorial/slides/cairo.svg b/doc/tutorial/slides/cairo.svg
new file mode 100644
index 000000000..5a9449b76
--- /dev/null
+++ b/doc/tutorial/slides/cairo.svg
@@ -0,0 +1,508 @@
+
+
diff --git a/doc/tutorial/slides/circle-cairo-large.png b/doc/tutorial/slides/circle-cairo-large.png
new file mode 100644
index 000000000..a08e1193a
Binary files /dev/null and b/doc/tutorial/slides/circle-cairo-large.png differ
diff --git a/doc/tutorial/slides/circle-cairo.png b/doc/tutorial/slides/circle-cairo.png
new file mode 100644
index 000000000..f5d8cd438
Binary files /dev/null and b/doc/tutorial/slides/circle-cairo.png differ
diff --git a/doc/tutorial/slides/circle-ooo-large.png b/doc/tutorial/slides/circle-ooo-large.png
new file mode 100644
index 000000000..dfa40997f
Binary files /dev/null and b/doc/tutorial/slides/circle-ooo-large.png differ
diff --git a/doc/tutorial/slides/circle-ooo.png b/doc/tutorial/slides/circle-ooo.png
new file mode 100644
index 000000000..eb90666e6
Binary files /dev/null and b/doc/tutorial/slides/circle-ooo.png differ
diff --git a/doc/tutorial/slides/expander-fuzzy-large.png b/doc/tutorial/slides/expander-fuzzy-large.png
new file mode 100644
index 000000000..3a485da6a
Binary files /dev/null and b/doc/tutorial/slides/expander-fuzzy-large.png differ
diff --git a/doc/tutorial/slides/expander-fuzzy.png b/doc/tutorial/slides/expander-fuzzy.png
new file mode 100644
index 000000000..b01fd636e
Binary files /dev/null and b/doc/tutorial/slides/expander-fuzzy.png differ
diff --git a/doc/tutorial/slides/expander-sharp-large.png b/doc/tutorial/slides/expander-sharp-large.png
new file mode 100644
index 000000000..f97fa06a4
Binary files /dev/null and b/doc/tutorial/slides/expander-sharp-large.png differ
diff --git a/doc/tutorial/slides/expander-sharp.png b/doc/tutorial/slides/expander-sharp.png
new file mode 100644
index 000000000..40759aef7
Binary files /dev/null and b/doc/tutorial/slides/expander-sharp.png differ
diff --git a/doc/tutorial/slides/fuzzies.svg b/doc/tutorial/slides/fuzzies.svg
new file mode 100644
index 000000000..df12b8a71
--- /dev/null
+++ b/doc/tutorial/slides/fuzzies.svg
@@ -0,0 +1,11 @@
+
+
diff --git a/doc/tutorial/slides/jaggies.svg b/doc/tutorial/slides/jaggies.svg
new file mode 100644
index 000000000..e99d07ba5
--- /dev/null
+++ b/doc/tutorial/slides/jaggies.svg
@@ -0,0 +1,11 @@
+
+
diff --git a/doc/tutorial/slides/tutorial.xml b/doc/tutorial/slides/tutorial.xml
new file mode 100644
index 000000000..4b5248e0d
--- /dev/null
+++ b/doc/tutorial/slides/tutorial.xml
@@ -0,0 +1,468 @@
+
+
+
+
+
+
+
+ http://cairographics.org/tutorial
+
+ tar xzf tutorial.tar.gz
+ cd tutorial
+ make
+
+ IRC help: freenode.net #cairo
+
+
+
+ Carl Worth
+ Red Hat, Inc.
+
+ Ottawa Linux Symposium
+ 2005-07-22
+ http://cairographics.org
+
+
+
+ Jaggies
+ Fuzzies
+ Fireworks
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Various shell cairo program
+
+
+
+ #include <cairo.h>
+ #include <cairo-xlib.h>
+ int main (void) {
+ Display *dpy = XOpenDisplay (0);
+ Window w = XCreateSimpleWindow (dpy,RootWindow (dpy, 0),
+ 0, 0, WIDTH, HEIGHT, 0, 0, WhitePixel (dpy, 0));
+ cairo_surface_t *surface = cairo_xlib_surface_create (dpy, w,
+ DefaultVisual (dpy, DefaultScreen (dpy)),
+ WIDTH, HEIGHT);
+ XEvent ev;
+ XSelectInput (dpy, w, ExposureMask);
+ XMapWindow (dpy, w);
+ while (XNextEvent (dpy, &ev) == 0)
+ if (ev.type == Expose && !ev.xexpose.count) {
+ cairo_t *cr = cairo_create (surface);
+ draw (cr);
+ cairo_destroy (cr);
+ }
+ }
+
+
+
+ #include <gtk/gtk.h>
+ static gboolean
+ handle_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data) {
+ cairo_t *cr = gdk_cairo_create (widget->window);
+ draw (cr);
+ cairo_destroy (cr);
+ return FALSE;
+ }
+ int main (int argc, char **argv) {
+ GtkWidget *window, *drawing_area;
+ gtk_init (&argc, &argv);
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);
+ drawing_area = gtk_drawing_area_new ();
+ gtk_container_add (GTK_CONTAINER (window), drawing_area);
+ g_signal_connect (drawing_area, "expose-event",
+ G_CALLBACK (handle_expose), NULL);
+ gtk_widget_show_all (window);
+ gtk_main ();
+ }
+
+
+
+ #include <cairo.h>
+
+ int main (void)
+ {
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ WIDTH, HEIGHT);
+
+ cr = cairo_create (surface);
+ draw (cr);
+ cairo_surface_write_to_png (surface, "foo.png");
+
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+
+ return 0;
+ }
+
+
+
+ #include <cairo.h>
+ #include <cairo-pdf.h>
+
+ int main (void)
+ {
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_pdf_surface_create (foo.pdf, WIDTH, HEIGHT);
+
+ cr = cairo_create (surface);
+ draw (cr);
+ cairo_show_page (cr);
+
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+
+ return 0;
+ }
+
+
+
+ import gtk
+ import cairo
+ import cairo.gtk
+
+ def handle_expose (widget, event):
+ cr = cairo.gtk.gdk_cairo_create (widget.window)
+ draw (c)
+
+ win = gtk.Window ()
+ win.connect ('destroy', lambda x: gtk.main_quit ())
+ drawingarea = gtk.DrawingArea ()
+ win.add (drawingarea)
+ drawingarea.connect ('expose_event', handle_expose)
+ drawingarea.set_size_request (WIDTH, HEIGHT)
+ drawingarea.set_double_buffered (False)
+ win.show_all ()
+ gtk.main ()
+
+
+
+ import cairo
+
+ surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
+ cr = cairo.Context (surface)
+
+ draw (cr)
+
+ surface.write_to_png ('foo.png')
+
+
+
+ autoimport Cairo;
+
+ cairo_t cr = new (WIDTH, HEIGHT);
+ draw (cr);
+
+
+
+ Here comes the fun part
+
+
+
+
+ - Paths
+
+ - construction
+ - filling, stroking
+
+ - Images
+
+ - loading from disk
+ - transforming
+ - using as pattern
+
+ - Text
+
+
+
+
+
+
+ - Built from lines and splines.
+
+ - cairo_move_to() set current point
+ - cairo_line_to() draw line
+ - cairo_curve_to() draw Bézier spline
+ - cairo_close_path() draw line to start
+
+ - Can also be built from glyphs
+
+ - cairo_text_path() path from UTF-8
+ - cairo_glyph_path() path from glyphs
+
+ - Part of graphics state
+
+ - cairo_save()/cairo_restore() affect path
+
+
+
+
+
+
+ - Stroke or Fill
+
+ - cairo_stroke walks path outline with pen
+ - cairo_fill paints interior of path
+ - both operations consume the path, resetting the current path to empty
+
+ - Clip
+
+ - cairo_clip intersects interior of path with current clip
+
+ - Convert path to stroked version
+
+
+
+
+
+
+
+
+
+ - Elliptical pen (line width radius)
+ - Join styles
+
+ - CAIRO_LINE_JOIN_MITER with limit
+ - CAIRO_LINE_JOIN_BEVEL
+ - CAIRO_LINE_JOIN_ROUND uses pen
+
+ - Cap styles
+
+ - CAIRO_LINE_CAP_BUTT
+ - CAIRO_LINE_CAP_ROUND
+ - CAIRO_LINE_CAP_SQUARE
+
+
+
+
+
+
+
+
+ cairo_close_path
+ Draws a line (if necessary) to the start of the path
+ Draws a join from that line to the first element of the path
+
+
+
+
+
+
+
+ - cairo_set_line_cap
+
+ - CAIRO_LINE_CAP_BUTT
+ - CAIRO_LINE_CAP_ROUND
+ - CAIRO_LINE_CAP_SQUARE
+
+ - cairo_set_line_join
+
+ - CAIRO_LINE_JOIN_BEVEL
+ - CAIRO_LINE_JOIN_ROUND
+ - CAIRO_LINE_JOIN_MITER
+
+
+
+
+
+
+
+
+
+
+
+
+ - Closes path with line_to if necessary
+
+ - line drawn from current point to last move_to location
+
+ - Fills interior
+ - Even/odd or winding fill rules
+
+
+
+
+
+
+
+ cairo_set_source_rgb sets a solid color source
+ Source color is used for any drawing operation (stroke, fill, or
+ others)
+
+
+
+ cairo_stroke/fill_preserve preserve the path
+ Could just walk the figure twice
+
+
+
+
+
+
+
+ - Single matrix combines rotation, translation, scale and shear
+ - Non-projective transformations
+
+ - Pen doesn't change shape along the stroke
+
+ - Transformations are cumulative
+
+ - translate, scale != scale, translate
+
+
+
+
+
+
+
+
+ Even/Odd counts edges, fills when odd
+ Winding counts up for clockwise edges, down for counterclockwise, fills when !zero
+
+
+
+ Cairo memory surfaces are images
+ cairo_show_surface paints one surface into another
+ Transformed through matrix
+ No projective transforms yet
+
+
+
+
+
+
+
+
+
+
+
+
+ Nearest Neighbor
+
+
+
+ Apply one surface as pattern on another
+ Pattern transformed through source surface matrix
+ Patterns may repeat
+
+
+
+
+
+
+
+ - Source surface holds matrix
+ - Constructed with matrix operations
+ - Some thought to changing this API
+
+ - Need to add projective transformations
+ - May want procedural patterns
+
+
+
+
+
+
+
+
+
+ - No primitive gradients in cairo
+
+ - Implemented as patterns
+ - Bilinear interpolation smooths result
+
+ - Future API may include more
+
+ - Procedural patterns
+ - Triangular patches
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - API is getting replaced
+ - “Toy” API will be similar to current code
+ - “Full” API will have
+
+ - OS dependent font selection
+ - Use Glyph Ids instead of Unicode chars
+
+ - New implementation will provide device-independent fonts
+ - Old API worked only on X
+
+
+
+
+
+ - Simple font selection
+
+ - family, weight, slant
+ - OS independent
+ - No font listing support
+
+ - UTF-8 text drawing and extents functions
+ - Still supports full font transformations
+
+
+
+
+
+
+ C has no exceptions
+ Checking each return is tedious
+ C programmers rarely bother
+ Lots of broken programs result
+
+
+
+ Cairo returns status
+ Status is “persistant”
+ cairo_status function returns error state
+ API “shuts down” when an error occurs
+ All cairo functions are benign (and well defined) after any error.
+
+
+
+
+
+
+
diff --git a/doc/tutorial/src/.cvsignore b/doc/tutorial/src/.cvsignore
new file mode 100644
index 000000000..59488b844
--- /dev/null
+++ b/doc/tutorial/src/.cvsignore
@@ -0,0 +1,7 @@
+*-gtk
+*-pdf
+*-png
+*-xlib
+*.pdf
+*.png
+
diff --git a/doc/tutorial/src/Makefile b/doc/tutorial/src/Makefile
new file mode 100644
index 000000000..1d80f2c34
--- /dev/null
+++ b/doc/tutorial/src/Makefile
@@ -0,0 +1,30 @@
+MYCFLAGS=$(shell pkg-config --cflags --libs cairo gtk+-2.0) -Wall -g -Wpointer-arith -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -fno-strict-aliasing
+
+# If you don't want to/can't compile all of these targets, then trim
+# this list.
+all: gtk xlib pdf png
+
+GTK_EXAMPLES=$(patsubst %.c,%-gtk,$(wildcard *.c))
+gtk: $(GTK_EXAMPLES)
+%-gtk:%.c cairo-tutorial-gtk.h
+ $(CC) -DCAIRO_TUTORIAL_GTK $(CFLAGS) $(MYCFLAGS) -o $@ $<
+
+XLIB_EXAMPLES=$(patsubst %.c,%-xlib,$(wildcard *.c))
+xlib: $(XLIB_EXAMPLES)
+%-xlib:%.c cairo-tutorial-xlib.h
+ $(CC) -DCAIRO_TUTORIAL_XLIB $(CFLAGS) $(MYCFLAGS) -o $@ $<
+
+PDF_EXAMPLES=$(patsubst %.c,%-pdf,$(wildcard *.c))
+pdf: $(PDF_EXAMPLES)
+%-pdf:%.c cairo-tutorial-pdf.h
+ $(CC) -DCAIRO_TUTORIAL_PDF $(CFLAGS) $(MYCFLAGS) -o $@ $<
+
+PNG_EXAMPLES=$(patsubst %.c,%-png,$(wildcard *.c))
+png: $(PNG_EXAMPLES)
+%-png:%.c cairo-tutorial-png.h
+ $(CC) -DCAIRO_TUTORIAL_PNG $(CFLAGS) $(MYCFLAGS) -o $@ $<
+
+clean:
+ rm -f $(GTK_EXAMPLES) $(XLIB_EXAMPLES) $(PDF_EXAMPLES) $(PNG_EXAMPLES)
+
+.PHONY: all gtk xlib pdf png clean
diff --git a/doc/tutorial/src/cairo-tutorial-gtk.h b/doc/tutorial/src/cairo-tutorial-gtk.h
new file mode 100644
index 000000000..adb10a054
--- /dev/null
+++ b/doc/tutorial/src/cairo-tutorial-gtk.h
@@ -0,0 +1,116 @@
+/* cairo-tutorial-gtk.h - a tutorial framework for cairo with gtk+
+ *
+ * Copyright © 2005, Carl Worth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include
+#include
+
+#ifndef WIDTH
+#define WIDTH 400
+#endif
+
+#ifndef HEIGHT
+#define HEIGHT 400
+#endif
+
+static void
+draw (cairo_t *cr);
+
+#if ! GTK_CHECK_VERSION(2,7,0)
+/* copied from gtk+/gdk/gdkcairo.c and gtk+/gdk/x11/gdkdrawable-x11.c
+ * gdk_cairo_create() which is available in 2.7.0 and later.
+ */
+static cairo_t *
+gdk_cairo_create (GdkDrawable *drawable)
+{
+ int width, height;
+ cairo_t *cr = NULL;
+ cairo_surface_t *surface = NULL;
+ GdkVisual *visual = gdk_drawable_get_visual (drawable);
+
+ gdk_drawable_get_size (drawable, &width, &height);
+ if (visual)
+ surface = cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY (drawable),
+ GDK_DRAWABLE_XID (drawable),
+ GDK_VISUAL_XVISUAL (visual),
+ width, height);
+ else if (gdk_drawable_get_depth (drawable) == 1)
+ surface = cairo_xlib_surface_create_for_bitmap
+ (GDK_PIXMAP_XDISPLAY (drawable),
+ GDK_PIXMAP_XID (drawable),
+ GDK_SCREEN_XSCREEN (gdk_drawable_get_screen (drawable)),
+ width, height);
+ else {
+ g_warning ("Using Cairo rendering requires the drawable argument to\n"
+ "have a specified colormap. All windows have a colormap,\n"
+ "however, pixmaps only have colormap by default if they\n"
+ "were created with a non-NULL window argument. Otherwise\n"
+ "a colormap must be set on them with "
+ "gdk_drawable_set_colormap");
+ return NULL;
+ }
+ if (surface) {
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+ }
+ return cr;
+}
+#endif
+
+static gboolean
+handle_expose (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data)
+{
+ cairo_t *cr;
+
+ cr = gdk_cairo_create (widget->window);
+
+ draw (cr);
+
+ cairo_destroy (cr);
+
+ return FALSE;
+}
+
+int
+main (int argc, char **argv)
+{
+ GtkWidget *window, *drawing_area;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);
+ gtk_window_set_title (GTK_WINDOW (window), "cairo demo");
+
+ g_signal_connect (window, "destroy-event",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ drawing_area = gtk_drawing_area_new ();
+ gtk_container_add (GTK_CONTAINER (window), drawing_area);
+
+ g_signal_connect (drawing_area, "expose-event",
+ G_CALLBACK (handle_expose), NULL);
+
+ gtk_widget_show_all (window);
+
+ gtk_main ();
+
+ return 0;
+}
diff --git a/doc/tutorial/src/cairo-tutorial-pdf.h b/doc/tutorial/src/cairo-tutorial-pdf.h
new file mode 100644
index 000000000..563ea763e
--- /dev/null
+++ b/doc/tutorial/src/cairo-tutorial-pdf.h
@@ -0,0 +1,74 @@
+/* cairo-tutorial-png.h - a tutorial framework for cairo to write a PNG image
+ *
+ * Copyright © 2005, Carl Worth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#ifndef WIDTH
+#define WIDTH 400
+#endif
+
+#ifndef HEIGHT
+#define HEIGHT 400
+#endif
+
+static void
+draw (cairo_t *cr);
+
+int
+main (int argc, char **argv)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ char *filename, *dash;
+
+ filename = strdup (argv[0]);
+ assert (filename != NULL);
+
+ dash = strrchr (filename, '-');
+
+ if (strcmp (dash, "-pdf") == 0) {
+ *dash = '.';
+ } else {
+ char *new_filename;
+ new_filename = malloc (strlen (filename) + 5);
+ sprintf (new_filename, "%s.pdf", filename);
+ free (filename);
+ filename = new_filename;
+ }
+
+ surface = cairo_pdf_surface_create (filename, WIDTH, HEIGHT);
+
+ cr = cairo_create (surface);
+
+ draw (cr);
+
+ cairo_show_page (cr);
+
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+
+ free (filename);
+
+ return 0;
+}
diff --git a/doc/tutorial/src/cairo-tutorial-png.h b/doc/tutorial/src/cairo-tutorial-png.h
new file mode 100644
index 000000000..a6800c8b7
--- /dev/null
+++ b/doc/tutorial/src/cairo-tutorial-png.h
@@ -0,0 +1,74 @@
+/* cairo-tutorial-png.h - a tutorial framework for cairo to write a PNG image
+ *
+ * Copyright © 2005, Carl Worth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+#ifndef WIDTH
+#define WIDTH 400
+#endif
+
+#ifndef HEIGHT
+#define HEIGHT 400
+#endif
+
+static void
+draw (cairo_t *cr);
+
+int
+main (int argc, char **argv)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ char *filename, *dash;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ WIDTH, HEIGHT);
+
+ cr = cairo_create (surface);
+
+ draw (cr);
+
+ filename = strdup (argv[0]);
+ assert (filename != NULL);
+
+ dash = strrchr (filename, '-');
+
+ if (strcmp (dash, "-png") == 0) {
+ *dash = '.';
+ } else {
+ char *new_filename;
+ new_filename = malloc (strlen (filename) + 5);
+ sprintf (new_filename, "%s.png", filename);
+ free (filename);
+ filename = new_filename;
+ }
+
+ cairo_surface_write_to_png (surface, filename);
+
+ free (filename);
+
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+
+ return 0;
+}
diff --git a/doc/tutorial/src/cairo-tutorial-xlib.h b/doc/tutorial/src/cairo-tutorial-xlib.h
new file mode 100644
index 000000000..301b9524c
--- /dev/null
+++ b/doc/tutorial/src/cairo-tutorial-xlib.h
@@ -0,0 +1,219 @@
+/* cairo-tutorial-xlib.h - a tutorial framework for cairo with xlib
+ *
+ * Copyright © 2005, Keith Packard
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifndef WIDTH
+#define WIDTH 400
+#endif
+
+#ifndef HEIGHT
+#define HEIGHT 400
+#endif
+
+#ifndef DEFAULT_VISUAL
+#define DEFAULT_VISUAL 0
+#endif
+
+static void
+Usage (char *program)
+{
+ fprintf (stderr, "Usage: %s\n", program);
+ fprintf (stderr, "\t-display \n");
+ fprintf (stderr, "\t-geometry \n");
+ exit (1);
+}
+
+char *dpy_name;
+VisualID vid = DEFAULT_VISUAL;
+Colormap colormap;
+Visual *visual;
+int depth;
+unsigned int width = WIDTH, height = HEIGHT;
+
+static void
+draw (cairo_t *cr);
+
+static void
+handle_expose (Display *dpy, Drawable d)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_xlib_surface_create (dpy, d, visual,
+ width, height);
+ cr = cairo_create (surface);
+
+ draw (cr);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+}
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ Display *dpy;
+ Window win;
+ Window root = 0;
+ char **init_argv = argv;
+ XSetWindowAttributes attr;
+ int scr;
+ int x = 0, y = 0;
+ int geometryMask;
+ int border_width = 1;
+ XSizeHints sizeHints;
+ XWMHints wmHints;
+ XClassHint classHints;
+ XEvent ev;
+ XEvent eev;
+ int HasExpose = 0;
+ int sync = 0;
+ XTextProperty wm_name, icon_name;
+ Atom wm_delete_window;
+ unsigned long gc_mask;
+ char quit_string[10];
+ unsigned long window_mask;
+ int has_colormap = 0;
+
+ wm_name.value = (unsigned char *) argv[0];
+ wm_name.encoding = XA_STRING;
+ wm_name.format = 8;
+ wm_name.nitems = strlen (argv[0]) + 1;
+ icon_name = wm_name;
+ gc_mask = 0;
+ while (*++argv) {
+ if (!strcmp (*argv, "-display"))
+ dpy_name = *++argv;
+ else if (!strcmp (*argv, "-visual"))
+ vid = strtol(*++argv, NULL, 0);
+ else if (!strcmp (*argv, "-geometry"))
+ geometryMask = XParseGeometry (*++argv, &x, &y, &width, &height);
+ else if (!strcmp (*argv, "-sync"))
+ sync = 1;
+ else if (!strcmp (*argv, "-bw"))
+ border_width = strtol(*++argv, NULL, 0);
+ else if (!strcmp (*argv, "-root"))
+ root = strtol (*++argv, NULL, 0);
+ else
+ Usage (*init_argv);
+ }
+ sizeHints.flags = 0;
+ wmHints.flags = InputHint;
+ wmHints.input = True;
+ classHints.res_name = init_argv[0];
+ classHints.res_class = init_argv[0];
+ dpy = XOpenDisplay (dpy_name);
+ if (!dpy) {
+ fprintf (stderr, "Error: failed to open display: %s\n",
+ XDisplayName (dpy_name));
+ exit (1);
+ }
+ if (sync)
+ XSynchronize (dpy, sync);
+ scr = DefaultScreen (dpy);
+ if (!root)
+ root = RootWindow (dpy, scr);
+ window_mask = CWBackPixel|CWBorderPixel|CWEventMask;
+ if (!has_colormap)
+ colormap = DefaultColormap (dpy, scr);
+ else
+ {
+ window_mask |= CWColormap;
+ attr.colormap = colormap;
+ }
+ visual = DefaultVisual (dpy, scr);
+ depth = DefaultDepth (dpy, scr);
+ if (vid)
+ {
+ XVisualInfo vi, *vi_ret;
+ int n;
+
+ vi.visualid = vid;
+ vi.screen = scr;
+ vi_ret = XGetVisualInfo (dpy, VisualIDMask|VisualScreenMask,
+ &vi, &n);
+ if (vi_ret)
+ {
+ visual = vi_ret->visual;
+ if (!has_colormap)
+ {
+ colormap = XCreateColormap (dpy, root, visual, AllocNone);
+ window_mask |= CWColormap;
+ attr.colormap = colormap;
+ }
+ depth = vi_ret->depth;
+ }
+ }
+ attr.background_pixel = WhitePixel (dpy, scr);
+ attr.border_pixel = 0;
+ attr.event_mask = ExposureMask|KeyPressMask|KeyReleaseMask;
+ wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+ win = XCreateWindow (dpy, root, x, y, width, height, border_width,
+ depth, InputOutput,
+ visual,
+ window_mask,
+ &attr);
+ XSetWMProperties (dpy, win,
+ &wm_name, &icon_name,
+ init_argv, argc,
+ &sizeHints, &wmHints, 0);
+ XSetWMProtocols (dpy, win, &wm_delete_window, 1);
+ XMapWindow (dpy, win);
+ for (;;) {
+ XNextEvent (dpy, &ev);
+ if (HasExpose && ev.type != Expose) {
+ HasExpose = 0;
+ handle_expose (dpy, eev.xexpose.window);
+ }
+ switch (ev.type) {
+ case Expose:
+ if (QLength(dpy)) {
+ eev = ev;
+ HasExpose = 1;
+ } else if (ev.xexpose.count == 0) {
+ handle_expose (dpy, ev.xexpose.window);
+ }
+ break;
+ case KeyPress:
+ if (XLookupString ((XKeyEvent *) &ev, quit_string, sizeof (quit_string), 0, 0) == 1) {
+ switch (quit_string[0]) {
+ case 'q':
+ exit (0);
+ case 'c':
+ XClearArea (dpy, ev.xkey.window, 0, 0, 0, 0, True);
+ break;
+ }
+ }
+ break;
+ case ClientMessage:
+ exit (0);
+ }
+ }
+}
diff --git a/doc/tutorial/src/cairo-tutorial.h b/doc/tutorial/src/cairo-tutorial.h
new file mode 100644
index 000000000..65a431afe
--- /dev/null
+++ b/doc/tutorial/src/cairo-tutorial.h
@@ -0,0 +1,41 @@
+/* cairo-tutorial-gtk.h - a tutorial framework for cairo
+ *
+ * Copyright © 2005, Carl Worth
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include
+#include
+
+/* The application program may override these before including
+ * cairo-tutorial.h in order to get a window of a different size. */
+#ifndef WIDTH
+#define WIDTH 400
+#endif
+
+#ifndef HEIGHT
+#define HEIGHT 400
+#endif
+
+#ifdef CAIRO_TUTORIAL_GTK
+#include "cairo-tutorial-gtk.h"
+#elif CAIRO_TUTORIAL_XLIB
+#include "cairo-tutorial-xlib.h"
+#elif CAIRO_TUTORIAL_PDF
+#include "cairo-tutorial-pdf.h"
+#elif CAIRO_TUTORIAL_PNG
+#include "cairo-tutorial-png.h"
+#endif
+
diff --git a/doc/tutorial/src/circle.c b/doc/tutorial/src/circle.c
new file mode 100644
index 000000000..06ca8fc9b
--- /dev/null
+++ b/doc/tutorial/src/circle.c
@@ -0,0 +1,22 @@
+#define WIDTH 50
+#define HEIGHT 50
+
+#include "cairo-tutorial.h"
+
+static void
+draw (cairo_t *cr)
+{
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_move_to (cr, 47.5, 25);
+ cairo_arc (cr, 25, 25, 22.5,
+ 0.0, 2 * M_PI);
+
+ cairo_set_source_rgb (cr, 0.6, 0.8, 1.0);
+ cairo_fill_preserve (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ cairo_set_line_width (cr, 1.0);
+ cairo_stroke (cr);
+}
diff --git a/doc/tutorial/src/expander.c b/doc/tutorial/src/expander.c
new file mode 100644
index 000000000..a00865fbd
--- /dev/null
+++ b/doc/tutorial/src/expander.c
@@ -0,0 +1,16 @@
+#define WIDTH 50
+#define HEIGHT 50
+
+#include "cairo-tutorial.h"
+
+static void
+draw (cairo_t *cr)
+{
+ cairo_translate (cr, 24.5, 25);
+ cairo_move_to (cr, 5, -2.5);
+ cairo_line_to (cr, 0, 2.5);
+ cairo_line_to (cr, -5, -2.5);
+ cairo_close_path (cr);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+}