3 xmlns="http://www.svgslides.org/svgslides0.1"
4 xmlns:svg="http://www.w3.org/2000/svg"
5 xmlns:xlink="http://www.w3.org/1999/xlink"
9 presentation="Drawing with cairo"
10 presentation-subtitle="drawing with cairo"
11 URL="http://cairographics.org"
14 <slide title="Tutorial preparation" variant="blank" bullet="">
16 <lc align="center">http://cairographics.org/tutorial</lc>
18 <li>wget http://cairographics.org/cairo-tutorial.tar.gz</li>
19 <li>tar xzf cairo-tutorial.tar.gz</li>
20 <li>cd cairo-tutorial</li>
24 <lc align="center">IRC: irc.freenode.net #cairo</lc>
27 <slide variant="title">
29 <lc>Red Hat, Inc.</lc>
31 <lc>linux.conf.au</lc>
33 <lc>http://cairographics.org</lc>
36 <slide title="Ugly graphics" variant="separator">
37 <lc align="left">Jaggies</lc>
38 <lc align="center">Fuzzies</lc>
39 <lc align="right">Fireworks</lc>
42 <slide title="Jaggies">
43 <img src="jaggies.svg"/>
46 <slide title="Fuzzies">
47 <img src="fuzzies.svg"/>
50 <slide title="Fireworks">
53 <slide title="What you can do about it">
54 <li>Let application authors know there are options</li>
55 <li>Learn to use cairo—patch the applications</li>
56 <li>Write your own cairo-using applications</li>
59 <slide title="Getting started" variant="separator">
60 <lc align="center">Various shell cairo programs</lc>
63 <slide title="Minimal cairo-xlib program" variant="code">
64 <lc>#include <cairo.h></lc>
65 <lc>#include <cairo-xlib.h></lc>
66 <lc>int main (void) {</lc>
67 <lc> Display *dpy = XOpenDisplay (0);</lc>
68 <lc> Window w = XCreateSimpleWindow (dpy,RootWindow (dpy, 0),</lc>
69 <lc> 0, 0, WIDTH, HEIGHT, 0, 0, WhitePixel (dpy, 0));</lc>
70 <lc> cairo_surface_t *surface = cairo_xlib_surface_create (dpy, w,</lc>
71 <lc> DefaultVisual (dpy, DefaultScreen (dpy)),</lc>
72 <lc> WIDTH, HEIGHT);</lc>
74 <lc> XSelectInput (dpy, w, ExposureMask);</lc>
75 <lc> XMapWindow (dpy, w);</lc>
76 <lc> while (XNextEvent (dpy, &ev) == 0)</lc>
77 <lc> if (ev.type == Expose && !ev.xexpose.count) {</lc>
78 <lc> cairo_t *cr = cairo_create (surface);</lc>
80 <lc> cairo_destroy (cr);</lc>
85 <slide title="Minimal cairo-gtk program" variant="code">
86 <lc>#include <gtk/gtk.h></lc>
87 <lc>static gboolean</lc>
88 <lc>handle_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data) {</lc>
89 <lc> cairo_t *cr = gdk_cairo_create (widget->window);</lc>
91 <lc> cairo_destroy (cr);</lc>
92 <lc> return FALSE;</lc>
94 <lc>int main (int argc, char **argv) {</lc>
95 <lc> GtkWidget *window, *drawing_area;</lc>
96 <lc> gtk_init (&argc, &argv);</lc>
97 <lc> window = gtk_window_new (GTK_WINDOW_TOPLEVEL);</lc>
98 <lc> gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);</lc>
99 <lc> drawing_area = gtk_drawing_area_new ();</lc>
100 <lc> gtk_container_add (GTK_CONTAINER (window), drawing_area);</lc>
101 <lc> g_signal_connect (drawing_area, "expose-event",</lc>
102 <lc> G_CALLBACK (handle_expose), NULL);</lc>
103 <lc> gtk_widget_show_all (window); gtk_main ();</lc>
107 <slide title="Minimal cairo-png program" variant="code">
108 <lc>#include <cairo.h></lc>
110 <lc>int main (void)</lc>
112 <lc> cairo_surface_t *surface;</lc>
113 <lc> cairo_t *cr;</lc>
115 <lc> surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,</lc>
116 <lc> WIDTH, HEIGHT);</lc>
117 <lc> cr = cairo_create (surface);</lc>
119 <lc> cairo_surface_write_to_png (surface, "foo.png");</lc>
121 <lc> cairo_surface_destroy (surface);</lc>
122 <lc> cairo_destroy (cr);</lc>
128 <slide title="Minimal cairo-pdf program" variant="code">
129 <lc>#include <cairo.h></lc>
130 <lc>#include <cairo-pdf.h></lc>
131 <lc>int main (void)</lc>
133 <lc> cairo_surface_t *surface;</lc>
134 <lc> cairo_t *cr;</lc>
136 <lc> surface = cairo_pdf_surface_create ("foo.pdf", WIDTH, HEIGHT);</lc>
138 <lc> cr = cairo_create (surface);</lc>
140 <lc> cairo_show_page (cr);</lc>
142 <lc> cairo_surface_destroy (surface);</lc>
143 <lc> cairo_destroy (cr);</lc>
149 <slide title="Minimal pycairo-gtk shell" variant="code">
150 <lc>#!/usr/bin/env python</lc>
152 <lc>import cairo</lc>
154 <lc>def expose (widget, event):</lc>
155 <lc> cr = widget.window.cairo_create ()</lc>
158 <lc>win = gtk.Window ()</lc>
159 <lc>win.connect ('destroy', gtk.main_quit)</lc>
160 <lc>win.set_default_size(WIDTH, HEIGHT)</lc>
161 <lc>drawingarea = gtk.DrawingArea ()</lc>
162 <lc>win.add (drawingarea)</lc>
163 <lc>drawingarea.connect ('expose_event', expose)</lc>
164 <lc>win.show_all ()</lc>
168 <slide title="Minimal pycairo-png shell" variant="code">
169 <lc>#!/usr/bin/env python</lc>
170 <lc>import cairo</lc>
172 <lc>surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, WIDTH, HEIGHT)</lc>
173 <lc>cr = cairo.Context (surface)</lc>
177 <lc>surface.write_to_png ('foo.png')</lc>
180 <slide title="Minimal nickle program" variant="code">
181 <lc>autoimport Cairo;</lc>
183 <lc>cairo_t cr = new (WIDTH, HEIGHT);</lc>
187 <slide title="Available bindings:" variant="large-content">
188 <li>C++ (cairomm)</li>
189 <li>Haskell (hscairo)</li>
190 <li>Java (CairoJava, cairo-java)</li>
191 <li>Common Lisp (cl-cairo)</li>
192 <li>Nickle (cairo-5c)</li>
193 <li>Objective Caml (cairo-ocaml)</li>
194 <li>perl (cairo-perl)</li>
195 <li>python (pycairo)</li>
196 <li>ruby (rcairo)</li>
197 <li>squeak (cairo-squeak)</li>
200 <slide title="Following along" >
202 <lc align="center">http://cairographics.org/tutorial</lc>
203 <lc align="center">http://cairographics.org/cairo-tutorial.tar.gz</lc>
204 <li>tar xzf cairo-tutorial.tar.gz</li>
205 <li>cd cairo-tutorial</li>
208 <lc align="center">IRC: irc.freenode.net #cairo</lc>
211 <slide title="Cairo's rendering model">
213 <image x="0" y="0" xlink:href="rendering-model.png" width="800" height="500" />
217 <slide title="Let's start drawing" variant="separator">
218 <lc align="center">Here comes the fun part</lc>
221 <slide title="API Overview" variant="large-content">
225 <li>construction</li>
226 <li>filling, stroking</li>
230 <li>loading from disk</li>
231 <li>using as source</li>
232 <li>transforming/filtering</li>
242 <slide title="Drawing functions" variant="large-content">
246 <li>cairo_stroke</li>
253 <li>cairo_paint_with_alpha</li>
257 <li>cairo_show_text (“toy”)</li>
258 <li>cairo_show_glyphs (“full”)</li>
263 <slide title="Basic path building">
265 <li>Paths consist of lines and splines:</li>
267 <li>cairo_move_to</li>
268 <lc> start new sub path, set current point</lc>
269 <li>cairo_line_to</li>
270 <lc> add line segment to path</lc>
271 <li>cairo_curve_to</li>
272 <lc> add Bézier spline to path</lc>
273 <li>cairo_close_path</li>
274 <lc> add line segment to last move_to point</lc>
279 <slide title="Stroking paths">
281 <li>cairo_stroke</li>
283 <li>Paints the path itself as stroked by a pen</li>
284 <li>Controlled by various stroke parameters:</li>
286 <li>cairo_set_line_width</li>
287 <li>cairo_set_line_cap</li>
288 <li>cairo_set_line_join</li>
289 <li>cairo_set_miter_limit</li>
290 <li>cairo_set_dash</li>
296 <slide title="cairo_stroke example">
299 <slide title="cairo_set_line_width">
302 <slide title="cairo_set_line_cap example">
304 <li>CAIRO_LINE_CAP_BUTT</li>
305 <li>CAIRO_LINE_CAP_ROUND</li>
306 <li>CAIRO_LINE_CAP_SQUARE</li>
310 <slide title="cairo_set_line_join example">
312 <li>CAIRO_LINE_JOIN_BEVEL</li>
313 <li>CAIRO_LINE_JOIN_ROUND</li>
314 <li>CAIRO_LINE_JOIN_MITER</li>
318 <slide title="cairo_close_path example">
319 <li>Adds a line segment (if necessary) to the</li>
320 <lc>start of the path</lc>
321 <li>Draws a join from that line to the first</li>
322 <lc>element of the path</lc>
325 <slide title="cairo_set_dash example">
328 <slide title="cairo_fill">
330 <li>Paints the “inside” of the path</li>
331 <li>Two different ways to determine inside-ness</li>
333 <li>cairo_set_fill_rule:</li>
334 <lc> CAIRO_FILL_RULE_WINDING</lc>
335 <lc> CAIRO_FILL_RULE_EVEN_ODD</lc>
340 <slide title="cairo_fill example">
343 <slide title="cairo_set_fill_rule">
344 <li>To test a point for inside-ness, imagine a ray</li>
345 <lc>from the point and extending to infinity</lc>
346 <lc>(any direction) and examine path crossings</lc>
347 <li>EVEN_ODD counts crossings and fills when odd</li>
348 <li>WINDING counts up/down for left/right crossings</li>
349 <lc>and fills when the final number is not zero</lc>
352 <slide title="Fill rule example">
355 <slide title="Something besides black?">
356 <li>All drawing occurs with the source pattern</li>
357 <li>Uniform-color sources can be set</li>
358 <lc>with or without alpha:</lc>
360 <li>cairo_set_source_rgb</li>
361 <li>cairo_set_source_rgba</li>
365 <slide title="cairo_set_source example">
368 <slide title="Fill and stroke the same path">
369 <li>cairo_stroke and cairo_fill consume the path</li>
370 <li>Variants are available to preserve the path:</li>
372 <li>cairo_stroke_preserve</li>
373 <li>cairo_fill_preserve</li>
375 <li>This is a variation from PostScript and PDF</li>
377 <li>The cairo approach differs in different ways</li>
378 <li>We think this way is better (of course)</li>
382 <slide title="Fill and stroke example">
385 <slide title="More path building">
387 <li>cairo_rectangle</li>
389 <li>cairo_text_path</li>
390 <li>cairo_glyph_path</li>
391 <li>Relative-coordinate variants:</li>
393 <li>cairo_rel_move_to</li>
394 <li>cairo_rel_line_to</li>
395 <li>cairo_rel_curve_to</li>
400 <slide title="cairo_arc example">
403 <slide title="Outline text">
406 <slide title="Affine Transformations">
408 <li>Single matrix combines rotation, translation,</li>
409 <lc>scale and shear</lc>
410 <li>Non-projective transformations</li>
412 <li>Pen doesn't change shape along the stroke</li>
414 <li>Transformations are cumulative</li>
416 <li>translate, scale != scale, translate</li>
421 <slide title="Affine Transform Example">
424 <slide title="Save/Restore Graphics States">
426 <li>cairo_save and cairo_restore</li>
427 <li>Very useful for bracketing function bodies</li>
428 <li>Eliminates graphics state side effects</li>
430 <li>NOTE: Path is not part of graphics state</li>
432 <li>Path is not affected by cairo_save/restore</li>
433 <li>Useful for path-generating functions</li>
438 <slide title="Clipping">
440 <li>Intersects path with current clip to further</li>
441 <lc>restrict drawing</lc>
442 <li>Pixel-aligned clipping is much faster</li>
443 <li>cairo_clip_preserve is available as well</li>
446 <slide title="Other source patterns">
448 <li>Surface patterns</li>
450 <li>Image from disk</li>
451 <li>Results of cairo drawing</li>
453 <li>Gradient patterns</li>
455 <li>linear gradients</li>
456 <li>radial gradients</li>
461 <slide title="Loading an image file">
464 <slide title="Painting an image">
467 <slide title="Pattern transformation">
470 <slide title="Pattern filtering">
473 <slide title="Linear gradient example">
476 <slide title="Radial gradient example">
483 <li>Useful for demos like we are writing today</li>
484 <li>No real layout—not useful for the majority</li>
485 <lc>of writing systems in the world</lc>
489 <li>User must do OS-dependent font selection</li>
490 <li>User must access font glyph IDs directly</li>
491 <li>User must do all text layout</li>
496 <slide title="“Toy” text API"/>
498 <li>Simple font selection</li>
500 <li>family, weight, slant</li>
501 <li>OS independent</li>
502 <li>No font listing support</li>
504 <li>UTF-8 text drawing and extents functions</li>
505 <li>Still supports full font transformations</li>
508 <slide title="“Toy” text example">
511 <slide title="“Real” text example">
512 <li>Just use pango</li>
515 <slide title="Error handling in C">
516 <li>C has no exceptions</li>
517 <li>Checking each return is tedious</li>
518 <li>C programmers rarely bother</li>
519 <li>Lots of broken programs result</li>
522 <slide title="Cairo error handling">
523 <li>Cairo stores status value when error occurs</li>
524 <li>API “shuts down” when an error occurs</li>
525 <li>All cairo functions are benign</li>
526 <lc>(and well defined) after any error.</lc>
527 <li>cairo_status can be called when convenient</li>
528 <li>Error status values propagate across objects</li>
531 <slide title="Cairo error example">