blob: 7488173c46b237af77bbe390b7d52a10d2c2c3d0 [file] [log] [blame]
Cairo 1.0 Porting Guide
Here are some notes on more easily porting cairo_code from cairo 0.4
to cairo 1.0. It is sorted roughly in order of importance, (the items
near the top are expected to affect the most people).
Automated API renamings
There have been a lot of simple renamings where the functionality is
the same but the name of the symbol is different. We have provided a
script to automate the conversion of these symbols. It can be found
within the cairo distribution in:
This script is used by installing it somewhere on your PATH, and the
running it and providing the names of your source files on the command
line. For example:
cairo-api-update *.[ch]
The script will first save backup copies of each file (renamed with a
.bak extension) and then will perform all of the simple renamings.
For your benefit, the script also produces messages giving filenames
and line numbers for several of the manual API updates that you will
need to perform as described below.
Manual API changes
This section of the porting guide describes changes you will have to
manually make to your source code. In addition to the information in
this guide, the cairo-api-update script will notify you of some of
these issues as described above.
Cairo's deprecation warnings
Also, if your compiler provides warnings for implicit declarations of
functions, (eg. "gcc -Wall"), then simply attempting to compile your
program will cause cairo to generate messages intended to guide you
through the porting process.
For example, if you neglect to update an old call to
cairo_set_target_drawable, you might see an error message as follows:
foo.c:10: warning: implicit declaration of function
This message is indicating to you that the deprecatd function
cairo_set_target_drawable appears in your program foo.c on line 10,
and you should rewrite your program to call cairo_xlib_surface_create
The remainder of this porting guide is arranged as a set of common
code patterns that appear in old (cairo-0.4) code and how it should be
transformed to new (cairo-0.5) code.
Was: cr = cairo_create ();
cairo_set_target_foo (cr, args);
/* draw */
cairo_destroy (cr);
Now: cairo_surface_t *surface;
surface = cairo_foo_surface_create (args);
cr = cairo_create (surface);
/* draw */
cairo_destroy (cr);
cairo_surface_destroy (surface);
Or: cairo_surface_t *surface;
surface = cairo_foo_surface_create (args);
cr = cairo_create (surface);
cairo_surface_destroy (surface);
/* draw */
cairo_destroy (cr);
NOTE: Many of the cairo_foo_surface_create functions accept the
identical arguments as the the old cairo_set_target_foo
functions, (minus the cairo_t*), making this transformation
quite easy. One notable exception is cairo_set_target_drawable
which, when it becomes cairo_xlib_surface_create must pickup new
arguments for the Visual*, the width, and the height.
cairo_set_alpha (1)
Was: cairo_set_rgb_color (cr, red, green, blue);
cairo_set_alpha (cr, alpha);
Now: cairo_set_source_rgba (cr, red, green, blue, alpha);
Was: cairo_show_surface (cr, surface, width, height);
Now: cairo_set_source_surface (cr, surface, x, y);
cairo_paint (cr);
NOTE: The type signatures of cairo_show_surface and cairo_set_source
are the same, but pay attention that cairo_show_surface required
the width and height, while cairo_set_source_surface requires
the X,Y location to where the surface will be placed.
cairo_set_alpha (2)
Was: cairo_set_alpha (cr, alpha);
cairo_show_surface (cr, surface, width, height);
Now: cairo_set_source_surface (cr, surface, x, y);
cairo_paint_with_alpha (cr, alpha);
filling and stroking
Was: cairo_save (cr);
/* set fill color */
cairo_fiill (cr);
cairo_restore (cr);
/* set stroke color */
cairo_stroke (cr);
Now: /* set fill color */
cairo_fill_preserve (cr);
/* set stroke color */
cairo_stroke (cr);
NOTE: The current path is no longer saved/restored by
cairo_save/cairo_restore. This can lead to some subtle
surprises, so look out.
Was: cairo_matrix_t *matrix;
matrix = cairo_matrix_create ();
/* Do stuff with matrix */
cairo_matrix_destroy (matrix);
Now: cairo_matrix_t matrix;
cairo_matrix_init_identity (&matrix);
/* Do stuff with &matrix */
NOTE: If you are really lazy, you can still use a cairo_matrix_t* and
avoid putting the &matrix all over by just replacing
cairo_matrix_create() with malloc() and cairo_matrix_destroy()
with free(). That's not as nice, and you still need to be
careful to see if you need to initialize it to an identity
matrix as cairo_matrix_create() did for you.
Rendering to a temporary surface
Was: cairo_save (cr);
cairo_set_target_surface (cr, temporary);
/* draw through cr onto temporary */
cairo_restore (cr);
/* use temporary as source on cr */
Now: {
cr2 = cairo_create (temporary);
/* draw through cr2 onto temporary */
cairo_destory (cr2);
/* use temporary as source on cr */
NOTE: Having to create another cairo_t is a bit annoying, but having
to invent a new name for it is just awful, (imagine a deeply
nested version of this code). Fortunately, the style above is
just a stop-gap measure until the new group API comes along.
Iterating over a path
Was: cairo_current_path (cr,
Now: int i;
cairo_path_t *path;
cairo_path_data_t *data;
path = cairo_copy_path (cr);
for (i=0; i < path->num_data; i += path->data[i].header.length) {
data = &path->data[i];
switch (data->header.type) {
my_move_to (closure, data[1].point.x, data[1].point.y);
my_line_to (closure, data[1].point.x, data[1].point.y);
my_curve_to (closure, data[1].point.x, data[1].point.y,
data[2].point.x, data[2].point.y,
data[3].point.x, data[3].point.y);
my_close_path (closure);
cairo_path_destroy (path);
NOTE: This version makes it looks like the new form is a _lot_ more
verbose than the old version. But realize that the old version
required the support of 4 additional functions. The new approach
allows great flexibility including the ability to inline the
entire operation within the switch statement when appropriate.
Erasing a surface to transparent
Was: cairo_set_rgb_color (cr, 0., 0., 0.);
cairo_set_alpha (cr, 0.)
cairo_set_operator (cr, CAIRO_OPERATOR_SRC);
cairo_rectangle (cr, 0., 0., surface_width, surface_height);
cairo_fill (cr);
or: cairo_set_rgb_color (cr, 0., 0., 0.);
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_rectangle (cr, 0., 0., surface_width, surface_height);
cairo_fill (cr);
Now: cairo_set_source_rgba (cr, 0., 0., 0., 0.);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
or: cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_paint (cr);
NOTE: Using cairo_rectangle and fill would still work just fine. It's
just a lot more convenient to use cairo_paint now, (particularly
as it doesn't require you to even know what the bounds of the
target surface are).
Drawing to a PNG file
Was: file = fopen (filename, "w");
cr = cairo_create ();
cairo_set_target_png (cr, file, format, width, height);
/* draw image */
cairo_destroy (cr);
fclose (file);
Now: surface = cairo_image_surface_create (format, width, height);
cr = cairo_create (surface);
/* draw image */
cairo_surface_write_to_png (surface, filename);
cairo_destroy (cr);
cairo_surface_destroy (surface);
NOTE: The png backend is gone. So there is no cairo_png_surface_create
to take the place of cairo_set_target_png. And notice that we
used an image surface here, but it is just as easy to use
cairo_surface_write_to_png with an xlib or other surface, (but
not PDF at the moment). This is one of the big advantages of
this approach as opposed to a PNG surface.