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