[cairo] create an image from window for printing
Fabian Förg
fabian.foerg at gmx.de
Sat Jan 20 08:25:29 PST 2007
Kalle Vahlman wrote:
> 2007/1/19, Fabian Förg <fabian.foerg at gmx.de>:
>> Hello,
>>
>> is it possible to capture a gtk-window, save it as an image file and use
>> that file for printing with cairo?
>> At first, I tried this:
>> pixmap = gdk_pixmap_new(window->window, window->allocation.width,
>> window->allocation.height, -1);
>> This should save the window as a pixmap.
>
> Actually it doesn't. It just creates a pixmap that has the same depth
> that the gdkwindow does. The content of that pixmap is undefined at
> that point, if I'm not mistaken.
Thank you for the hint.
>> In order to print it, I tried gdk_cairo_set_source_pixbuf, but the
>> function requires a pixbuf as an argument.
>> How can I convert the pixmap to a pixbuf and is my approach alright?
>
> First, you can get a pixbuf directly from the window with the function
>
> gdk_pixbuf_get_from_drawable()
>
> Secondly, I haven't tried the printing code of Gtk+ yet myself
> (assuming that is what you are using), but I gather from these
> questions and the API docs that it offers you a cairo context to which
> you draw your stuff for printing.
Yes, I use the Gtk+ printing API, and it offers me a GtkPrintContext.
>
> So rather than converting the window to a pixbuf in between, you are
> probably better off geting a cairo surface for the window and simply
> painting that to the context you get from the printing system. The Gdk
> Cairo helpers don't offer it directly, but you can get it by aquiring
> the context and asking the target surface from it:
>
> cairo_context = gdk_cairo_create(window->window);
> surface = cairo_get_target(cairo_context);
>
> and then you can set the surface as the source for the printing context:
>
> cairo_set_source_surface (printing_context, surface);
>
> and do whatever transforms and tricks you want to with it (fitting it
> to the page size or such) before painting it to the surface.
>
> Cheers,
>
Thanks for your suggestions. I tried the following:
("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?
Moreover, I have these questions:
- How can I scale the surface, so that it fits the complete selected paper?
- How can I change the background color of the captured window, i. e.
change the theme/style of the window?
Regards,
Fabian
More information about the cairo
mailing list