I'm working on a GtkDrawingArea which, in the expose event, is drawing a section of a pixbuf in a tiled manner. The tiling type varies - depending on the source image; it can be orthogonal, isometric or hexagonal. Drawing this with gdk_draw_pixmap is simple enough; here is an example on how it looks for isometric tiling:
for(y=0,row=0; y+tile_height<height; y+=tile_half_height,++row)
for(x=((row&1)? tile_half_width : 0); x+tile_width<width; x+=tile_width)
gdk_draw_pixbuf(widget->window,NULL,
pixbuf,src_x,src_y,
x,y,tile_width,tile_height,
GDK_RGB_DITHER_NONE,0,0);
Result:
However, drawing the same with Cairo proved to be quite not the same. This is what I have so far, which isn't working:
cairo_t *cr = gdk_cairo_create(widget->window);
gdk_cairo_set_source_pixbuf(cr,pixbuf,src_x,src_y);
for(y=0,row=0; y+tile_height<height; y+=tile_half_height,++row)
for(x=((row&1)? tile_half_width : 0); x+tile_width<width; x+=tile_width) {
cairo_rectangle(cr,x,y,tile_width,tile_height);
cairo_paint(cr);
}
}
cairo_destroy(cr);
Result:
Cairo simply refuses to draw the image as a normal raster image would be drawn. What am I doing wrong, how is this solved?
Untested, but might work. If not, then report back and I'll try again:
static void _cairo_gdk_draw_pixbuf(cairo_t *cr, cairo_surface_t *source,
int src_x, int src_y,
int dest_x, int dest_y,
int width, int height)
{
cairo_save(cr);
/* Move (0, 0) to the destination position */
cairo_translate(cr, dest_x, dest_y);
/* Set up the source surface in such a way that (src_x, src_y) maps to
* (0, 0) in user coordinates. */
cairo_set_source_surface(cr, source, -src_x, -src_y);
/* Do the drawing */
cairo_rectangle(cr, 0, 0, width, height);
cairo_fill(cr);
/* Undo all of our modifications to the drawing state */
cairo_restore(cr);
}
The above function should work like gdk_draw_pixbuf
(well, similar to it).