]> www.fi.muni.cz Git - evince.git/commitdiff
Allow printing to PDF when suppoted by the backend.
authorCarlos Garcia Campos <carlosgc@gnome.org>
Sun, 3 Dec 2006 20:35:46 +0000 (20:35 +0000)
committerCarlos Garcia Campos <carlosgc@src.gnome.org>
Sun, 3 Dec 2006 20:35:46 +0000 (20:35 +0000)
2006-12-03  Carlos Garcia Campos  <carlosgc@gnome.org>
* configure.ac:
* backend/Makefile.am:
* backend/ev-file-exporter.[ch]:
* pdf/ev-poppler.cc: (pdf_document_file_exporter_*):
* ps/ps-document.c: (ps_document_file_exporter_*):
* tiff/tiff-document.c: (tiff_document_document_file_exporter_*):
* shell/ev-jobs.[ch]: (ev_job_print_new), (ev_job_print_run):
* shell/ev-window.c: (ev_window_setup_action_sensitivity),
(ev_window_print_dialog_response_cb), (ev_window_print_range):
Allow printing to PDF when suppoted by the backend.

13 files changed:
ChangeLog
backend/Makefile.am
backend/ev-file-exporter.c [new file with mode: 0644]
backend/ev-file-exporter.h [new file with mode: 0644]
backend/ev-ps-exporter.c [deleted file]
backend/ev-ps-exporter.h [deleted file]
configure.ac
pdf/ev-poppler.cc
ps/ps-document.c
shell/ev-jobs.c
shell/ev-jobs.h
shell/ev-window.c
tiff/tiff-document.c

index 98f88652810546fcd832253bab4b311cb7fb88f1..d52d0231a3b602de7f86e24a88c5b1fc5c780c20 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2006-12-03  Carlos Garcia Campos  <carlosgc@gnome.org>
+
+       * configure.ac:
+       * backend/Makefile.am:
+       * backend/ev-file-exporter.[ch]:
+       * pdf/ev-poppler.cc: (pdf_document_file_exporter_*):
+       * ps/ps-document.c: (ps_document_file_exporter_*):
+       * tiff/tiff-document.c: (tiff_document_document_file_exporter_*):
+       * shell/ev-jobs.[ch]: (ev_job_print_new), (ev_job_print_run):
+       * shell/ev-window.c: (ev_window_setup_action_sensitivity),
+       (ev_window_print_dialog_response_cb), (ev_window_print_range):
+
+       Allow printing to PDF when suppoted by the backend.
+       
 2006-12-03  Carlos Garcia Campos  <carlosgc@gnome.org>
 
        * shell/ev-window.c: (build_comments_string):
index bcf975a30e9d7529262be0331f567fb0bbec3cd6..2de2f5fe53949a1888fd8dfad0f2db400d7e511c 100644 (file)
@@ -43,8 +43,8 @@ libevbackend_la_SOURCES=                      \
        ev-document-find.c                      \
        ev-document-find.h                      \
        ev-document-info.h                      \
-       ev-ps-exporter.c                        \
-       ev-ps-exporter.h                        \
+       ev-file-exporter.c                      \
+       ev-file-exporter.h                      \
        ev-render-context.h                     \
        ev-render-context.c                     \
        ev-selection.h                          \
