File 0005-tiff-use-cairo-for-printing.patch of Package mingw32-evince

From 39814f90a9500c36c6b3692a91ef37decad630b4 Mon Sep 17 00:00:00 2001
From: Hib Eris <hib@hiberis.nl>
Date: Tue, 7 Jun 2011 21:58:31 +0200
Subject: [PATCH 05/12] tiff: use cairo for printing

Fixes bug #652308.
---
 backend/tiff/tiff-document.c |  116 +++++++++++++++++++++++++++++++++++-------
 1 files changed, 98 insertions(+), 18 deletions(-)

diff --git a/backend/tiff/tiff-document.c b/backend/tiff/tiff-document.c
index 7813eb8..8fda725 100644
--- a/backend/tiff/tiff-document.c
+++ b/backend/tiff/tiff-document.c
@@ -32,6 +32,7 @@
 #include "tiff-document.h"
 #include "ev-document-misc.h"
 #include "ev-file-exporter.h"
+#include "ev-document-print.h"
 #include "ev-file-helpers.h"
 
 struct _TiffDocumentClass
@@ -53,11 +54,15 @@ struct _TiffDocument
 typedef struct _TiffDocumentClass TiffDocumentClass;
 
 static void tiff_document_document_file_exporter_iface_init (EvFileExporterInterface *iface);
+static void tiff_document_document_print_iface_init (EvDocumentPrintInterface *iface);
 
 EV_BACKEND_REGISTER_WITH_CODE (TiffDocument, tiff_document,
 			 {
 			   EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER,
 							   tiff_document_document_file_exporter_iface_init);
+			   EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_PRINT,
+							   tiff_document_document_print_iface_init);
+
 			 });
 
 static TIFFErrorHandler orig_error_handler = NULL;
@@ -219,9 +224,13 @@ tiff_document_get_page_size (EvDocument *document,
 	pop_handlers ();
 }
 
-static cairo_surface_t *
-tiff_document_render (EvDocument      *document,
-		      EvRenderContext *rc)
+static guchar*
+tiff_document_read_data (EvDocument *document,
+			 int index,
+			 int *pwidth,
+			 int *pheight,
+			 float *pscale,
+			 gint *prowstride)
 {
 	TiffDocument *tiff_document = TIFF_DOCUMENT (document);
 	int width, height;
@@ -230,17 +239,14 @@ tiff_document_render (EvDocument      *document,
 	guchar *pixels = NULL;
 	guchar *p;
 	int orientation;
-	cairo_surface_t *surface;
-	cairo_surface_t *rotated_surface;
-	static const cairo_user_data_key_t key;
 	
 	g_return_val_if_fail (TIFF_IS_DOCUMENT (document), NULL);
 	g_return_val_if_fail (tiff_document->tiff != NULL, NULL);
   
 	push_handlers ();
-	if (TIFFSetDirectory (tiff_document->tiff, rc->page->index) != 1) {
+	if (TIFFSetDirectory (tiff_document->tiff, index) != 1) {
 		pop_handlers ();
-		g_warning("Failed to select page %d", rc->page->index);
+		g_warning("Failed to select page %d", index);
 		return NULL;
 	}
 
@@ -262,8 +268,6 @@ tiff_document_render (EvDocument      *document,
 
 	tiff_document_get_resolution (tiff_document, &x_res, &y_res);
 	
-	pop_handlers ();
-  
 	/* Sanity check the doc */
 	if (width <= 0 || height <= 0) {
 		g_warning("Invalid width or height.");
@@ -294,13 +298,6 @@ tiff_document_render (EvDocument      *document,
 		return NULL;
 	}
 	
-	surface = cairo_image_surface_create_for_data (pixels,
-						       CAIRO_FORMAT_RGB24,
-						       width, height,
-						       rowstride);
-	cairo_surface_set_user_data (surface, &key,
-				     pixels, (cairo_destroy_func_t)g_free);
-
 	TIFFReadRGBAImageOriented (tiff_document->tiff,
 				   width, height,
 				   (uint32 *)pixels,
@@ -323,9 +320,47 @@ tiff_document_render (EvDocument      *document,
 		p += 4;
 	}
 
+	*pscale = x_res/y_res;
+	*pwidth = width;
+	*pheight = height;
+	*prowstride = rowstride;
+
+	return pixels;
+}
+
+static cairo_surface_t *
+tiff_document_render (EvDocument      *document,
+		      EvRenderContext *rc)
+{
+	int width, height;
+	float scale;
+	gint rowstride;
+	guchar *pixels = NULL;
+	cairo_surface_t *surface;
+	cairo_surface_t *rotated_surface;
+	static const cairo_user_data_key_t key;
+
+	pixels = tiff_document_read_data (document, rc->page->index, &width, &height, &scale, &rowstride);
+	if (!pixels) {
+		g_warning("Failed to read data for rendering.");
+		return NULL;
+	}
+
+	surface = cairo_image_surface_create_for_data (pixels,
+						       CAIRO_FORMAT_RGB24,
+						       width, height,
+						       rowstride);
+	if (!surface) {
+		g_free (pixels);
+		g_warning("Failed to create surface for rendering.");
+		return NULL;
+	}
+	cairo_surface_set_user_data (surface, &key,
+				     pixels, (cairo_destroy_func_t)*g_free);
+
 	rotated_surface = ev_document_misc_surface_rotate_and_scale (surface,
 								     (width * rc->scale) + 0.5,
-								     (height * rc->scale * (x_res / y_res)) + 0.5,
+								     (height * rc->scale * scale) + 0.5,
 								     rc->rotation);
 	cairo_surface_destroy (surface);
 	
@@ -501,6 +536,51 @@ tiff_document_document_file_exporter_iface_init (EvFileExporterInterface *iface)
 	iface->get_capabilities = tiff_document_file_exporter_get_capabilities;
 }
 
+/* EvDocumentPrint */
+static void
+tiff_document_print_print_page (EvDocumentPrint *document,
+			        EvPage          *page,
+			        cairo_t         *cr)
+{
+	int width, height;
+	float scale;
+	gint rowstride;
+	static const cairo_user_data_key_t key;
+	guchar *pixels = NULL;
+	cairo_surface_t *surface;
+
+	pixels = tiff_document_read_data (EV_DOCUMENT (document), page->index, &width, &height, &scale, &rowstride);
+	if (!pixels) {
+		g_warning("Failed to read data for printing.");
+		return;
+	}
+
+	surface = cairo_image_surface_create_for_data (pixels,
+						       CAIRO_FORMAT_RGB24,
+						       width, height,
+						       rowstride);
+	if (!surface) {
+		g_free (pixels);
+		g_warning("Failed to create image surface for printing.");
+		return;
+	}
+	cairo_surface_set_user_data (surface, &key,
+				     pixels, (cairo_destroy_func_t)*g_free);
+
+	cairo_save (cr);
+	cairo_set_source_surface (cr, surface, 0, 0);
+	cairo_paint (cr);
+	cairo_restore (cr);
+
+	cairo_surface_destroy (surface);
+}
+
+static void
+tiff_document_document_print_iface_init (EvDocumentPrintInterface *iface)
+{
+	iface->print_page = tiff_document_print_print_page;
+}
+
 static void
 tiff_document_init (TiffDocument *tiff_document)
 {
-- 
1.7.5.4

openSUSE Build Service is sponsored by