From 9c25532eb22532c2766b5a894ccd73c6cb8b407a Mon Sep 17 00:00:00 2001 From: auroux Date: Thu, 21 Jul 2011 22:07:33 +0000 Subject: [PATCH] wrapper for missing GdkPixbuf rendering function in newest poppler --- ChangeLog | 1 + src/xo-file.c | 2 +- src/xo-misc.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/xo-misc.h | 9 +++++ src/xo-print.c | 2 +- 5 files changed, 102 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c4ce61e..8be0914 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ This version: - fix crash upon unplugging input devices - change close dialog box default to "save" (patch by Kit Barnes) - option to force PDF background rendering via cairo (slower but nicer) + - wrapper for missing GdkPixbuf rendering function in newest poppler Version 0.4.5 (Oct 2, 2009): - bugfixes for GTK+ 2.16/2.17 issues with xinput events diff --git a/src/xo-file.c b/src/xo-file.c index e26bcd1..6a1a659 100644 --- a/src/xo-file.c +++ b/src/xo-file.c @@ -1031,7 +1031,7 @@ gboolean bgpdf_scheduler_callback(gpointer data) else { // directly poppler -> pixbuf: faster, but bitmap font bug pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, scaled_width, scaled_height); - poppler_page_render_to_pixbuf( + wrapper_poppler_page_render_to_pixbuf( pdfpage, 0, 0, scaled_width, scaled_height, req->dpi/72, 0, pixbuf); } diff --git a/src/xo-misc.c b/src/xo-misc.c index 158b81b..65a948e 100644 --- a/src/xo-misc.c +++ b/src/xo-misc.c @@ -2197,3 +2197,93 @@ void install_focus_hooks(GtkWidget *w, gpointer data) if(GTK_IS_CONTAINER(w)) gtk_container_forall(GTK_CONTAINER(w), install_focus_hooks, data); } + +// wrapper for missing poppler functions (defunct poppler-gdk api) + +static void +wrapper_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++; + } + } +} + +void +wrapper_poppler_page_render_to_pixbuf (PopplerPage *page, + int src_x, int src_y, + int src_width, int src_height, + double scale, + int rotation, + GdkPixbuf *pixbuf) +{ + cairo_t *cr; + cairo_surface_t *surface; + + 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); + + 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); + + wrapper_copy_cairo_surface_to_pixbuf (surface, pixbuf); + cairo_surface_destroy (surface); +} diff --git a/src/xo-misc.h b/src/xo-misc.h index 5be0c13..6f052da 100644 --- a/src/xo-misc.h +++ b/src/xo-misc.h @@ -107,6 +107,15 @@ void unset_flags(GtkWidget *w, gpointer flag); gboolean intercept_activate_events(GtkWidget *w, GdkEvent *ev, gpointer data); void install_focus_hooks(GtkWidget *w, gpointer data); +// wrapper for a function no longer provided by poppler 0.17+ +void +wrapper_poppler_page_render_to_pixbuf (PopplerPage *page, + int src_x, int src_y, + int src_width, int src_height, + double scale, + int rotation, + GdkPixbuf *pixbuf); + // defines for paper rulings #define RULING_MARGIN_COLOR 0xff0080ff diff --git a/src/xo-print.c b/src/xo-print.c index 8887984..df4afcd 100644 --- a/src/xo-print.c +++ b/src/xo-print.c @@ -728,7 +728,7 @@ int pdf_draw_bitmap_background(struct Page *pg, GString *str, width = (int) (PDFTOPPM_PRINTING_DPI * pgwidth/72.0); height = (int) (PDFTOPPM_PRINTING_DPI * pgheight/72.0); pix = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height); - poppler_page_render_to_pixbuf( + wrapper_poppler_page_render_to_pixbuf( pdfpage, 0, 0, width, height, PDFTOPPM_PRINTING_DPI/72.0, 0, pix); g_object_unref(pdfpage); } -- 2.39.2