diff --git a/backend/ev-file-exporter.c b/backend/ev-file-exporter.c
new file mode 100644 (file)
index 0000000..7a4e902
--- /dev/null
@@ -0,0 +1,91 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ *  Copyright (C) 2004 Martin Kretzschmar
+ *
+ *  Author:
+ *    Martin Kretzschmar <martink@gnome.org>
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "ev-file-exporter.h"
+
+GType
+ev_file_exporter_get_type (void)
+{
+        static GType type = 0;
+
+        if (G_UNLIKELY (type == 0)) {
+                const GTypeInfo our_info =
+                {
+                        sizeof (EvFileExporterIface),
+                        NULL,
+                        NULL,
+                };
+
+                type = g_type_register_static (G_TYPE_INTERFACE,
+                                               "EvFileExporter",
+                                               &our_info, (GTypeFlags)0);
+        }
+
+        return type;
+}
+
+gboolean
+ev_file_exporter_format_supported (EvFileExporter      *exporter,
+                                  EvFileExporterFormat format)
+{
+       EvFileExporterIface *iface = EV_FILE_EXPORTER_GET_IFACE (exporter);
+
+       if (format < EV_FILE_FORMAT_PS ||
+           format > EV_FILE_FORMAT_PDF)
+               return FALSE;
+
+       return iface->format_supported (exporter, format);
+}
+
+void
+ev_file_exporter_begin (EvFileExporter      *exporter,
+                        EvFileExporterFormat format,
+                        const gchar         *filename,
+                        gint                 first_page,
+                        gint                 last_page,
+                        gdouble              paper_width,
+                        gdouble              paper_height,
+                        gboolean             duplex)
+{
+        EvFileExporterIface *iface = EV_FILE_EXPORTER_GET_IFACE (exporter);
+
+       g_return_if_fail (ev_file_exporter_format_supported (exporter, format));
+
+        iface->begin (exporter, format, filename, first_page, last_page,
+                      paper_width, paper_height, duplex);
+}
+
+void
+ev_file_exporter_do_page (EvFileExporter *exporter, EvRenderContext *rc)
+{
+        EvFileExporterIface *iface = EV_FILE_EXPORTER_GET_IFACE (exporter);
+
+        iface->do_page (exporter, rc);
+}
+
+void
+ev_file_exporter_end (EvFileExporter *exporter)
+{
+        EvFileExporterIface *iface = EV_FILE_EXPORTER_GET_IFACE (exporter);
+
+        iface->end (exporter);
+}
diff --git a/backend/ev-file-exporter.h b/backend/ev-file-exporter.h
new file mode 100644 (file)
index 0000000..f0e517c
--- /dev/null
@@ -0,0 +1,84 @@
+/* this file is part of evince, a gnome document viewer
+ *
+ *  Copyright (C) 2004 Martin Kretzschmar
+ *
+ *  Author:
+ *    Martin Kretzschmar <martink@gnome.org>
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef EV_FILE_EXPORTER_H
+#define EV_FILE_EXPORTER_H
+
+#include <glib-object.h>
+
+#include "ev-render-context.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+        EV_FILE_FORMAT_PS,
+        EV_FILE_FORMAT_PDF,
+        EV_FILE_FORMAT_UNKNOWN
+} EvFileExporterFormat;
+
+#define EV_TYPE_FILE_EXPORTER            (ev_file_exporter_get_type ())
+#define EV_FILE_EXPORTER(o)              (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_FILE_EXPORTER, EvFileExporter))
+#define EV_FILE_EXPORTER_IFACE(k)        (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_FILE_EXPORTER, EvFileExporterIface))
+#define EV_IS_FILE_EXPORTER(o)           (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_FILE_EXPORTER))
+#define EV_IS_FILE_EXPORTER_IFACE(k)     (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_FILE_EXPORTER))
+#define EV_FILE_EXPORTER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_FILE_EXPORTER, EvFileExporterIface))
+
+typedef struct _EvFileExporter EvFileExporter;
+typedef struct _EvFileExporterIface EvFileExporterIface;
+
+struct _EvFileExporterIface {
+        GTypeInterface base_iface;
+
+        /* Methods  */
+        gboolean   (* format_supported) (EvFileExporter      *exporter,
+                                         EvFileExporterFormat format);
+        void       (* begin)            (EvFileExporter      *exporter,
+                                         EvFileExporterFormat format,
+                                         const gchar         *filename,
+                                         gint                 first_page,
+                                         gint                 last_page,
+                                         gdouble              paper_width,
+                                         gdouble              paper_height,
+                                         gboolean             duplex);
+        void       (* do_page)          (EvFileExporter      *exporter,
+                                         EvRenderContext     *rc);
+        void       (* end)              (EvFileExporter      *exporter);
+};
+
+GType    ev_file_exporter_get_type         (void) G_GNUC_CONST;
+gboolean ev_file_exporter_format_supported (EvFileExporter      *exporter,
+                                            EvFileExporterFormat format);
+void     ev_file_exporter_begin            (EvFileExporter      *exporter,
+                                            EvFileExporterFormat format, 
+                                            const gchar         *filename,
+                                            gint                 first_page,
+                                            gint                 last_page,
+                                            gdouble              paper_width,
+                                            gdouble              paper_height,
+                                            gboolean             duplex);
+void     ev_file_exporter_do_page          (EvFileExporter      *exporter,
+                                            EvRenderContext     *rc);
+void     ev_file_exporter_end              (EvFileExporter      *exporter);
+
+G_END_DECLS
+
+#endif
diff --git a/backend/ev-ps-exporter.c b/backend/ev-ps-exporter.c
deleted file mode 100644 (file)
index 18c3536..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/* this file is part of evince, a gnome document viewer
- *
- *  Copyright (C) 2004 Martin Kretzschmar
- *
- *  Author:
- *    Martin Kretzschmar <martink@gnome.org>
- *
- * Evince is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Evince is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "ev-ps-exporter.h"
-
-GType
-ev_ps_exporter_get_type (void)
-{
-       static GType type = 0;
-
-       if (G_UNLIKELY (type == 0))
-       {
-               const GTypeInfo our_info =
-               {
-                       sizeof (EvPSExporterIface),
-                       NULL,
-                       NULL,
-               };
-
-               type = g_type_register_static (G_TYPE_INTERFACE,
-                                              "EvPSExporter",
-                                              &our_info, (GTypeFlags)0);
-       }
-
-       return type;
-}
-
-void
-ev_ps_exporter_begin (EvPSExporter *exporter, const char *filename,
-                     int first_page, int last_page,
-                      double paper_width, double paper_height, gboolean duplex)
-{
-       EvPSExporterIface *iface = EV_PS_EXPORTER_GET_IFACE (exporter);
-
-       iface->begin (exporter, filename, first_page, last_page,
-                      paper_width, paper_height, duplex);
-}
-
-void
-ev_ps_exporter_do_page (EvPSExporter *exporter, EvRenderContext *rc)
-{
-       EvPSExporterIface *iface = EV_PS_EXPORTER_GET_IFACE (exporter);
-
-       iface->do_page (exporter, rc);
-}
-
-void
-ev_ps_exporter_end     (EvPSExporter *exporter)
-{
-       EvPSExporterIface *iface = EV_PS_EXPORTER_GET_IFACE (exporter);
-
-       iface->end (exporter);
-}
diff --git a/backend/ev-ps-exporter.h b/backend/ev-ps-exporter.h
deleted file mode 100644 (file)
index 4115e3a..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* this file is part of evince, a gnome document viewer
- *
- *  Copyright (C) 2004 Martin Kretzschmar
- *
- *  Author:
- *    Martin Kretzschmar <martink@gnome.org>
- *
- * Evince is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Evince is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef EV_PS_EXPORTER_H
-#define EV_PS_EXPORTER_H
-
-#include <glib-object.h>
-
-#include "ev-render-context.h"
-
-G_BEGIN_DECLS
-
-#define EV_TYPE_PS_EXPORTER           (ev_ps_exporter_get_type ())
-#define EV_PS_EXPORTER(o)             (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_PS_EXPORTER, EvPSExporter))
-#define EV_PS_EXPORTER_IFACE(k)               (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_PS_EXPORTER, EvPSExporterIface))
-#define EV_IS_PS_EXPORTER(o)          (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_PS_EXPORTER))
-#define EV_IS_PS_EXPORTER_IFACE(k)     (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_PS_EXPORTER))
-#define EV_PS_EXPORTER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_PS_EXPORTER, EvPSExporterIface))
-
-typedef struct _EvPSExporter EvPSExporter;
-typedef struct _EvPSExporterIface EvPSExporterIface;
-
-struct _EvPSExporterIface {
-       GTypeInterface base_iface;
-
-       /* Methods  */
-       void            (* begin)       (EvPSExporter    *exporter,
-                                        const char      *filename,
-                                        int              first_page,
-                                        int              last_page,
-                                         double           paper_width,
-                                         double           paper_height,
-                                         gboolean         duplex);
-       void            (* do_page)     (EvPSExporter    *exporter,
-                                        EvRenderContext *rc);
-       void            (* end)         (EvPSExporter    *exporter);
-};
-
-GType  ev_ps_exporter_get_type (void);
-void   ev_ps_exporter_begin    (EvPSExporter *exporter, const char *filename,
-                                int first_page, int last_page,
-                                 double paper_width, double paper_height,
-                                 gboolean duplex);
-void   ev_ps_exporter_do_page  (EvPSExporter *exporter, EvRenderContext *rc);
-void   ev_ps_exporter_end      (EvPSExporter *exporter);
-
-G_END_DECLS
-
-#endif
index a299f09420dc42982fb526f35a4dbd65ac4b2055..304219975be03d923d589d1aa2af04a4d23764e1 100644 (file)
@@ -199,6 +199,10 @@ if test "x$enable_pdf" = "xyes"; then
            FRONTEND_LIBS="$FRONTEND_LIBS $POPPLER_LIBS"
            SHELL_LIBS="$SHELL_LIBS $POPPLER_LIBS"
            SHELL_CFLAGS="$SHELL_CFLAGS $POPPLER_CFLAGS"
