[cairo] Starting from something other than the origin of a source surface

Carl Worth cworth at cworth.org
Thu Oct 23 11:53:03 PDT 2008

On Thu, 2008-10-23 at 10:42 -0500, Matt Hoosier wrote:
> I have what feels like an obvious question, but I'm having trouble to
> locate the API that does what I want.

Hi Matt,

Hopefully we can help out with an easy answer, then.

> Suppose I have some arbitrary pre-drawn data in a cairo_surface_t. I
> want to blit some subrectangle not starting at the origin of this
> source surface, into the target cairo_t.
> The setup for this looks like:
>     /* pre-existing source image */
>     cairo_surface_t *source;
>     cairo_t *cr = ....; /* hook up to your window system */
>     /* Restrict size of paint to subrectangle requested */
>     cairo_rectangle(cr, dest_x, dest_y, width, height);
>     cairo_clip(cr);
>     cairo_set_source_surface(cr, source, dest_x, dest_y);
>     cairo_paint(cr);

Thank you for the very clear explanation of your problem. This is very

> But this always takes a subrectangle of source starting at (0, 0). It
> feels like I want to supply an extra X,Y pair to
> cairo_set_source_surface() that tells where in the source image to
> begin blitting. But the parameters allowed just affect the output
> translation.

You don't need an extra paint of coordinates at all---you just need to
use that coordinate the way you want to.

Your cairo_rectangle(cr, dest_x, dest_y, width, height) sets up the
rectangular region of the destination surface that you want to modify.
And that's working just fine, right?

Meanwhile, the coordinate passed to cairo_set_source_surface specifies
in user-space coordinates, (which in your case are identical to your
destination's device-space coordinates), where you would like the origin
of the source surface to appear. You're passing dest_x and dest_y again
which is why you're always seeing the source's (0,0) origin pixel at
dest_x, dest_y.

If you instead want a sub-rectangle starting at (source_x,source_y) then

	cairo_set_source_surface (cr, source,
				  dest_x - source_x,
				  dest_y - source_y);

This will put the surface's (0,0) at (dest_x-source_x,dest_y-source_y)
which in term means that the pixel drawn at (dest_x,dest_y) should come
from the surface at (source_x,source_y).

I hope that helps, (though explaining this in text rather than with a
picture definitely feels wrong).


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.cairographics.org/archives/cairo/attachments/20081023/ef631cba/attachment-0001.pgp 

More information about the cairo mailing list