mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-20 19:50:10 +01:00
Add header/footer-less slide variant for slides needed an extra bit of space. Start getting slides ready for linux.conf.au 2006 tutorial, updating for cairo 1.0 API, and adding better organization. Verify and fix all the little example shell programs. Really remove the building of the -pdf programs this time.
528 lines
15 KiB
XML
528 lines
15 KiB
XML
<?xml version="1.0" ?>
|
|
<svgslides
|
|
xmlns="http://www.svgslides.org/svgslides0.1"
|
|
xmlns:svg="http://www.w3.org/2000/svg"
|
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
>
|
|
|
|
<slides theme="cairo"
|
|
presentation="How to Recognize Ugly Graphics"
|
|
presentation-subtitle="How to recognize ugly graphics—and what you can do about it."
|
|
URL="http://cairographics.org"
|
|
bullet="bullet">
|
|
|
|
<slide title="Tutorial Preparation" variant="blank" bullet="">
|
|
<lc></lc>
|
|
<lc align="center">http://cairographics.org/tutorial</lc>
|
|
<lc></lc>
|
|
<li>wget http://cairographics.org/tutorial.tar.gz</li>
|
|
<li>tar xzf tutorial.tar.gz</li>
|
|
<li>cd tutorial</li>
|
|
<li>make</li>
|
|
<lc></lc>
|
|
<lc align="center">IRC: irc.freenode.net #cairo</lc>
|
|
</slide>
|
|
|
|
<slide variant="title">
|
|
<lc>Carl Worth</lc>
|
|
<lc>Red Hat, Inc.</lc>
|
|
<lc></lc>
|
|
<lc>linux.conf.au</lc>
|
|
<lc>2006-01-26</lc>
|
|
<lc>http://cairographics.org</lc>
|
|
</slide>
|
|
|
|
<slide title="Ugly Graphics" variant="separator">
|
|
<lc align="left">Jaggies</lc>
|
|
<lc align="center">Fuzzies</lc>
|
|
<lc align="right">Fireworks</lc>
|
|
</slide>
|
|
|
|
<slide title="Jaggies">
|
|
<img src="jaggies.svg"/>
|
|
</slide>
|
|
|
|
<slide title="Fuzzies">
|
|
<img src="fuzzies.svg"/>
|
|
</slide>
|
|
|
|
<slide title="Fireworks">
|
|
</slide>
|
|
|
|
<slide title="What you can do about it">
|
|
<li>Let application authors know there are options</li>
|
|
<li>Learn to use cairo—patch the applications</li>
|
|
<li>Write your own cairo-using applications</li>
|
|
</slide>
|
|
|
|
<slide title="Getting Started" variant="separator">
|
|
<lc align="center">Various shell cairo programs</lc>
|
|
</slide>
|
|
|
|
<slide title="Minimal cairo-xlib program" variant="code">
|
|
<lc>#include <cairo.h></lc>
|
|
<lc>#include <cairo-xlib.h></lc>
|
|
<lc>int main (void) {</lc>
|
|
<lc> Display *dpy = XOpenDisplay (0);</lc>
|
|
<lc> Window w = XCreateSimpleWindow (dpy,RootWindow (dpy, 0),</lc>
|
|
<lc> 0, 0, WIDTH, HEIGHT, 0, 0, WhitePixel (dpy, 0));</lc>
|
|
<lc> cairo_surface_t *surface = cairo_xlib_surface_create (dpy, w,</lc>
|
|
<lc> DefaultVisual (dpy, DefaultScreen (dpy)),</lc>
|
|
<lc> WIDTH, HEIGHT);</lc>
|
|
<lc> XEvent ev;</lc>
|
|
<lc> XSelectInput (dpy, w, ExposureMask);</lc>
|
|
<lc> XMapWindow (dpy, w);</lc>
|
|
<lc> while (XNextEvent (dpy, &ev) == 0)</lc>
|
|
<lc> if (ev.type == Expose && !ev.xexpose.count) {</lc>
|
|
<lc> cairo_t *cr = cairo_create (surface);</lc>
|
|
<lc> draw (cr);</lc>
|
|
<lc> cairo_destroy (cr);</lc>
|
|
<lc> }</lc>
|
|
<lc>}</lc>
|
|
</slide>
|
|
|
|
<slide title="Minimal cairo-gtk program" variant="code">
|
|
<lc>#include <gtk/gtk.h></lc>
|
|
<lc>static gboolean</lc>
|
|
<lc>handle_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data) {</lc>
|
|
<lc> cairo_t *cr = gdk_cairo_create (widget->window);</lc>
|
|
<lc> draw (cr);</lc>
|
|
<lc> cairo_destroy (cr);</lc>
|
|
<lc> return FALSE;</lc>
|
|
<lc>}</lc>
|
|
<lc>int main (int argc, char **argv) {</lc>
|
|
<lc> GtkWidget *window, *drawing_area;</lc>
|
|
<lc> gtk_init (&argc, &argv);</lc>
|
|
<lc> window = gtk_window_new (GTK_WINDOW_TOPLEVEL);</lc>
|
|
<lc> gtk_window_set_default_size (GTK_WINDOW (window), WIDTH, HEIGHT);</lc>
|
|
<lc> drawing_area = gtk_drawing_area_new ();</lc>
|
|
<lc> gtk_container_add (GTK_CONTAINER (window), drawing_area);</lc>
|
|
<lc> g_signal_connect (drawing_area, "expose-event",</lc>
|
|
<lc> G_CALLBACK (handle_expose), NULL);</lc>
|
|
<lc> gtk_widget_show_all (window); gtk_main ();</lc>
|
|
<lc>}</lc>
|
|
</slide>
|
|
|
|
<slide title="Minimal cairo-png program" variant="code">
|
|
<lc>#include <cairo.h></lc>
|
|
<lc></lc>
|
|
<lc>int main (void)</lc>
|
|
<lc>{</lc>
|
|
<lc> cairo_surface_t *surface;</lc>
|
|
<lc> cairo_t *cr;</lc>
|
|
<lc></lc>
|
|
<lc> surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,</lc>
|
|
<lc> WIDTH, HEIGHT);</lc>
|
|
<lc> cr = cairo_create (surface);</lc>
|
|
<lc> draw (cr);</lc>
|
|
<lc> cairo_surface_write_to_png (surface, "foo.png");</lc>
|
|
<lc></lc>
|
|
<lc> cairo_surface_destroy (surface);</lc>
|
|
<lc> cairo_destroy (cr);</lc>
|
|
<lc></lc>
|
|
<lc> return 0;</lc>
|
|
<lc>}</lc>
|
|
</slide>
|
|
|
|
<slide title="Minimal cairo-pdf program" variant="code">
|
|
<lc>#include <cairo.h></lc>
|
|
<lc>#include <cairo-pdf.h></lc>
|
|
<lc>int main (void)</lc>
|
|
<lc>{</lc>
|
|
<lc> cairo_surface_t *surface;</lc>
|
|
<lc> cairo_t *cr;</lc>
|
|
<lc></lc>
|
|
<lc> surface = cairo_pdf_surface_create ("foo.pdf", WIDTH, HEIGHT);</lc>
|
|
<lc> </lc>
|
|
<lc> cr = cairo_create (surface);</lc>
|
|
<lc> draw (cr);</lc>
|
|
<lc> cairo_show_page (cr);</lc>
|
|
<lc></lc>
|
|
<lc> cairo_surface_destroy (surface);</lc>
|
|
<lc> cairo_destroy (cr);</lc>
|
|
<lc></lc>
|
|
<lc> return 0;</lc>
|
|
<lc>}</lc>
|
|
</slide>
|
|
|
|
<slide title="Minimal pycairo-gtk shell" variant="code">
|
|
<lc>#!/usr/bin/env python</lc>
|
|
<lc>import gtk</lc>
|
|
<lc>import cairo</lc>
|
|
<lc></lc>
|
|
<lc>def expose (widget, event):</lc>
|
|
<lc> cr = widget.window.cairo_create ()</lc>
|
|
<lc> draw (cr)</lc>
|
|
<lc> </lc>
|
|
<lc>win = gtk.Window ()</lc>
|
|
<lc>win.connect ('destroy', gtk.main_quit)</lc>
|
|
<lc>win.set_default_size(WIDTH, HEIGHT)</lc>
|
|
<lc>drawingarea = gtk.DrawingArea ()</lc>
|
|
<lc>win.add (drawingarea)</lc>
|
|
<lc>drawingarea.connect ('expose_event', expose)</lc>
|
|
<lc>win.show_all ()</lc>
|
|
<lc>gtk.main ()</lc>
|
|
</slide>
|
|
|
|
<slide title="Minimal pycairo-png shell" variant="code">
|
|
<lc>#!/usr/bin/env python</lc>
|
|
<lc>import cairo</lc>
|
|
<lc></lc>
|
|
<lc>surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, WIDTH, HEIGHT)</lc>
|
|
<lc>cr = cairo.Context (surface)</lc>
|
|
<lc></lc>
|
|
<lc>draw (cr)</lc>
|
|
<lc></lc>
|
|
<lc>surface.write_to_png ('foo.png')</lc>
|
|
</slide>
|
|
|
|
<slide title="Minimal nickle program" variant="code">
|
|
<lc>autoimport Cairo;</lc>
|
|
<lc></lc>
|
|
<lc>cairo_t cr = new (WIDTH, HEIGHT);</lc>
|
|
<lc>draw (cr);</lc>
|
|
</slide>
|
|
|
|
<slide title="Available bindings:" variant="large-content">
|
|
<li>C++ (cairomm)</li>
|
|
<li>Haskell (hscairo)</li>
|
|
<li>Java (CairoJava, cairo-java)</li>
|
|
<li>Common Lisp (cl-cairo)</li>
|
|
<li>Nickle (cairo-5c)</li>
|
|
<li>Objective Caml (cairo-ocaml)</li>
|
|
<li>perl (cairo-perl)</li>
|
|
<li>python (pycairo)</li>
|
|
<li>ruby (rcairo)</li>
|
|
<li>squeak (cairo-squeak)</li>
|
|
</slide>
|
|
|
|
<slide title="Following along" >
|
|
<lc></lc>
|
|
<lc align="center">http://cairographics.org/tutorial</lc>
|
|
<lc></lc>
|
|
<li>wget http://cairographics.org/tutorial.tar.gz</li>
|
|
<li>tar xzf tutorial.tar.gz</li>
|
|
<li>cd tutorial</li>
|
|
<li>make</li>
|
|
<lc></lc>
|
|
<lc align="center">IRC: irc.freenode.net #cairo</lc>
|
|
</slide>
|
|
|
|
<slide title="cairo's rendering model">
|
|
<g>
|
|
<image x="0" y="0" xlink:href="rendering-model.png" width="800" height="500" />
|
|
</g>
|
|
</slide>
|
|
|
|
<slide title="Let's start drawing" variant="separator">
|
|
<lc align="center">Here comes the fun part</lc>
|
|
</slide>
|
|
|
|
<slide title="API Overview" variant="large-content">
|
|
<ul>
|
|
<li>Paths</li>
|
|
<ul>
|
|
<li>construction</li>
|
|
<li>filling, stroking</li>
|
|
</ul>
|
|
<li>Images</li>
|
|
<ul>
|
|
<li>loading from disk</li>
|
|
<li>using as source</li>
|
|
<li>transforming/filtering</li>
|
|
</ul>
|
|
<li>Text</li>
|
|
<ul>
|
|
<li>“Toy” API</li>
|
|
<li>“Real” API</li>
|
|
</ul>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="Drawing functions" variant="large-content">
|
|
<ul>
|
|
<li>Paths</li>
|
|
<ul>
|
|
<li>cairo_stroke</li>
|
|
<li>cairo_fill</li>
|
|
</ul>
|
|
<li>Images</li>
|
|
<ul>
|
|
<li>cairo_paint</li>
|
|
<li>cairo_mask</li>
|
|
<li>cairo_paint_with_alpha</li>
|
|
</ul>
|
|
<li>Text</li>
|
|
<ul>
|
|
<li>cairo_show_text (“toy”)</li>
|
|
<li>cairo_show_glyphs (“real”)</li>
|
|
</ul>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="Paths">
|
|
<ul>
|
|
<li>Built from lines and splines.</li>
|
|
<ul>
|
|
<li>cairo_move_to() start new sub path and set current point</li>
|
|
<li>cairo_line_to() add line segment to path</li>
|
|
<li>cairo_curve_to() add Bézier spline to path</li>
|
|
<li>cairo_close_path() add line segment to last move_to point</li>
|
|
</ul>
|
|
<li>Can also be built from glyphs</li>
|
|
<ul>
|
|
<li>cairo_text_path() path from UTF-8 text</li>
|
|
<li>cairo_glyph_path() path from glyphs</li>
|
|
</ul>
|
|
<li>Not part of graphics state</li>
|
|
<ul>
|
|
<li>Path not affected by cairo_save()/cairo_restore()</li>
|
|
</ul>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="Using Paths">
|
|
<ul>
|
|
<li>Stroke or Fill</li>
|
|
<ul>
|
|
<li>cairo_stroke walks path with an elliptical pen</li>
|
|
<li>cairo_fill paints interior of path</li>
|
|
</ul>
|
|
<li>Clip</li>
|
|
<ul>
|
|
<li>cairo_clip intersects interior of path with current clip</li>
|
|
</ul>
|
|
<ul>
|
|
<li>These operations consume the path. Variants are available that preserve the path:</li>
|
|
<ul>
|
|
<li>cairo_stroke_preserve</li>
|
|
<li>cairo_fill_preserve</li>
|
|
<li>cairo_clip_preserve</li>
|
|
</ul>
|
|
</ul>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="Path Example">
|
|
</slide>
|
|
|
|
<slide title="Stroking Paths">
|
|
<ul>
|
|
<li>Elliptical pen (line width radius)</li>
|
|
<li>Join styles</li>
|
|
<ul>
|
|
<li>CAIRO_LINE_JOIN_MITER with limit</li>
|
|
<LI>CAIRO_LINE_JOIN_BEVEL</LI>
|
|
<li>CAIRO_LINE_JOIN_ROUND uses pen</li>
|
|
</ul>
|
|
<li>Cap styles</li>
|
|
<ul>
|
|
<LI>CAIRO_LINE_CAP_BUTT</LI>
|
|
<LI>CAIRO_LINE_CAP_ROUND</LI>
|
|
<LI>CAIRO_LINE_CAP_SQUARE</LI>
|
|
</ul>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="Stroke Example">
|
|
</slide>
|
|
|
|
<slide title="Closing the Path">
|
|
<li>cairo_close_path</li>
|
|
<li>Adds a line segment (if necessary) to the start of the path</li>
|
|
<li>ADraws a join from that line to the first element of the path</li>
|
|
</slide>
|
|
|
|
<slide title="Close Path Example">
|
|
</slide>
|
|
|
|
<slide title="Caps and Joins">
|
|
<ul>
|
|
<li>cairo_set_line_cap</li>
|
|
<ul>
|
|
<LI>CAIRO_LINE_CAP_BUTT</LI>
|
|
<LI>CAIRO_LINE_CAP_ROUND</LI>
|
|
<LI>CAIRO_LINE_CAP_SQUARE</LI>
|
|
</ul>
|
|
<li>cairo_set_line_join</li>
|
|
<ul>
|
|
<LI>CAIRO_LINE_JOIN_BEVEL</LI>
|
|
<LI>CAIRO_LINE_JOIN_ROUND</LI>
|
|
<LI>CAIRO_LINE_JOIN_MITER</LI>
|
|
</ul>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="Caps and Joins Setup">
|
|
</slide>
|
|
|
|
<slide title="Caps and Joins Example">
|
|
</slide>
|
|
|
|
<slide title="Filling Paths">
|
|
<ul>
|
|
<li>Closes path with line_to if necessary</li>
|
|
<ul>
|
|
<li>line drawn from current point to last move_to location</li>
|
|
</ul>
|
|
<li>Fills interior</li>
|
|
<li>Even/odd or winding fill rules</li>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="Fill Example">
|
|
</slide>
|
|
|
|
<slide title="Source color">
|
|
<li>cairo_set_source_rgb sets a solid color source</li>
|
|
<li>Source color is used for any drawing operation (stroke, fill, or</li>
|
|
<li>others)</li>
|
|
</slide>
|
|
|
|
<slide title="Fill and Stroke">
|
|
<li>cairo_stroke/fill_preserve preserve the path</li>
|
|
<li>Could just walk the figure twice</li>
|
|
</slide>
|
|
|
|
<slide title="Fill and Stroke Example">
|
|
</slide>
|
|
|
|
<slide title="Affine Transformations">
|
|
<ul>
|
|
<li>Single matrix combines rotation, translation, scale and shear</li>
|
|
<li>Non-projective transformations</li>
|
|
<ul>
|
|
<li>Pen doesn't change shape along the stroke</li>
|
|
</ul>
|
|
<li>Transformations are cumulative</li>
|
|
<ul>
|
|
<li>translate, scale != scale, translate</li>
|
|
</ul>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="Affine Transform Example">
|
|
</slide>
|
|
|
|
<slide title="Even/Odd vs Winding">
|
|
<li>Even/Odd counts edges, fills when odd</li>
|
|
<li>Winding counts up for clockwise edges, down for counterclockwise, fills when !zero</li>
|
|
</slide>
|
|
|
|
<slide title="Combining Images">
|
|
<li>Cairo memory surfaces are images</li>
|
|
<li>cairo_show_surface paints one surface into another</li>
|
|
<li>Transformed through matrix</li>
|
|
<li>No projective transforms yet</li>
|
|
</slide>
|
|
|
|
<slide title="Loading an Image File">
|
|
</slide>
|
|
|
|
<slide title="Image Example">
|
|
</slide>
|
|
|
|
<slide title="Image Transformation">
|
|
</slide>
|
|
|
|
<slide title="Resampling Modes">
|
|
<li>Nearest Neighbor</li>
|
|
</slide>
|
|
|
|
<slide title="Patterns">
|
|
<li>Apply one surface as pattern on another</li>
|
|
<li>Pattern transformed through source surface matrix</li>
|
|
<li>Patterns may repeat</li>
|
|
</slide>
|
|
|
|
<slide title="Pattern Example">
|
|
</slide>
|
|
|
|
<slide title="Pattern Transformations">
|
|
<ul>
|
|
<li>Source surface holds matrix</li>
|
|
<li>Constructed with matrix operations</li>
|
|
<li>Some thought to changing this API</li>
|
|
<ul>
|
|
<li>Need to add projective transformations</li>
|
|
<li>May want procedural patterns</li>
|
|
</ul>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="Pattern Transform">
|
|
</slide>
|
|
|
|
<slide title="Gradients">
|
|
<ul>
|
|
<li>No primitive gradients in cairo</li>
|
|
<ul>
|
|
<li>Implemented as patterns</li>
|
|
<li>Bilinear interpolation smooths result</li>
|
|
</ul>
|
|
<li>Future API may include more</li>
|
|
<ul>
|
|
<li>Procedural patterns</li>
|
|
<li>Triangular patches</li>
|
|
</ul>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="Gradient Setup">
|
|
</slide>
|
|
|
|
<slide title="Gradient Creation">
|
|
</slide>
|
|
|
|
<slide title="Gradient Example">
|
|
</slide>
|
|
|
|
<slide title="Text">
|
|
<ul>
|
|
<li>API is getting replaced</li>
|
|
<li>“Toy” API will be similar to current code</li>
|
|
<li>“Full” API will have</li>
|
|
<ul>
|
|
<li>OS dependent font selection</li>
|
|
<li>Use Glyph Ids instead of Unicode chars</li>
|
|
</ul>
|
|
<li>New implementation will provide device-independent fonts</li>
|
|
<li>Old API worked only on X</li>
|
|
</ul>
|
|
</slide>
|
|
|
|
<slide title="“Toy” Text API"/>
|
|
<ul>
|
|
<li>Simple font selection</li>
|
|
<ul>
|
|
<li>family, weight, slant</li>
|
|
<li>OS independent</li>
|
|
<li>No font listing support</li>
|
|
</ul>
|
|
<li>UTF-8 text drawing and extents functions</li>
|
|
<li>Still supports full font transformations</li>
|
|
</ul>
|
|
|
|
<slide title="“Toy” Text Example">
|
|
</slide>
|
|
|
|
<slide title="Error Handling in C">
|
|
<li>C has no exceptions</li>
|
|
<li>Checking each return is tedious</li>
|
|
<li>C programmers rarely bother</li>
|
|
<li>Lots of broken programs result</li>
|
|
</slide>
|
|
|
|
<slide title="Cairo Error Handling">
|
|
<li>Cairo returns status</li>
|
|
<li>Status is “persistant”</li>
|
|
<li>cairo_status function returns error state</li>
|
|
<li>API “shuts down” when an error occurs</li>
|
|
<li>All cairo functions are benign (and well defined) after any error.</li>
|
|
</slide>
|
|
|
|
<slide title="Cairo Error Example">
|
|
</slide>
|
|
|
|
</slides>
|
|
</svgslides>
|