+           evince_save_LIBS=$LIBS
+           LIBS="$LIBS $FRONTEND_LIBS"
+           AC_CHECK_FUNCS(poppler_page_render)
+           LIBS=$evince_save_LIBS
     else
            AC_MSG_WARN("PDF support is disabled since poppler-glib library version $POPPLER_REQUIRED or newer not found")
     fi 
index dc5510e619841b08a1a10250db7577bb52147113..a90c52413a1c769d0c516460fe8e4d6e6abc8c08 100644 (file)
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#include "config.h"
+
 #include <math.h>
 #include <string.h>
 #include <gtk/gtk.h>
 #include <poppler.h>
 #include <poppler-document.h>
 #include <poppler-page.h>
+#include <cairo-pdf.h>
 #include <glib/gi18n.h>
 
 #include "ev-poppler.h"
-#include "ev-ps-exporter.h"
+#include "ev-file-exporter.h"
 #include "ev-document-find.h"
 #include "ev-document-misc.h"
 #include "ev-document-links.h"
@@ -45,6 +48,12 @@ typedef struct {
        int search_page;
 } PdfDocumentSearch;
 
+typedef struct {
+       EvFileExporterFormat format;
+       PopplerPSFile *ps_file;
+       cairo_t *pdf_cairo;
+} PdfPrintContext;
+
 struct _PdfDocumentClass
 {
        GObjectClass parent_class;
@@ -55,7 +64,6 @@ struct _PdfDocument
        GObject parent_instance;
 
        PopplerDocument *document;
-       PopplerPSFile *ps_file;
        gchar *password;
 
        PopplerFontInfo *font_info;
@@ -63,6 +71,7 @@ struct _PdfDocument
        int fonts_scanned_pages;
 
        PdfDocumentSearch *search;
+       PdfPrintContext *print_ctx;
 };
 
 static void pdf_document_document_iface_init            (EvDocumentIface           *iface);
