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
      • Simple API example
    • Built from lines and splines.
      • cairo_move_to() start new sub path and set current point
      • cairo_line_to() add line segment to path
      • cairo_curve_to() add Bézier spline to path
      • cairo_close_path() add line segment to last move_to point
    • Can also be built from glyphs
      • cairo_text_path() path from UTF-8 text
      • cairo_glyph_path() path from glyphs
    • Not part of graphics state
      • Path not affected by cairo_save()/cairo_restore()
    • Stroke or Fill
      • cairo_stroke walks path with an elliptical pen
      • cairo_fill paints interior of path
    • Clip
      • cairo_clip intersects interior of path with current clip
      • These operations consume the path. Variants are available that preserve the path:
        • cairo_stroke_preserve
        • cairo_fill_preserve
        • cairo_clip_preserve
    • 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
  • Adds a line segment (if necessary) to the start of the path
  • ADraws 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.