Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2007-07-29 14:15:17 (GMT)
committer Carlos Garcia Campos <carlosgc@src.gnome.org>2007-07-29 14:15:17 (GMT)
commit85fa11d86616d3a9c5a5cfeba78dd7aa72e7997a (patch)
treec8641298dbaafcb9c5440ed0fa7d0cbc9ed37b92
parent5f6b1add282b53fc4544d79e9a6fb635c6754058 (diff)
Allow printing multiple pages per sheet. Fixes bug #395573.
2007-07-29 Carlos Garcia Campos <carlosgc@gnome.org> * configure.ac: * backend/pdf/ev-poppler.cc: (pdf_print_context_free), (pdf_document_file_exporter_begin), (pdf_document_file_exporter_do_page), (pdf_document_file_exporter_get_capabilities): * libdocument/ev-file-exporter.h: * shell/ev-jobs.[ch]: (ev_job_print_new), (ev_job_print_run): * shell/ev-window.c: (ev_window_print_send), (ev_window_print_dialog_response_cb): Allow printing multiple pages per sheet. Fixes bug #395573. svn path=/trunk/; revision=2591
-rw-r--r--ChangeLog14
-rw-r--r--backend/pdf/ev-poppler.cc151
-rw-r--r--configure.ac5
-rw-r--r--libdocument/ev-file-exporter.h1
-rw-r--r--shell/ev-jobs.c6
-rw-r--r--shell/ev-jobs.h2
-rw-r--r--shell/ev-window.c6
7 files changed, 153 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index 238a152..1f86db9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2007-07-29 Carlos Garcia Campos <carlosgc@gnome.org>
+
+ * configure.ac:
+ * backend/pdf/ev-poppler.cc: (pdf_print_context_free),
+ (pdf_document_file_exporter_begin),
+ (pdf_document_file_exporter_do_page),
+ (pdf_document_file_exporter_get_capabilities):
+ * libdocument/ev-file-exporter.h:
+ * shell/ev-jobs.[ch]: (ev_job_print_new), (ev_job_print_run):
+ * shell/ev-window.c: (ev_window_print_send),
+ (ev_window_print_dialog_response_cb):
+
+ Allow printing multiple pages per sheet. Fixes bug #395573.
+
2007-07-29 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
* shell/ev-view.c: (tip_from_link):
diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc
index 4b6b114..38a96a5 100644
--- a/backend/pdf/ev-poppler.cc
+++ b/backend/pdf/ev-poppler.cc
@@ -32,6 +32,9 @@
#ifdef HAVE_CAIRO_PDF
#include <cairo-pdf.h>
#endif
+#ifdef HAVE_CAIRO_PS
+#include <cairo-ps.h>
+#endif
#include <glib/gi18n.h>
#include "ev-poppler.h"
@@ -49,6 +52,10 @@
#include "ev-attachment.h"
#include "ev-image.h"
+#if defined (HAVE_CAIRO_PDF) || defined (HAVE_CAIRO_PS)
+#define HAVE_CAIRO_PRINT
+#endif
+
typedef struct {
PdfDocument *document;
char *text;
@@ -61,8 +68,17 @@ typedef struct {
typedef struct {
EvFileExporterFormat format;
PopplerPSFile *ps_file;
-#ifdef HAVE_CAIRO_PDF
- cairo_t *pdf_cairo;
+
+ /* Pages per sheet */
+ gint pages_per_sheet;
+ gint pages_printed;
+ gint pages_x;
+ gint pages_y;
+ gdouble page_width;
+ gdouble page_height;
+
+#ifdef HAVE_CAIRO_PRINT
+ cairo_t *cr;
#endif
} PdfPrintContext;
@@ -1516,10 +1532,10 @@ pdf_print_context_free (PdfPrintContext *ctx)
poppler_ps_file_free (ctx->ps_file);
ctx->ps_file = NULL;
}
-#ifdef HAVE_CAIRO_PDF
- if (ctx->pdf_cairo) {
- cairo_destroy (ctx->pdf_cairo);
- ctx->pdf_cairo = NULL;
+#ifdef HAVE_CAIRO_PRINT
+ if (ctx->cr) {
+ cairo_destroy (ctx->cr);
+ ctx->cr = NULL;
}
#endif
g_free (ctx);
@@ -1531,35 +1547,87 @@ pdf_document_file_exporter_begin (EvFileExporter *exporter,
{
PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
PdfPrintContext *ctx;
-
+ gdouble width, height;
+ gboolean change_orient = FALSE;
+#ifdef HAVE_CAIRO_PRINT
+ cairo_surface_t *surface = NULL;
+#endif
+
if (pdf_document->print_ctx)
pdf_print_context_free (pdf_document->print_ctx);
pdf_document->print_ctx = g_new0 (PdfPrintContext, 1);
ctx = pdf_document->print_ctx;
ctx->format = fc->format;
-
+ ctx->pages_per_sheet = fc->pages_per_sheet;
+
+ switch (fc->pages_per_sheet) {
+ default:
+ case 1:
+ ctx->pages_x = 1;
+ ctx->pages_y = 1;
+ break;
+ case 2:
+ change_orient = TRUE;
+ ctx->pages_x = 2;
+ ctx->pages_y = 1;
+ break;
+ case 4:
+ ctx->pages_x = 2;
+ ctx->pages_y = 2;
+ break;
+ case 6:
+ change_orient = TRUE;
+ ctx->pages_x = 3;
+ ctx->pages_y = 2;
+ break;
+ case 9:
+ ctx->pages_x = 3;
+ ctx->pages_y = 3;
+ break;
+ case 16:
+ ctx->pages_x = 4;
+ ctx->pages_y = 4;
+ break;
+ }
+
+ if (change_orient) {
+ width = fc->paper_height;
+ height = fc->paper_width;
+ } else {
+ width = fc->paper_width;
+ height = fc->paper_height;
+ }
+
+ ctx->page_width = width / ctx->pages_x;
+ ctx->page_height = height / ctx->pages_y;
+
+ ctx->pages_printed = 0;
+
switch (fc->format) {
case EV_FILE_FORMAT_PS:
+#ifdef HAVE_CAIRO_PS
+ surface = cairo_ps_surface_create (fc->filename, width, height);
+#else
ctx->ps_file = poppler_ps_file_new (pdf_document->document,
fc->filename, fc->first_page,
fc->last_page - fc->first_page + 1);
poppler_ps_file_set_paper_size (ctx->ps_file, fc->paper_width, fc->paper_height);
poppler_ps_file_set_duplex (ctx->ps_file, fc->duplex);
-
+#endif /* HAVE_CAIRO_PS */
break;
- case EV_FILE_FORMAT_PDF: {
+ case EV_FILE_FORMAT_PDF:
#ifdef HAVE_CAIRO_PDF
- cairo_surface_t *surface;
-
- surface = cairo_pdf_surface_create (fc->filename, fc->paper_width, fc->paper_height);
- ctx->pdf_cairo = cairo_create (surface);
- cairo_surface_destroy (surface);
+ surface = cairo_pdf_surface_create (fc->filename, width, height);
#endif
- }
break;
default:
g_assert_not_reached ();
}
+
+#ifdef HAVE_CAIRO_PRINT
+ ctx->cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+#endif
}
static void
@@ -1569,30 +1637,41 @@ pdf_document_file_exporter_do_page (EvFileExporter *exporter,
PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
PdfPrintContext *ctx = pdf_document->print_ctx;
PopplerPage *poppler_page;
+#ifdef HAVE_CAIRO_PRINT
+ gdouble page_width, page_height;
+ gint x, y;
+#endif
g_return_if_fail (pdf_document->print_ctx != NULL);
poppler_page = poppler_document_get_page (pdf_document->document, rc->page);
+
+#ifdef HAVE_CAIRO_PRINT
+ x = (ctx->pages_printed % ctx->pages_per_sheet) % ctx->pages_x;
+ y = (ctx->pages_printed % ctx->pages_per_sheet) / ctx->pages_x;
+ poppler_page_get_size (poppler_page, &page_width, &page_height);
+
+ cairo_save (ctx->cr);
+ cairo_translate (ctx->cr,
+ x * ctx->page_width,
+ y * ctx->page_height);
+ cairo_scale (ctx->cr,
+ ctx->page_width / page_width,
+ ctx->page_height / page_height);
- switch (ctx->format) {
- case EV_FILE_FORMAT_PS:
- poppler_page_render_to_ps (poppler_page, ctx->ps_file);
- break;
- case EV_FILE_FORMAT_PDF:
-#ifdef HAVE_CAIRO_PDF
- cairo_save (ctx->pdf_cairo);
-#endif
#ifdef HAVE_POPPLER_PAGE_RENDER
- poppler_page_render (poppler_page, ctx->pdf_cairo);
-#endif
-#ifdef HAVE_CAIRO_PDF
- cairo_show_page (ctx->pdf_cairo);
- cairo_restore (ctx->pdf_cairo);
+ poppler_page_render (poppler_page, ctx->cr);
#endif
- break;
- default:
- g_assert_not_reached ();
+ ctx->pages_printed++;
+
+ if (ctx->pages_printed % ctx->pages_per_sheet == 0) {
+ cairo_show_page (ctx->cr);
}
+ cairo_restore (ctx->cr);
+#else /* HAVE_CAIRO_PRINT */
+ if (ctx->format == EV_FILE_FORMAT_PS)
+ poppler_page_render_to_ps (poppler_page, ctx->ps_file);
+#endif /* HAVE_CAIRO_PRINT */
g_object_unref (poppler_page);
}
@@ -1615,6 +1694,14 @@ pdf_document_file_exporter_get_capabilities (EvFileExporter *exporter)
EV_FILE_EXPORTER_CAN_COLLATE |
EV_FILE_EXPORTER_CAN_REVERSE |
EV_FILE_EXPORTER_CAN_SCALE |
+#ifdef HAVE_CAIRO_PRINT
+#ifdef HAVE_POPPLER_PAGE_RENDER
+#if GTK_CHECK_VERSION (2, 11, 1)
+ EV_FILE_EXPORTER_CAN_NUMBER_UP |
+#endif
+#endif
+#endif
+
#ifdef HAVE_CAIRO_PDF
#ifdef HAVE_POPPLER_PAGE_RENDER
EV_FILE_EXPORTER_CAN_GENERATE_PDF |
diff --git a/configure.ac b/configure.ac
index d696787..5b65fd7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -257,6 +257,11 @@ if test "x$enable_pdf" = "xyes"; then
if test x$enable_cairo_pdf == xyes; then
AC_DEFINE([HAVE_CAIRO_PDF], [1], [defined if cairo-pdf is available])
fi
+
+ PKG_CHECK_MODULES(CAIRO_PS, cairo-ps, enable_cairo_ps=yes, enable_cairo_ps=no)
+ if test x$enable_cairo_ps == xyes; then
+ AC_DEFINE([HAVE_CAIRO_PS], [1], [defined if cairo-ps is available])
+ fi
else
AC_MSG_WARN("PDF support is disabled since poppler-glib library version $POPPLER_REQUIRED or newer not found")
fi
diff --git a/libdocument/ev-file-exporter.h b/libdocument/ev-file-exporter.h
index 7fadb1a..c05ea27 100644
--- a/libdocument/ev-file-exporter.h
+++ b/libdocument/ev-file-exporter.h
@@ -55,6 +55,7 @@ typedef struct {
gdouble paper_width;
gdouble paper_height;
gboolean duplex;
+ gint pages_per_sheet;
} EvFileExporterContext;
#define EV_TYPE_FILE_EXPORTER (ev_file_exporter_get_type ())
diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c
index d5d45f2..8e140f8 100644
--- a/shell/ev-jobs.c
+++ b/shell/ev-jobs.c
@@ -326,6 +326,8 @@ render_finished_cb (EvDocument *document,
/* FIXME: ps backend should be ported to cairo */
job->surface = ev_document_misc_surface_from_pixbuf (pixbuf);
+ job->page_ready = TRUE;
+ g_signal_emit (job, job_render_signals[PAGE_READY], 0);
EV_JOB (job)->finished = TRUE;
ev_job_finished (EV_JOB (job));
}
@@ -562,6 +564,7 @@ ev_job_print_new (EvDocument *document,
EvPrintRange *ranges,
gint n_ranges,
EvPrintPageSet page_set,
+ gint pages_per_sheet,
gint copies,
gdouble collate,
gdouble reverse)
@@ -584,6 +587,8 @@ ev_job_print_new (EvDocument *document,
job->n_ranges = n_ranges;
job->page_set = page_set;
+
+ job->pages_per_sheet = pages_per_sheet;
job->copies = copies;
job->collate = collate;
@@ -711,6 +716,7 @@ ev_job_print_run (EvJobPrint *job)
fc.paper_width = job->width;
fc.paper_height = job->height;
fc.duplex = FALSE;
+ fc.pages_per_sheet = job->pages_per_sheet;
ev_document_doc_mutex_lock ();
ev_file_exporter_begin (EV_FILE_EXPORTER (document), &fc);
diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h
index c0a4036..1f348d8 100644
--- a/shell/ev-jobs.h
+++ b/shell/ev-jobs.h
@@ -199,6 +199,7 @@ struct _EvJobPrint
gint n_ranges;
EvPrintPageSet page_set;
gint copies;
+ gint pages_per_sheet;
gboolean collate;
gboolean reverse;
gdouble width;
@@ -264,6 +265,7 @@ EvJob *ev_job_print_new (EvDocument *document,
EvPrintRange *ranges,
gint n_ranges,
EvPrintPageSet page_set,
+ gint pages_per_sheet,
gint copies,
gdouble collate,
gdouble reverse);
diff --git a/shell/ev-window.c b/shell/ev-window.c
index 7f928a5..233067b 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -2220,6 +2220,8 @@ ev_window_print_send (EvWindow *window,
gtk_print_settings_set_collate (settings, FALSE);
if (capabilities & EV_FILE_EXPORTER_CAN_REVERSE)
gtk_print_settings_set_reverse (settings, FALSE);
+ if (capabilities & EV_FILE_EXPORTER_CAN_NUMBER_UP)
+ gtk_print_settings_set_number_up (settings, 1);
if (window->priv->print_preview) {
gchar *uri;
@@ -2294,6 +2296,7 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog,
EvPrintPageSet page_set;
gint n_ranges = 0;
gint copies;
+ gint pages_per_sheet;
gboolean collate;
gboolean reverse;
gdouble scale;
@@ -2385,6 +2388,8 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog,
height *= scale;
}
+ pages_per_sheet = gtk_print_settings_get_number_up (window->priv->print_settings);
+
copies = gtk_print_settings_get_n_copies (window->priv->print_settings);
collate = gtk_print_settings_get_collate (window->priv->print_settings);
reverse = gtk_print_settings_get_reverse (window->priv->print_settings);
@@ -2394,6 +2399,7 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog,
width, height,
ranges, n_ranges,
page_set,
+ pages_per_sheet,
copies, collate,
reverse);