@@ -71,7 +80,7 @@ static void pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIfa
 static void pdf_document_document_links_iface_init      (EvDocumentLinksIface      *iface);
 static void pdf_document_document_fonts_iface_init      (EvDocumentFontsIface      *iface);
 static void pdf_document_find_iface_init                (EvDocumentFindIface       *iface);
-static void pdf_document_ps_exporter_iface_init         (EvPSExporterIface         *iface);
+static void pdf_document_file_exporter_iface_init       (EvFileExporterIface       *iface);
 static void pdf_selection_iface_init                    (EvSelectionIface          *iface);
 static void pdf_document_thumbnails_get_dimensions      (EvDocumentThumbnails      *document_thumbnails,
                                                         gint                       page,
@@ -85,6 +94,7 @@ static EvLinkDest *ev_link_dest_from_dest   (PdfDocument       *pdf_document,
 static EvLink     *ev_link_from_action      (PdfDocument       *pdf_document,
                                             PopplerAction     *action);
 static void        pdf_document_search_free (PdfDocumentSearch *search);
+static void        pdf_print_context_free   (PdfPrintContext   *ctx);
 
 
 G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
@@ -101,8 +111,8 @@ G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
                                                        pdf_document_document_fonts_iface_init);
                                 G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
                                                        pdf_document_find_iface_init);
-                                G_IMPLEMENT_INTERFACE (EV_TYPE_PS_EXPORTER,
-                                                       pdf_document_ps_exporter_iface_init);
+                                G_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER,
+                                                       pdf_document_file_exporter_iface_init);
                                 G_IMPLEMENT_INTERFACE (EV_TYPE_SELECTION,
                                                        pdf_selection_iface_init);
                         });
@@ -147,6 +157,11 @@ pdf_document_dispose (GObject *object)
 {
        PdfDocument *pdf_document = PDF_DOCUMENT(object);
 
+       if (pdf_document->print_ctx) {
+               pdf_print_context_free (pdf_document->print_ctx);
+               pdf_document->print_ctx = NULL;
+       }
+       
        if (pdf_document->search) {
                pdf_document_search_free (pdf_document->search);
                pdf_document->search = NULL;
@@ -1398,51 +1413,128 @@ pdf_document_find_iface_init (EvDocumentFindIface *iface)
         iface->cancel = pdf_document_find_cancel;
 }
 
+static const gboolean supported_formats[] = {
+       TRUE, /* EV_FILE_FORMAT_PS */
+#ifdef HAVE_POPPLER_PAGE_RENDER
+       TRUE, /* EV_FILE_FORMAT_PDF */
+#else
+       FALSE, /* EV_FILE_FORMAT_PDF */
+#endif
+};
+
+static void
+pdf_print_context_free (PdfPrintContext *ctx)
+{
+       if (!ctx)
+               return;
+
+       if (ctx->ps_file) {
+               poppler_ps_file_free (ctx->ps_file);
+               ctx->ps_file = NULL;
+       }
+
+       if (ctx->pdf_cairo) {
+               cairo_destroy (ctx->pdf_cairo);
+               ctx->pdf_cairo = NULL;
+       }
+
+       g_free (ctx);
+}
+
+static gboolean
+pdf_document_file_exporter_format_supported (EvFileExporter      *exporter,
+                                            EvFileExporterFormat format)
+{
+       return supported_formats[format];
+}
+
 static void
-pdf_document_ps_exporter_begin (EvPSExporter *exporter, const char *filename,
-                               int first_page, int last_page,
-                               double width, double height, gboolean duplex)
+pdf_document_file_exporter_begin (EvFileExporter      *exporter,
+                                 EvFileExporterFormat format,
+                                 const char          *filename,
+                                 int                  first_page,
+                                 int                  last_page,
+                                 double               width,
+                                 double               height,
+                                 gboolean             duplex)
 {
        PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
+       PdfPrintContext *ctx;
+
+       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 = format;
        
-       pdf_document->ps_file = poppler_ps_file_new (pdf_document->document, filename,
-                                                    first_page,
-                                                    last_page - first_page + 1);
-       poppler_ps_file_set_paper_size (pdf_document->ps_file, width, height);
-       poppler_ps_file_set_duplex (pdf_document->ps_file, duplex);
+       switch (format) {
+               case EV_FILE_FORMAT_PS:
+                       ctx->ps_file = poppler_ps_file_new (pdf_document->document,
+                                                           filename, first_page,
+                                                           last_page - first_page + 1);
+                       poppler_ps_file_set_paper_size (ctx->ps_file, width, height);
+                       poppler_ps_file_set_duplex (ctx->ps_file, duplex);
+
+                       break;
+               case EV_FILE_FORMAT_PDF: {
+                       cairo_surface_t *surface;
+                       
+                       surface = cairo_pdf_surface_create (filename, width, height);
+                       ctx->pdf_cairo = cairo_create (surface);
+                       cairo_surface_destroy (surface);
+               }
+                       break;
+               default:
+                       g_assert_not_reached ();
+       }
 }
 
 static void
-pdf_document_ps_exporter_do_page (EvPSExporter *exporter, EvRenderContext *rc)
+pdf_document_file_exporter_do_page (EvFileExporter *exporter, EvRenderContext *rc)
 {
        PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
+       PdfPrintContext *ctx = pdf_document->print_ctx;
        PopplerPage *poppler_page;
 
-       g_return_if_fail (pdf_document->ps_file != NULL);
+       g_return_if_fail (pdf_document->print_ctx != NULL);
 
        poppler_page = poppler_document_get_page (pdf_document->document, rc->page);
-       poppler_page_render_to_ps (poppler_page, pdf_document->ps_file);
+
+       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_POPPLER_PAGE_RENDER
+                       poppler_page_render (poppler_page, ctx->pdf_cairo);
+#endif
+                       cairo_show_page (ctx->pdf_cairo);
+                       break;
+               default:
+                       g_assert_not_reached ();
+       }
+       
        g_object_unref (poppler_page);
 }
 
 static void
