]> www.fi.muni.cz Git - evince.git/commitdiff
Allow printing multiple pages per sheet. Fixes bug #395573.
authorCarlos Garcia Campos <carlosgc@gnome.org>
Sun, 29 Jul 2007 14:15:17 +0000 (14:15 +0000)
committerCarlos Garcia Campos <carlosgc@src.gnome.org>
Sun, 29 Jul 2007 14:15:17 +0000 (14:15 +0000)
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

ChangeLog
backend/pdf/ev-poppler.cc
configure.ac
libdocument/ev-file-exporter.h
shell/ev-jobs.c
shell/ev-jobs.h
shell/ev-window.c

index 238a1524ec3cb8f7e48d2103c1b258ecdc3f4fbb..1f86db9bdffde1e58df3c886ecf2708e32472653 100644 (file)
--- 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):
index 4b6b114e23b7b0d97b0773c9d67694fab83b442d..38a96a533a4d75fd4b397513fce56e06a48bdbad 100644 (file)
@@ -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"
 #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 |
index d6967870456f6acd3047f9bd61e7197b99a4e96b..5b65fd7ad133274c1669c0225d381ccdfedc0a38 100644 (file)
@@ -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 
index 7fadb1ae62ccd305a57752ef6578f5dc5b7c6146..c05ea27d966e3edbdb38378899b750f28c23ce2b 100644 (file)
@@ -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 ())
index d5d45f2206670703ee4cde012e875bb4f88df439..8e140f8808f4126dcb1ae0a00e5d6cbfc559cfb9 100644 (file)
@@ -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);
index c0a4036fe9e49570f0d239ed84b3b656089ed9e7..1f348d81ee0372a1726898db8544baccb27bc459 100644 (file)
@@ -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);
index 7f928a5f1bbe5665c0b5736a82b042724baaa1d6..233067b398dfd5214bf591e835374d003bb67646 100644 (file)
@@ -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);