[cairo] fill pre-existing png polygons? (tried formatting better)

M Joonas Pihlaja jpihlaja at cc.helsinki.fi
Mon Aug 9 11:05:50 PDT 2010


On Mon, 9 Aug 2010, Daniel Goldman wrote:

> With GD, I would import a png outline of the map that has been generated before, 
> and use gdImageFill () to fill a polygon. With cairo, it's easy to get the 
> outline map in with cairo_image_surface_create_from_png (). But I'm getting the 
> feeling that is not a helpful step under cairo, that cairo does not fill 
> existing png polygons.

Right, cairo doesn't have the equivalent of gdImageFill().

> Can cairo fill polygons from a pre-existing png file? 

Sort of.  What you can do is have an image consisting of only an alpha 
channel containing 0.0 where you don't want colour and 1.0 where you 
do (and possibly values in between for antialiasing at the edges), and 
use cairo_mask() to "colour in" the pixels according to their alpha 
values.  Something like this, assuming you have a single polygon in 
the file "polygon123.png" which you want to appear at position 
(poly_x, poly_y):

  cairo_surface_t *poly_mask = cairo_image_surface_create_from_png("polygon123.png");
  cairo_set_source_rgb(cr, r,g,b);
  cairo_mask_surface(cr, poly_mask, poly_x, poly_y);
  cairo_surface_destroy(poly_mask);

However, there's a huge downside to this method!  Your pdf maps will 
actually contain prerasterised polygons rather than vector ones (which 
are scalable and can be zoomed into nicely etc.)

> Is it correct the GD model (import png outline map, fill existing 
> polygons) doesn't work under vector-based cairo? 

You're correct that you can't do that with cairo.

> Do I need to use cairo_move_to () and cairo_line_to () to create the 
> polygons in real-time before filling them?

This is the preferred way to make it work for both vector and raster 
backends.  If rendering is too slow, please let us know!

> My preference is to use the pre-existing outline, since it never 
> changes, but it would not be that big a deal to draw the map each 
> time.

Repeated rendering is best cached into a "similar surface" in cairo: 
you draw it once into a cached surface, and then copy from cached 
surface whenever you need to redraw the same content into your map.

Each backend can create a similar surface from another which retains 
the characteristic of the first.  The idea is that for instance the 
pdf backend can keep its vector drawings in vector form in the similar 
surface, whereas the image backend can rasterise the drawings just 
once.

Joonas


More information about the cairo mailing list