From 4094f85bec2a1f27274e42411555fc1ede846775 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Sun, 03 Dec 2006 20:35:46 +0000 Subject: Allow printing to PDF when suppoted by the backend. 2006-12-03 Carlos Garcia Campos * 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. --- diff --git a/ChangeLog b/ChangeLog index 98f8865..d52d023 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2006-12-03 Carlos Garcia Campos + * 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 + * shell/ev-window.c: (build_comments_string): Use always "Document Viewer" in about dialog. diff --git a/backend/Makefile.am b/backend/Makefile.am index bcf975a..2de2f5f 100644 --- a/backend/Makefile.am +++ b/backend/Makefile.am @@ -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 index 0000000..7a4e902 --- /dev/null +++ b/backend/ev-file-exporter.c @@ -0,0 +1,91 @@ +/* this file is part of evince, a gnome document viewer + * + * Copyright (C) 2004 Martin Kretzschmar + * + * Author: + * Martin Kretzschmar + * + * 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 index 0000000..f0e517c --- /dev/null +++ b/backend/ev-file-exporter.h @@ -0,0 +1,84 @@ +/* this file is part of evince, a gnome document viewer + * + * Copyright (C) 2004 Martin Kretzschmar + * + * Author: + * Martin Kretzschmar + * + * 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 + +#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 index 18c3536..0000000 --- a/backend/ev-ps-exporter.c +++ /dev/null @@ -1,74 +0,0 @@ -/* this file is part of evince, a gnome document viewer - * - * Copyright (C) 2004 Martin Kretzschmar - * - * Author: - * Martin Kretzschmar - * - * 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 index 4115e3a..0000000 --- a/backend/ev-ps-exporter.h +++ /dev/null @@ -1,68 +0,0 @@ -/* this file is part of evince, a gnome document viewer - * - * Copyright (C) 2004 Martin Kretzschmar - * - * Author: - * Martin Kretzschmar - * - * 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 - -#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 diff --git a/configure.ac b/configure.ac index a299f09..3042199 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/pdf/ev-poppler.cc b/pdf/ev-poppler.cc index dc5510e..a90c524 100644 --- a/pdf/ev-poppler.cc +++ b/pdf/ev-poppler.cc @@ -17,16 +17,19 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include #include #include #include #include +#include #include #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, diff --git a/ps/ps-document.c b/ps/ps-document.c index 3457967..e9c7ca5 100644 --- a/ps/ps-document.c +++ b/ps/ps-document.c @@ -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; } diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c index 6749c66..3657f65 100644 --- a/shell/ev-jobs.c +++ b/shell/ev-jobs.c @@ -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 @@ -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); diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h index b91d822..43f4496 100644 --- a/shell/ev-jobs.h +++ b/shell/ev-jobs.h @@ -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, diff --git a/shell/ev-window.c b/shell/ev-window.c index 03927ae..7ece884 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -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); diff --git a/tiff/tiff-document.c b/tiff/tiff-document.c index 4a532e1..24af05f 100644 --- a/tiff/tiff-document.c +++ b/tiff/tiff-document.c @@ -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 -- cgit v0.9.1