[cairo] How can I scale a calro surface
Owen Taylor
otaylor at redhat.com
Tue Jan 24 09:28:08 PST 2006
On Tue, 2006-01-24 at 10:46 -0600, Meryl Silverburgh wrote:
> How can I scale a calro surface?
>
> I have the following code, but it does not work (does not scale):
> cairo_t* cr = cairo_create(tmpSurf);
>
> double scale = 0.5;
>
> cairo_scale (cr, scale, scale);
>
> cairo_surface_write_to_png(tmpSurf, "tmpSurf.png");
>
> Can you please tell me why it does not work?
Jonathan's answer tells you why the above doesn't work, but it is
actually a fairly subtle how to do it correctly. (I think
explaining the following would make a good section for the docs.)
cairo_surface_t *
scale_surface (cairo_surface_t *old_surface,
int old_width, int old_height,
int new_width, int_new_height
{
cairo_surface_t *new _surface = cairo_surface_create_similar(old_surface, new_width, new_height);
cairo_t *cr = cairo_create (new_surface);
/* Scale *before* setting the source surface (1) */
cairo_scale (cr, (double)new_width / old_width, (double)new_height / old_height);
cairo_set_source_surface (cr, old_surface, 0, 0);
/* To avoid getting the edge pixels blended with 0 alpha, which would
* occur with the default EXTEND_NONE. Use EXTEND_PAD for 1.2 or newer (2)
*/
cairo_pattern_set_extend (cairo_get_source(cr), CAIRO_EXTEND_REFLECT);
/* Replace the destination with the source instead of overlaying */
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
/* Do the actual drawing */
cairo_paint (cr);
cairo_destroy (cr);
return new_surface;
}
[Untested code warning].
Regards,
Owen
(1) I'm pretty sure we implemented locking for the pattern transform
like this but I may be misremembering.
(2) Calling get_source() and modifying the implicit source create by
set_source_surface() is a little hacky, but I think we consider
it legitimate, and it saves a bunch of typing.
More information about the cairo
mailing list