[cairo] create an image from window for printing

Owen Taylor otaylor at redhat.com
Sat Jan 20 14:50:41 PST 2007


On Sat, 2007-01-20 at 22:33 +0100, Fabian Förg wrote:
> Fabian Förg wrote:
> > ("appl_t" is a private struct which contains "cairo_t *cairo_context;").
> >
> > void output(appl_t * appl)
> > {
> >    GtkWidget *window;
> >
> >    /* ... */
> >    /* this function creates the window which should be printed 
> > afterwards */
> >
> >    /* create a cairo_context of the screen */
> >    appl->cairo_context = gdk_cairo_create(window->window);
> >
[...]

>     surface_width = cairo_image_surface_get_width(surface);
> >    surface_height = cairo_image_surface_get_height(surface);
> >    g_print("\nsurface_width: %i\n", surface_width);

[...]

> I included <cairo/cairo-xlibs.h> and replaced 
> cairo_image_surface_get_width/height with 
> cairo_xlib_surface_get_width/height and now it works under UNIX.
> Windows has no xserver, so I can't use it there.
> How can I get the surface width and height under Windows?

Get the width and height of the window instead ... use
gdk_drawable_get_size(window);

> > [...]
> > - How can I change the background color of the captured window, i. e. 
> > change the theme/style of the window?
> This question remains unanswered.

Out of scope for this list... gtk_widget_modify_background() may or
may not be useful.

> 
> In order to scale the "screenshot", I changed the code to the following:

[...]

> Now it prints the screen scaled to the paper, but the margins are also 
> filled with the scaled screen.
> How can I get white margins?

So, say you have an surface of dimensions w0, h0, and you want to draw
it at x,y and size w,h 

 cairo_save(cr);
 cairo_move_to(cr, x, y);
 cairo_scale(cr, w/w0, h/h0);
 cairo_set_source_surface(cr, surface, 0, 0);
 cairo_paint(cr);

You really should study that until you realize that there is zero magic
in it; it's just a straightforward consequence of how cairo works.

So, say if you were drawing directly to a PDF surface, and you wanted to
paint it with the top left at 1cm, 1cm and with width of 10cm, then you
would do:

 #define POINTS_PER_CM (72. / 2.54);

 cairo_save(cr);
 cairo_move_to(cr, POINTS_PER_CM, POINTS_PER_CM);
 double scale = (10 * POINTS_PER_CM) / w0;
 cairo_scale(cr, scale, scale); /* Preserve aspect ratio */
 cairo_set_source_surface(cr, surface, 0, 0);
 cairo_paint(cr);

Regards,
				 	Owen




More information about the cairo mailing list