[cairo] create an image from window for printing

Fabian Förg fabian.foerg at gmx.de
Sat Jan 20 13:33:30 PST 2007


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);
> }
>
>
> static void draw_page(GtkPrintOperation * operation, GtkPrintContext * 
> print_context,
>              int page_nr, appl_t * appl)
> {
>    cairo_t *cr;
>    cairo_surface_t *surface;
>    gdouble print_width, print_height, scale_x, scale_y;
>    gint surface_width, surface_height;
>
>    /* transform the print_context into a cairo_context */
>    cr = gtk_print_context_get_cairo_context(print_context);
>
>    /* create a surface from cairo_context (the captured window) */
>    surface = cairo_get_target(appl->cairo_context);
>
>    /* prevent surface from being destroyed */
>    cairo_surface_reference(surface);
>
>    /* get width and heigth of print_context */
>    print_width = gtk_print_context_get_width(print_context);
>    print_height = gtk_print_context_get_height(print_context);
>
>    /* get width and height of surface */
>    surface_width = cairo_image_surface_get_width(surface);
>    surface_height = cairo_image_surface_get_height(surface);
>    g_print("\nsurface_width: %i\n", surface_width);
>
>    /* calculate the scale factors */
>    scale_x = (gdouble) print_width / surface_width;
>    scale_y = (gdouble) print_height / surface_height;
>    g_print("scale_x: %g\n", scale_x);
>
>    /* scale surface, so it fits the complete print_context */
>
>    /* set surface as source for cr */
>    cairo_set_source_surface(cr, surface, 0., 0.);
>
>    /* the cairo surface can be destroyed now */
>    cairo_surface_destroy(surface);
>
>    /* paint cr */
>    cairo_paint(cr);
> }
>
> g_print shows that surface_width is 0. Why?

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?

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


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

static void draw_page(GtkPrintOperation * operation,
              GtkPrintContext * print_context, int page_nr,
              appl_t * appl)
{
    cairo_t *cr;
    cairo_surface_t *surface;
    gdouble print_width, print_height, sx;
    gint surface_width, surface_height;

    /* transform the print_context into a cairo_context */
    cr = gtk_print_context_get_cairo_context(print_context);

    /* create a surface from cairo_context (the captured window) */
    surface = cairo_get_target(appl->cairo_context);

    /* prevent surface from being destroyed */
    cairo_surface_reference(surface);

    /* get width and heigth of print_context */
    print_width = gtk_print_context_get_width(print_context);
    print_height = gtk_print_context_get_height(print_context);

    /* get width and height of surface */
    surface_width = cairo_xlib_surface_get_width(surface);
    surface_height = cairo_xlib_surface_get_height(surface);

    if (((gdouble) surface_width / surface_height) >= 1.)
        sx = (gdouble) print_width / surface_width;
    else
        sx = (gdouble) print_height / surface_height;

    /* scale surface, so that it fits print_context */
    cairo_scale(cr, sx, sx);

    /* set surface as source for cr */
    cairo_set_source_surface(cr, surface, 0., 0.);

    /* the cairo surface can be destroyed now */
    cairo_surface_destroy(surface);

    /* paint cr */
    cairo_paint(cr);
}

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?

Regards,
Fabian


More information about the cairo mailing list