-pdf_document_ps_exporter_end (EvPSExporter *exporter)
+pdf_document_file_exporter_end (EvFileExporter *exporter)
 {
        PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
 
-       poppler_ps_file_free (pdf_document->ps_file);
-       pdf_document->ps_file = NULL;
+       pdf_print_context_free (pdf_document->print_ctx);
+       pdf_document->print_ctx = NULL;
 }
 
 static void
-pdf_document_ps_exporter_iface_init (EvPSExporterIface *iface)
+pdf_document_file_exporter_iface_init (EvFileExporterIface *iface)
 {
-        iface->begin = pdf_document_ps_exporter_begin;
-        iface->do_page = pdf_document_ps_exporter_do_page;
-        iface->end = pdf_document_ps_exporter_end;
+       iface->format_supported = pdf_document_file_exporter_format_supported;
+        iface->begin = pdf_document_file_exporter_begin;
+        iface->do_page = pdf_document_file_exporter_do_page;
+        iface->end = pdf_document_file_exporter_end;
 }
 
-
 void
 pdf_selection_render_selection (EvSelection      *selection,
                                EvRenderContext  *rc,
index 34579674c302add2e07d0964c4e537ee323c0638..e9c7ca55ea30c1d5ba4561a8d9f2012ee72cc819 100644 (file)
@@ -46,7 +46,7 @@
 #include "ps-document.h"
 #include "ev-debug.h"
 #include "gsdefaults.h"
-#include "ev-ps-exporter.h"
+#include "ev-file-exporter.h"
 #include "ev-async-renderer.h"
 
 #define MAX_BUFSIZE 1024
@@ -70,30 +70,30 @@ struct record_list
 static gboolean broken_pipe = FALSE;
 
 /* Forward declarations */
-static void    ps_document_init                        (PSDocument           *gs);
-static void    ps_document_class_init                  (PSDocumentClass      *klass);
-static void    send_ps                                 (PSDocument           *gs,
-                                                        long                  begin,
-                                                        unsigned int          len,
-                                                        gboolean              close);
-static void    output                                  (gpointer              data,
-                                                        gint                  source,
-                                                        GdkInputCondition     condition);
-static void    input                                   (gpointer              data,
-                                                        gint                  source,
-                                                        GdkInputCondition     condition);
-static void    stop_interpreter                        (PSDocument           *gs);
-static gint    start_interpreter                       (PSDocument           *gs);
-static void    ps_document_document_iface_init         (EvDocumentIface      *iface);
-static void    ps_document_ps_exporter_iface_init      (EvPSExporterIface    *iface);
-static void    ps_async_renderer_iface_init            (EvAsyncRendererIface *iface);
+static void    ps_document_init                        (PSDocument             *gs);
+static void    ps_document_class_init                  (PSDocumentClass        *klass);
+static void    send_ps                                 (PSDocument             *gs,
+                                                        long                    begin,
+                                                        unsigned int            len,
+                                                        gboolean                close);
+static void    output                                  (gpointer                data,
+                                                        gint                    source,
+                                                        GdkInputCondition       condition);
+static void    input                                   (gpointer                data,
+                                                        gint                    source,
+                                                        GdkInputCondition       condition);
+static void    stop_interpreter                        (PSDocument             *gs);
+static gint    start_interpreter                       (PSDocument             *gs);
+static void    ps_document_document_iface_init         (EvDocumentIface        *iface);
+static void    ps_document_file_exporter_iface_init    (EvFileExporterIface    *iface);
+static void    ps_async_renderer_iface_init            (EvAsyncRendererIface   *iface);
 
 G_DEFINE_TYPE_WITH_CODE (PSDocument, ps_document, G_TYPE_OBJECT,
                          {
                                 G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT,
                                                        ps_document_document_iface_init);
-                                G_IMPLEMENT_INTERFACE (EV_TYPE_PS_EXPORTER,
-                                                       ps_document_ps_exporter_iface_init);
+                                G_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER,
+                                                       ps_document_file_exporter_iface_init);
                                 G_IMPLEMENT_INTERFACE (EV_TYPE_ASYNC_RENDERER,
                                                        ps_async_renderer_iface_init);
                         });
