#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;
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;
static void pdf_document_search_free (PdfDocumentSearch *search);
static void pdf_print_context_free (PdfPrintContext *ctx);
+#ifdef HAVE_FORMS
G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
{
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT,
pdf_document_document_links_iface_init);
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_IMAGES,
pdf_document_document_images_iface_init);
-#ifdef HAVE_FORMS
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FORMS,
pdf_document_document_forms_iface_init);
-#endif /* HAVE_FORMS */
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FONTS,
pdf_document_document_fonts_iface_init);
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_TRANSITION,
pdf_document_page_transition_iface_init);
});
-
+#else /* !HAVE_FORMS */
+G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
+ {
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT,
+ pdf_document_document_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_SECURITY,
+ pdf_document_security_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS,
+ pdf_document_document_thumbnails_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_LINKS,
+ pdf_document_document_links_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_IMAGES,
+ pdf_document_document_images_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FONTS,
+ pdf_document_document_fonts_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
+ pdf_document_find_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);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_TRANSITION,
+ pdf_document_page_transition_iface_init);
+ });
+#endif /* HAVE_FORMS */
static void
set_rc_data (PdfDocument *pdf_document,
g_return_val_if_fail (poppler_page != NULL, NULL);
pixbuf = poppler_page_get_thumbnail (poppler_page);
- if (!pixbuf) {
+ if (pixbuf) {
+ /* Rotate provided thumbnail if needed */
+ GdkPixbuf *rotated_pixbuf;
+
+ rotated_pixbuf = gdk_pixbuf_rotate_simple (pixbuf,
+ (GdkPixbufRotation) (360 - rc->rotation));
+ g_object_unref (pixbuf);
+ pixbuf = rotated_pixbuf;
+ } else {
/* There is no provided thumbnail. We need to make one. */
pixbuf = make_thumbnail_for_page (pdf_document, poppler_page, rc);
}
iface->cancel = pdf_document_find_cancel;
}
-static const gboolean supported_formats[] = {
- TRUE, /* EV_FILE_FORMAT_PS */
-#ifdef HAVE_CAIRO_PDF
-#ifdef HAVE_POPPLER_PAGE_RENDER
- TRUE, /* EV_FILE_FORMAT_PDF */
-#else
- FALSE, /* EV_FILE_FORMAT_PDF */
-#endif
-#endif
-};
-
static void
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);
}
-static gboolean
-pdf_document_file_exporter_format_supported (EvFileExporter *exporter,
- EvFileExporterFormat format)
-{
- return supported_formats[format];
-}
-
static void
-pdf_document_file_exporter_begin (EvFileExporter *exporter,
- EvFileExporterFormat format,
- const char *filename,
- int first_page,
- int last_page,
- double width,
- double height,
- gboolean duplex)
+pdf_document_file_exporter_begin (EvFileExporter *exporter,
+ EvFileExporterContext *fc)
{
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 = format;
-
- switch (format) {
+ 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,
- 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);
-
+ 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 (filename, width, 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
-pdf_document_file_exporter_do_page (EvFileExporter *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;
+#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);
}
pdf_document->print_ctx = NULL;
}
+static EvFileExporterCapabilities
+pdf_document_file_exporter_get_capabilities (EvFileExporter *exporter)
+{
+ return (EvFileExporterCapabilities) (
+ EV_FILE_EXPORTER_CAN_PAGE_SET |
+ EV_FILE_EXPORTER_CAN_COPIES |
+ 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 |
+#endif
+#endif
+ EV_FILE_EXPORTER_CAN_GENERATE_PS);
+}
+
static void
pdf_document_file_exporter_iface_init (EvFileExporterIface *iface)
{
- 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;
+ iface->get_capabilities = pdf_document_file_exporter_get_capabilities;
}
static void
field_text->do_scroll = poppler_form_field_text_do_scroll (poppler_field);
field_text->is_rich_text = poppler_form_field_text_is_rich_text (poppler_field);
field_text->is_password = poppler_form_field_text_is_password (poppler_field);
-
+
+#ifdef HAVE_POPPLER_FORM_FIELD_TEXT_GET_MAX_LEN
+ field_text->max_len = poppler_form_field_text_get_max_len (poppler_field);
+#endif
field_text->text = poppler_form_field_text_get_text (poppler_field);
}