| ...-----=======-----... |
| 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: |
| |
| util/cairo-api-update |
| |
| 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 |
| ‘cairo_set_target_drawable_DEPRECATED_BY_cairo_xlib_surface_create’ |
| |
| 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 |
| instead. |
| |
| 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. |
| |
| cairo_create |
| ------------ |
| 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); |
| |
| cairo_show_surface |
| ------------------ |
| 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. |
| |
| cairo_matrix_t |
| -------------- |
| 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, |
| my_move_to, |
| my_line_to, |
| my_curve_to, |
| my_close_path, |
| closure); |
| |
| 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) { |
| case CAIRO_PATH_MOVE_TO: |
| my_move_to (closure, data[1].point.x, data[1].point.y); |
| break; |
| case CAIRO_PATH_LINE_TO: |
| my_line_to (closure, data[1].point.x, data[1].point.y); |
| break; |
| case CAIRO_PATH_CURVE_TO: |
| 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); |
| break; |
| case CAIRO_PATH_CLOSE_PATH: |
| my_close_path (closure); |
| break; |
| } |
| } |
| 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. |