@@ -1289,10 +1289,22 @@ ps_async_renderer_iface_init (EvAsyncRendererIface *iface)
        iface->render_pixbuf = ps_async_renderer_render_pixbuf;
 }
 
+static gboolean
+ps_document_file_exporter_format_supported (EvFileExporter      *exporter,
+                                           EvFileExporterFormat format)
+{
+       return (format == EV_FILE_FORMAT_PS);
+}
+
 static void
-ps_document_ps_export_begin (EvPSExporter *exporter, const char *filename,
-                            int first_page, int last_page,
-                             double width, double height, gboolean duplex)
+ps_document_file_exporter_begin (EvFileExporter      *exporter,
+                                EvFileExporterFormat format,
+                                const char          *filename,
+                                int                  first_page,
+                                int                  last_page,
+                                double               width,
+                                double               height,
+                                gboolean             duplex)
 {
        PSDocument *document = PS_DOCUMENT (exporter);
 
@@ -1306,7 +1318,7 @@ ps_document_ps_export_begin (EvPSExporter *exporter, const char *filename,
 }
 
 static void
-ps_document_ps_export_do_page (EvPSExporter *exporter, EvRenderContext *rc)
+ps_document_file_exporter_do_page (EvFileExporter *exporter, EvRenderContext *rc)
 {
        PSDocument *document = PS_DOCUMENT (exporter);
        
@@ -1316,7 +1328,7 @@ ps_document_ps_export_do_page (EvPSExporter *exporter, EvRenderContext *rc)
 }
 
 static void
-ps_document_ps_export_end (EvPSExporter *exporter)
+ps_document_file_exporter_end (EvFileExporter *exporter)
 {
        PSDocument *document = PS_DOCUMENT (exporter);
 
@@ -1333,9 +1345,10 @@ ps_document_ps_export_end (EvPSExporter *exporter)
 }
 
 static void
-ps_document_ps_exporter_iface_init (EvPSExporterIface *iface)
+ps_document_file_exporter_iface_init (EvFileExporterIface *iface)
 {
-       iface->begin = ps_document_ps_export_begin;
-       iface->do_page = ps_document_ps_export_do_page;
-       iface->end = ps_document_ps_export_end;
+       iface->format_supported = ps_document_file_exporter_format_supported;
+       iface->begin = ps_document_file_exporter_begin;
+       iface->do_page = ps_document_file_exporter_do_page;
+       iface->end = ps_document_file_exporter_end;
 }
index 6749c661d7f7f7c14f66c53c8b4a8541f580cca5..3657f6573323ddac45babd5855aee4a03e50659e 100644 (file)
@@ -7,7 +7,7 @@
 #include "ev-document-fonts.h"
 #include "ev-selection.h"
 #include "ev-async-renderer.h"
-#include "ev-ps-exporter.h"
+#include "ev-file-exporter.h"
 #include "ev-window.h"
 
 #include <glib/gstdio.h>
@@ -528,6 +528,7 @@ ev_job_xfer_run (EvJobXfer *job)
 
 EvJob *
 ev_job_print_new (EvDocument    *document,
+                 const gchar   *format,
                  gdouble        width,
                  gdouble        height,
                  EvPrintRange  *ranges,
@@ -543,6 +544,8 @@ ev_job_print_new (EvDocument    *document,
 
        EV_JOB (job)->document = g_object_ref (document);
 
+       job->format = format;
+       
        job->temp_file = NULL;
        job->error = NULL;
 
@@ -636,7 +639,7 @@ ev_job_print_do_page (EvJobPrint *job, gint page)
        EvRenderContext *rc;
 
        rc = ev_render_context_new (0, page, 1.0);
-       ev_ps_exporter_do_page (EV_PS_EXPORTER (document), rc);
+       ev_file_exporter_do_page (EV_FILE_EXPORTER (document), rc);
        g_object_unref (rc);
 }
 
@@ -648,6 +651,7 @@ ev_job_print_run (EvJobPrint *job)
        gint        last_page;
        gint        first_page;
        gint        i;
+       gchar      *filename;
        
        g_return_if_fail (EV_IS_JOB_PRINT (job));
 
@@ -658,8 +662,10 @@ ev_job_print_run (EvJobPrint *job)
        if (job->error)
                g_error_free (job->error);
        job->error = NULL;
-       
-       fd = g_file_open_tmp ("evince_print.ps.XXXXXX", &job->temp_file, &job->error);
+
+       filename = g_strdup_printf ("evince_print.%s.XXXXXX", job->format);
+       fd = g_file_open_tmp (filename, &job->temp_file, &job->error);
+       g_free (filename);
        if (fd <= -1) {
                EV_JOB (job)->finished = TRUE;
                return;
@@ -669,17 +675,21 @@ ev_job_print_run (EvJobPrint *job)
        last_page = ev_print_job_get_last_page (job);
 
        ev_document_doc_mutex_lock ();
-       ev_ps_exporter_begin (EV_PS_EXPORTER (document),
-                             job->temp_file,
-                             MIN (first_page, last_page),
-                             MAX (first_page, last_page),
-                             job->width, job->height, FALSE);
+       ev_file_exporter_begin (EV_FILE_EXPORTER (document),
+                               g_ascii_strcasecmp (job->format, "pdf") == 0 ?
+                               EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS,
+                               job->temp_file,
+                               MIN (first_page, last_page),
+                               MAX (first_page, last_page),
+                               job->width, job->height, FALSE);
+       ev_document_doc_mutex_unlock ();
 
        for (i = 0; i < job->copies; i++) {
                gint page, step;
                
                step = job->reverse ? -1 : 1;
                page = job->reverse ? last_page : first_page;
+               
                while ((job->reverse && (page >= first_page)) ||
                       (!job->reverse && (page <= last_page))) {
                        gint n_pages = 1;
@@ -700,7 +710,9 @@ ev_job_print_run (EvJobPrint *job)
                                n_pages = job->copies;
 
                        for (j = 0; j < n_pages; j++) {
+                               ev_document_doc_mutex_lock ();
                                ev_job_print_do_page (job, page);
+                               ev_document_doc_mutex_unlock ();
                        }
 
                        page += step;
@@ -710,7 +722,8 @@ ev_job_print_run (EvJobPrint *job)
                        break;
        }
 
-       ev_ps_exporter_end (EV_PS_EXPORTER (document));
+       ev_document_doc_mutex_lock ();
+       ev_file_exporter_end (EV_FILE_EXPORTER (document));
        ev_document_doc_mutex_unlock ();
 
        close (fd);
index b91d8228f6b67ffceaea5e4ee7619ee80f615318..43f4496987348f3daa11a652aa5a9a4131e5cdfc 100644 (file)
@@ -188,6 +188,7 @@ struct _EvJobPrint
        EvJob parent;
 
        GError *error;
+       const gchar *format;
        gchar  *temp_file;
        EvPrintRange *ranges;
        gint n_ranges;
@@ -250,6 +251,7 @@ void                ev_job_xfer_run           (EvJobXfer       *xfer);
 /* EvJobPrint */
 GType           ev_job_print_get_type     (void) G_GNUC_CONST;
 EvJob          *ev_job_print_new          (EvDocument      *document,
+                                          const gchar     *format,
                                           gdouble          width,
                                           gdouble          height,
                                           EvPrintRange    *ranges,
index 03927ae6181e11ce8a6e8338d4d2793b22d5dfe8..7ece884f214d8467bcff4b5fdf1d91e941ef0c66 100644 (file)
@@ -40,7 +40,7 @@
 #include "ev-password.h"
 #include "ev-password-view.h"
 #include "ev-properties-dialog.h"
-#include "ev-ps-exporter.h"
+#include "ev-file-exporter.h"
 #include "ev-document-thumbnails.h"
 #include "ev-document-links.h"
 #include "ev-document-fonts.h"
@@ -328,7 +328,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window)
                ok_to_copy = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_COPY);
        }
 
-       if (has_document && !EV_IS_PS_EXPORTER(document))
+       if (has_document && !EV_IS_FILE_EXPORTER(document))
                ok_to_print = FALSE;
 
        
@@ -1742,6 +1742,7 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog,
        gdouble        width;
        gdouble        height;
        GtkPrintPages  print_pages;
+       const gchar   *file_format;
        
        if (response != GTK_RESPONSE_OK) {
                gtk_widget_destroy (GTK_WIDGET (dialog));
@@ -1764,6 +1765,9 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog,
        window->priv->print_page_setup = g_object_ref (
                gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (dialog)));
 
+       file_format = gtk_print_settings_get (window->priv->print_settings,
+                                             GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
+       
        if (!gtk_printer_accepts_ps (window->priv->printer)) {
                GtkWidget *msgdialog;
 
@@ -1825,6 +1829,7 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog,
        reverse = gtk_print_settings_get_reverse (window->priv->print_settings);
        
        window->priv->print_job = ev_job_print_new (window->priv->document,
+                                                   file_format ? file_format : "ps",
                                                    width, height,
                                                    ranges, n_ranges,
                                                    page_set,
@@ -1846,10 +1851,11 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog,
 void
 ev_window_print_range (EvWindow *ev_window, int first_page, int last_page)
 {
-       GtkWidget   *dialog;
-       EvPageCache *page_cache;
-       gint         current_page;
-       gint         document_last_page;
+       GtkWidget           *dialog;
+       EvPageCache         *page_cache;
+       gint                 current_page;
+       gint                 document_last_page;
+       GtkPrintCapabilities capabilities;
 
        g_return_if_fail (EV_IS_WINDOW (ev_window));
        g_return_if_fail (ev_window->priv->document != NULL);
@@ -1881,13 +1887,22 @@ ev_window_print_range (EvWindow *ev_window, int first_page, int last_page)
 
        dialog = gtk_print_unix_dialog_new (_("Print"), GTK_WINDOW (ev_window));
        ev_window->priv->print_dialog = dialog;
+       
+       capabilities = GTK_PRINT_CAPABILITY_PAGE_SET |
+               GTK_PRINT_CAPABILITY_COPIES |
+               GTK_PRINT_CAPABILITY_COLLATE |
+               GTK_PRINT_CAPABILITY_REVERSE |
+               GTK_PRINT_CAPABILITY_SCALE |
+               GTK_PRINT_CAPABILITY_GENERATE_PS;
+       
+       if (EV_IS_FILE_EXPORTER (ev_window->priv->document) &&
+           ev_file_exporter_format_supported (EV_FILE_EXPORTER (ev_window->priv->document),
+                                              EV_FILE_FORMAT_PDF)) {
+               capabilities |= GTK_PRINT_CAPABILITY_GENERATE_PDF;
+       }
+       
        gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dialog),
-                                                      GTK_PRINT_CAPABILITY_PAGE_SET |
-                                                      GTK_PRINT_CAPABILITY_COPIES |
-                                                      GTK_PRINT_CAPABILITY_COLLATE |
-                                                      GTK_PRINT_CAPABILITY_REVERSE |
-                                                      GTK_PRINT_CAPABILITY_SCALE |
-                                                      GTK_PRINT_CAPABILITY_GENERATE_PS);
+                                                      capabilities);
 
        gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (dialog),
                                                current_page);
index 4a532e19579692b08b555649cf446dcc1998e0b3..24af05fbc887705fee05f28162bb30d5c42cf087 100644 (file)
@@ -28,7 +28,7 @@
 #include "tiff-document.h"
 #include "ev-document-misc.h"
 #include "ev-document-thumbnails.h"
-#include "ev-ps-exporter.h"
+#include "ev-file-exporter.h"
 
 struct _TiffDocumentClass
 {
@@ -50,15 +50,15 @@ typedef struct _TiffDocumentClass TiffDocumentClass;
 
 static void tiff_document_document_iface_init (EvDocumentIface *iface);
 static void tiff_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface);
-static void tiff_document_document_ps_exporter_iface_init (EvPSExporterIface *iface);
+static void tiff_document_document_file_exporter_iface_init (EvFileExporterIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (TiffDocument, tiff_document, G_TYPE_OBJECT,
                          { G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT,
                                                  tiff_document_document_iface_init);
                           G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS,
                                                  tiff_document_document_thumbnails_iface_init);
-                          G_IMPLEMENT_INTERFACE (EV_TYPE_PS_EXPORTER,
-                                                 tiff_document_document_ps_exporter_iface_init);
+                          G_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER,
+                                                 tiff_document_document_file_exporter_iface_init);
                         });
 
 static TIFFErrorHandler orig_error_handler = NULL;
