--- poppler.override 2009-09-26 20:31:23.000000000 +0200 +++ poppler.override 2011-08-25 05:32:00.000000000 +0200 @@ -257,6 +257,100 @@ #define PYGDK_TYPE_REGION (pygdk_region_get_type ()) #endif /* GDK_TYPE_REGION */ +static void +copy_cairo_surface_to_pixbuf (cairo_surface_t *surface, + GdkPixbuf *pixbuf) +{ + int cairo_width, cairo_height, cairo_rowstride; + unsigned char *pixbuf_data, *dst, *cairo_data; + int pixbuf_rowstride, pixbuf_n_channels; + unsigned int *src; + int x, y; + + cairo_width = cairo_image_surface_get_width (surface); + cairo_height = cairo_image_surface_get_height (surface); + cairo_rowstride = cairo_image_surface_get_stride (surface); + cairo_data = cairo_image_surface_get_data (surface); + + pixbuf_data = gdk_pixbuf_get_pixels (pixbuf); + pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf); + + if (cairo_width > gdk_pixbuf_get_width (pixbuf)) + cairo_width = gdk_pixbuf_get_width (pixbuf); + if (cairo_height > gdk_pixbuf_get_height (pixbuf)) + cairo_height = gdk_pixbuf_get_height (pixbuf); + for (y = 0; y < cairo_height; y++) + { + src = (unsigned int *) (cairo_data + y * cairo_rowstride); + dst = pixbuf_data + y * pixbuf_rowstride; + for (x = 0; x < cairo_width; x++) + { + dst[0] = (*src >> 16) & 0xff; + dst[1] = (*src >> 8) & 0xff; + dst[2] = (*src >> 0) & 0xff; + if (pixbuf_n_channels == 4) + dst[3] = (*src >> 24) & 0xff; + dst += pixbuf_n_channels; + src++; + } + } +} + +static void +_poppler_page_render_to_pixbuf (PopplerPage *page, + int src_x, int src_y, + int src_width, int src_height, + double scale, + int rotation, + gboolean printing, + GdkPixbuf *pixbuf) +{ + cairo_t *cr; + cairo_surface_t *surface; + + if (scale <= 0.0) return; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + src_width, src_height); + cr = cairo_create (surface); + cairo_save (cr); + switch (rotation) { + case 90: + cairo_translate (cr, src_x + src_width, -src_y); + break; + case 180: + cairo_translate (cr, src_x + src_width, src_y + src_height); + break; + case 270: + cairo_translate (cr, -src_x, src_y + src_height); + break; + default: + cairo_translate (cr, -src_x, -src_y); + } + + if (scale != 1.0) + cairo_scale (cr, scale, scale); + + if (rotation != 0) + cairo_rotate (cr, rotation * G_PI / 180.0); + + if (printing) + poppler_page_render_for_printing (page, cr); + else + poppler_page_render (page, cr); + cairo_restore (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER); + cairo_set_source_rgb (cr, 1., 1., 1.); + cairo_paint (cr); + + cairo_destroy (cr); + + copy_cairo_surface_to_pixbuf (surface, pixbuf); + cairo_surface_destroy (surface); +} + %% init @@ -600,3 +694,62 @@ return PycairoSurface_FromSurface(surface, NULL, NULL); #endif } +%% +override poppler_page_render_to_pixbuf kwargs +static PyObject * +_wrap_poppler_page_render_to_pixbuf(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "src_x", "src_y", "src_width", + "src_height", "scale", "rotation", "pixbuf", NULL }; + int src_x, src_y, src_width, src_height, rotation; + double scale; + PyGObject *pixbuf; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "iiiidiO!:Poppler.Page.render_to_pixbuf", + kwlist, &src_x, &src_y, &src_width, + &src_height, &scale, &rotation, &PyGdkPixbuf_Type, &pixbuf)) + return NULL; + + pyg_begin_allow_threads; + + _poppler_page_render_to_pixbuf(POPPLER_PAGE(self->obj), src_x, src_y, + src_width, src_height, scale, + rotation, FALSE, GDK_PIXBUF(pixbuf->obj)); + + pyg_end_allow_threads; + Py_INCREF(Py_None); + return Py_None; +} +%% +override poppler_page_render_to_pixbuf_for_printing kwargs +static PyObject * +_wrap_poppler_page_render_to_pixbuf_for_printing(PyGObject *self, + PyObject *args, + PyObject *kwargs) +{ + static char *kwlist[] = { "src_x", "src_y", "src_width", + "src_height", "scale", "rotation", "pixbuf", NULL }; + int src_x, src_y, src_width, src_height, rotation; + double scale; + PyGObject *pixbuf; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "iiiidiO!:Poppler.Page.render_to_pixbuf_for_printing", + kwlist, &src_x, &src_y, &src_width, + &src_height, &scale, &rotation, &PyGdkPixbuf_Type, &pixbuf)) + return NULL; + + pyg_begin_allow_threads; + + _poppler_page_render_to_pixbuf(POPPLER_PAGE(self->obj), + src_x, src_y, src_width, + src_height, scale, + rotation, TRUE, GDK_PIXBUF(pixbuf->obj)); + + pyg_end_allow_threads; + Py_INCREF(Py_None); + return Py_None; +}