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

Matt Hoosier matt.hoosier at gmail.com
Thu Oct 23 14:05:25 PDT 2008


On Thu, Oct 23, 2008 at 1:53 PM, Carl Worth <cworth at cworth.org> wrote:

> > 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
> helpful.
>
> > 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?


Yes.

>
>
> 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
> try:
>
>        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).


Yeah, I think I get the idea. We're just sliding the surfaces around w.r.t.
each other by stipulating that final coordinate pair. I didn't realize it
was legitimate to give values outside of Quadrant IV.

Your suggestion works. Now that your explanation makes it obvious to me that
the coordinate pair accepted by cairo_set_source_surface() is just getting
stuck onto the translation matrix, I ended up doing this instead just
because the two separated operations make it a little clearer to me what's
happening:

    cairo_translate(cr, dst_x, dst_y);
    cairo_set_source_surface(cr, source, -src_x, -src_y);

Thanks for the help!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cairographics.org/archives/cairo/attachments/20081023/2f1d0e3a/attachment.htm 


More information about the cairo mailing list