@@ -376,10 +376,22 @@ tiff_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface)
 
 /* postscript exporter implementation */
 
+static gboolean
+tiff_document_file_exporter_format_supported (EvFileExporter      *exporter,
+                                             EvFileExporterFormat format)
+{
+       return (format == EV_FILE_FORMAT_PS);
+}
+
 static void
-tiff_document_ps_export_begin (EvPSExporter *exporter, const char *filename,
-                              int first_page, int last_page,
-                              double width, double height, gboolean duplex)
+tiff_document_file_exporter_begin (EvFileExporter      *exporter,
+                                  EvFileExporterFormat format,
+                                  const char          *filename,
+                                  int                  first_page,
+                                  int                  last_page,
+                                  double               width,
+                                  double               height,
+                                  gboolean             duplex)
 {
        TiffDocument *document = TIFF_DOCUMENT (exporter);
 
@@ -387,7 +399,7 @@ tiff_document_ps_export_begin (EvPSExporter *exporter, const char *filename,
 }
 
 static void
-tiff_document_ps_export_do_page (EvPSExporter *exporter, EvRenderContext *rc)
+tiff_document_file_exporter_do_page (EvFileExporter *exporter, EvRenderContext *rc)
 {
        TiffDocument *document = TIFF_DOCUMENT (exporter);
 
@@ -400,7 +412,7 @@ tiff_document_ps_export_do_page (EvPSExporter *exporter, EvRenderContext *rc)
 }
 
 static void
-tiff_document_ps_export_end (EvPSExporter *exporter)
+tiff_document_file_exporter_end (EvFileExporter *exporter)
 {
        TiffDocument *document = TIFF_DOCUMENT (exporter);
 
@@ -410,11 +422,12 @@ tiff_document_ps_export_end (EvPSExporter *exporter)
 }
 
 static void
-tiff_document_document_ps_exporter_iface_init (EvPSExporterIface *iface)
+tiff_document_document_file_exporter_iface_init (EvFileExporterIface *iface)
 {
-       iface->begin = tiff_document_ps_export_begin;
-       iface->do_page = tiff_document_ps_export_do_page;
-       iface->end = tiff_document_ps_export_end;
+       iface->format_supported = tiff_document_file_exporter_format_supported;
+       iface->begin = tiff_document_file_exporter_begin;
+       iface->do_page = tiff_document_file_exporter_do_page;
+       iface->end = tiff_document_file_exporter_end;
 }
 
 static void