#include "config.h"
-#ifdef HAVE_POPPLER_FORM_FIELD_BUTTON_GET_BUTTON_TYPE
-#define HAVE_FORMS
-#endif
-
#include <math.h>
#include <string.h>
#include <gtk/gtk.h>
#include "ev-document-transition.h"
#include "ev-document-forms.h"
#include "ev-selection.h"
+#include "ev-transition-effect.h"
#include "ev-attachment.h"
#include "ev-image.h"
-#if defined (HAVE_CAIRO_PDF) || defined (HAVE_CAIRO_PS)
+#if (defined (HAVE_POPPLER_PAGE_RENDER) || defined (HAVE_POPPLER_PAGE_RENDER_FOR_PRINTING)) && (defined (HAVE_CAIRO_PDF) || defined (HAVE_CAIRO_PS))
#define HAVE_CAIRO_PRINT
#endif
typedef struct {
EvFileExporterFormat format;
- gboolean landscape;
-
/* Pages per sheet */
gint pages_per_sheet;
gint pages_printed;
gint pages_x;
gint pages_y;
- gdouble page_width;
- gdouble page_height;
+ gdouble paper_width;
+ gdouble paper_height;
#ifdef HAVE_CAIRO_PRINT
cairo_t *cr;
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_iface_init);
+EV_BACKEND_REGISTER_WITH_CODE (PdfDocument, pdf_document,
+ {
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_SECURITY,
pdf_document_security_iface_init);
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS,
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,
ev_dest = ev_link_dest_new_xyz (dest->page_num - 1,
dest->left,
height - dest->top,
- dest->zoom);
+ dest->zoom,
+ dest->change_left,
+ dest->change_top,
+ dest->change_zoom);
g_object_unref (poppler_page);
}
break;
MAX (0, dest->page_num - 1));
poppler_page_get_size (poppler_page, NULL, &height);
ev_dest = ev_link_dest_new_fith (dest->page_num - 1,
- height - dest->top);
+ height - dest->top,
+ dest->change_top);
g_object_unref (poppler_page);
}
break;
case POPPLER_DEST_FITV:
ev_dest = ev_link_dest_new_fitv (dest->page_num - 1,
- dest->left);
+ dest->left,
+ dest->change_left);
break;
case POPPLER_DEST_FITR: {
PopplerPage *poppler_page;
break;
}
- if (!link) {
+ if (!link || strlen (ev_link_get_title (link)) <= 0) {
poppler_action_free (action);
+ if (link)
+ g_object_unref (link);
+
continue;
}
}
static GList *
-pdf_document_images_get_images (EvDocumentImages *document_images,
- gint page)
+pdf_document_images_get_image_mapping (EvDocumentImages *document_images,
+ gint page)
{
GList *retval = NULL;
PdfDocument *pdf_document;
image_mapping = (PopplerImageMapping *)list->data;
ev_image_mapping = g_new (EvImageMapping, 1);
-
+#ifdef HAVE_POPPLER_PAGE_GET_IMAGE
+ ev_image_mapping->image = ev_image_new (page, image_mapping->image_id);
+#else
ev_image_mapping->image = ev_image_new_from_pixbuf (image_mapping->image);
+#endif
ev_image_mapping->x1 = image_mapping->area.x1;
ev_image_mapping->x2 = image_mapping->area.x2;
ev_image_mapping->y1 = image_mapping->area.y1;
return retval;
}
+GdkPixbuf *
+pdf_document_images_get_image (EvDocumentImages *document_images,
+ EvImage *image)
+{
+#ifdef HAVE_POPPLER_PAGE_GET_IMAGE
+ PdfDocument *pdf_document;
+ PopplerPage *poppler_page;
+ cairo_surface_t *surface;
+ GdkPixbuf *retval = NULL;
+
+ pdf_document = PDF_DOCUMENT (document_images);
+ poppler_page = poppler_document_get_page (pdf_document->document,
+ ev_image_get_page (image));
+
+ surface = poppler_page_get_image (poppler_page, ev_image_get_id (image));
+ if (surface) {
+ retval = ev_document_misc_pixbuf_from_surface (surface);
+ cairo_surface_destroy (surface);
+ }
+
+ g_object_unref (poppler_page);
+
+ return retval;
+#else
+ return GDK_PIXBUF (g_object_ref (ev_image_get_pixbuf (image)));
+#endif /* HAVE_POPPLER_PAGE_GET_IMAGE */
+}
+
static void
pdf_document_document_images_iface_init (EvDocumentImagesIface *iface)
{
- iface->get_images = pdf_document_images_get_images;
+ iface->get_image_mapping = pdf_document_images_get_image_mapping;
+ iface->get_image = pdf_document_images_get_image;
}
static GdkPixbuf *
{
PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
PdfPrintContext *ctx;
- gdouble width, height;
- gboolean landscape, change_orient = FALSE;
#ifdef HAVE_CAIRO_PRINT
+ gdouble width, height;
cairo_surface_t *surface = NULL;
#endif
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;
+
+#ifdef HAVE_CAIRO_PRINT
+ ctx->pages_per_sheet = CLAMP (fc->pages_per_sheet, 1, 16);
- landscape = (fc->orientation == EV_FILE_EXPORTER_LANDSCAPE);
- change_orient = landscape;
+ ctx->paper_width = fc->paper_width;
+ ctx->paper_height = fc->paper_height;
switch (fc->pages_per_sheet) {
default:
ctx->pages_y = 1;
break;
case 2:
- landscape = !landscape;
ctx->pages_x = 1;
ctx->pages_y = 2;
break;
ctx->pages_y = 2;
break;
case 6:
- landscape = !landscape;
ctx->pages_x = 2;
ctx->pages_y = 3;
break;
break;
}
- ctx->landscape = landscape;
-
- if (change_orient) {
- width = fc->paper_height;
- height = fc->paper_width;
- } else {
- width = fc->paper_width;
- height = fc->paper_height;
- }
-
- if (landscape) {
- gint tmp;
-
- tmp = ctx->pages_x;
- ctx->pages_x = ctx->pages_y;
- ctx->pages_y = tmp;
-
- ctx->page_width = height / ctx->pages_x;
- ctx->page_height = width / ctx->pages_y;
- } else {
- 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 */
+ surface = cairo_ps_surface_create (fc->filename, fc->paper_width, fc->paper_height);
+#endif
break;
case EV_FILE_FORMAT_PDF:
#ifdef HAVE_CAIRO_PDF
- surface = cairo_pdf_surface_create (fc->filename, width, height);
+ surface = cairo_pdf_surface_create (fc->filename, fc->paper_width, fc->paper_height);
#endif
break;
default:
g_assert_not_reached ();
}
-#ifdef HAVE_CAIRO_PRINT
ctx->cr = cairo_create (surface);
- if (landscape) {
- cairo_matrix_t matrix;
-
- cairo_translate (ctx->cr, width, 0);
- cairo_matrix_init (&matrix,
- 0, 1,
- -1, 0,
- 0, 0);
- cairo_transform (ctx->cr, &matrix);
- }
cairo_surface_destroy (surface);
-#endif
+
+#else /* HAVE_CAIRO_PRINT */
+ if (ctx->format == EV_FILE_FORMAT_PS) {
+ 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_PRINT */
+}
+
+static void
+pdf_document_file_exporter_begin_page (EvFileExporter *exporter)
+{
+ PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
+ PdfPrintContext *ctx = pdf_document->print_ctx;
+
+ g_return_if_fail (pdf_document->print_ctx != NULL);
+
+ ctx->pages_printed = 0;
+
+#ifdef HAVE_CAIRO_PRINT
+ if (ctx->paper_width > ctx->paper_height) {
+ if (ctx->format == EV_FILE_FORMAT_PS) {
+ cairo_ps_surface_set_size (cairo_get_target (ctx->cr),
+ ctx->paper_height,
+ ctx->paper_width);
+ } else if (ctx->format == EV_FILE_FORMAT_PDF) {
+ cairo_pdf_surface_set_size (cairo_get_target (ctx->cr),
+ ctx->paper_height,
+ ctx->paper_width);
+ }
+ }
+#endif /* HAVE_CAIRO_PRINT */
}
static void
PdfPrintContext *ctx = pdf_document->print_ctx;
PopplerPage *poppler_page;
#ifdef HAVE_CAIRO_PRINT
- gdouble page_width, page_height;
- gint x, y;
+ gdouble page_width, page_height;
+ gint x, y;
+ gboolean rotate, landscape;
+ gdouble width, height;
+ gdouble pwidth, pheight;
+ gdouble xscale, yscale;
#endif
g_return_if_fail (pdf_document->print_ctx != NULL);
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);
- if (ctx->landscape) {
- cairo_scale (ctx->cr,
- ctx->page_height / page_height,
- ctx->page_height / page_height);
+
+ if (page_width > page_height && page_width > ctx->paper_width) {
+ rotate = TRUE;
} else {
- cairo_scale (ctx->cr,
- ctx->page_width / page_width,
- ctx->page_height / page_height);
+ rotate = FALSE;
+ }
+
+ landscape = (ctx->paper_width > ctx->paper_height);
+
+ /* Use always portrait mode and rotate when necessary */
+ if (ctx->paper_width > ctx->paper_height) {
+ width = ctx->paper_height;
+ height = ctx->paper_width;
+ rotate = !rotate;
+ } else {
+ width = ctx->paper_width;
+ height = ctx->paper_height;
+ }
+
+ if (ctx->pages_per_sheet == 2 || ctx->pages_per_sheet == 6) {
+ rotate = !rotate;
+ }
+
+ if (rotate) {
+ gint tmp1;
+ gdouble tmp2;
+
+ tmp1 = x;
+ x = y;
+ y = tmp1;
+
+ tmp2 = page_width;
+ page_width = page_height;
+ page_height = tmp2;
+ }
+
+ pwidth = width / ctx->pages_x;
+ pheight = height / ctx->pages_y;
+
+ if ((page_width > pwidth || page_height > pheight) ||
+ (page_width < pwidth && page_height < pheight)) {
+ xscale = pwidth / page_width;
+ yscale = pheight / page_height;
+
+ if (yscale < xscale) {
+ xscale = yscale;
+ } else {
+ yscale = xscale;
+ }
+
+ } else {
+ xscale = yscale = 1;
}
+ /* TODO: center */
+
+ cairo_save (ctx->cr);
+ if (rotate) {
+ cairo_matrix_t matrix;
+
+ cairo_translate (ctx->cr, width, 0);
+ cairo_matrix_init (&matrix,
+ 0, 1,
+ -1, 0,
+ 0, 0);
+ cairo_transform (ctx->cr, &matrix);
+ }
+
+ cairo_translate (ctx->cr,
+ x * (rotate ? pheight : pwidth),
+ y * (rotate ? pwidth : pheight));
+ cairo_scale (ctx->cr, xscale, yscale);
+
+#ifdef HAVE_POPPLER_PAGE_RENDER_FOR_PRINTING
+ poppler_page_render_for_printing (poppler_page, ctx->cr);
+#else
#ifdef HAVE_POPPLER_PAGE_RENDER
poppler_page_render (poppler_page, ctx->cr);
#endif
+#endif
+
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)
g_object_unref (poppler_page);
}
+static void
+pdf_document_file_exporter_end_page (EvFileExporter *exporter)
+{
+ PdfDocument *pdf_document = PDF_DOCUMENT (exporter);
+ PdfPrintContext *ctx = pdf_document->print_ctx;
+
+ g_return_if_fail (pdf_document->print_ctx != NULL);
+
+#ifdef HAVE_CAIRO_PRINT
+ cairo_show_page (ctx->cr);
+#endif
+}
+
static void
pdf_document_file_exporter_end (EvFileExporter *exporter)
{
pdf_document_file_exporter_iface_init (EvFileExporterIface *iface)
{
iface->begin = pdf_document_file_exporter_begin;
+ iface->begin_page = pdf_document_file_exporter_begin_page;
iface->do_page = pdf_document_file_exporter_do_page;
+ iface->end_page = pdf_document_file_exporter_end_page;
iface->end = pdf_document_file_exporter_end;
iface->get_capabilities = pdf_document_file_exporter_get_capabilities;
}
return duration;
}
-static void
-pdf_document_page_transition_iface_init (EvDocumentTransitionIface *iface)
+static EvTransitionEffect *
+pdf_document_get_effect (EvDocumentTransition *trans,
+ gint page)
{
- iface->get_page_duration = pdf_document_get_page_duration;
+ PdfDocument *pdf_document;
+ PopplerPage *poppler_page;
+ PopplerPageTransition *page_transition;
+ EvTransitionEffect *effect;
+
+ pdf_document = PDF_DOCUMENT (trans);
+ poppler_page = poppler_document_get_page (pdf_document->document, page);
+
+ if (!poppler_page)
+ return NULL;
+
+ page_transition = poppler_page_get_transition (poppler_page);
+
+ if (!page_transition) {
+ g_object_unref (poppler_page);
+ return NULL;
+ }
+
+ /* enums in PopplerPageTransition match the EvTransitionEffect ones */
+ effect = ev_transition_effect_new ((EvTransitionEffectType) page_transition->type,
+ "alignment", page_transition->alignment,
+ "direction", page_transition->direction,
+ "duration", page_transition->duration,
+ "angle", page_transition->angle,
+ "scale", page_transition->scale,
+ "rectangular", page_transition->rectangular,
+ NULL);
+
+ poppler_page_transition_free (page_transition);
+ g_object_unref (poppler_page);
+
+ return effect;
}
-PdfDocument *
-pdf_document_new (void)
+static void
+pdf_document_page_transition_iface_init (EvDocumentTransitionIface *iface)
{
- return PDF_DOCUMENT (g_object_new (PDF_TYPE_DOCUMENT, NULL));
+ iface->get_page_duration = pdf_document_get_page_duration;
+ iface->get_effect = pdf_document_get_effect;
}
/* Forms */
rect->y2 = poppler_rect.y2;
}
-#ifdef HAVE_FORMS
static EvFormField *
ev_form_field_from_poppler_field (PopplerFormField *poppler_field)
{
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);
}
ev_field = ev_form_field_signature_new (id);
break;
case POPPLER_FORM_FIELD_UNKNOWN:
- break;
+ return NULL;
}
ev_field->font_size = font_size;
GList *fields;
GList *list;
double height;
-
pdf_document = PDF_DOCUMENT (document);
poppler_page = poppler_document_get_page (pdf_document->document, page);
for (list = fields; list; list = list->next) {
PopplerFormFieldMapping *mapping;
EvFormFieldMapping *field_mapping;
-
+ EvFormField *ev_field;
+
mapping = (PopplerFormFieldMapping *)list->data;
+ ev_field = ev_form_field_from_poppler_field (mapping->field);
+ if (!ev_field)
+ continue;
+
field_mapping = g_new0 (EvFormFieldMapping, 1);
field_mapping->x1 = mapping->area.x1;
field_mapping->x2 = mapping->area.x2;
field_mapping->y1 = height - mapping->area.y2;
field_mapping->y2 = height - mapping->area.y1;
- field_mapping->field = ev_form_field_from_poppler_field (mapping->field);
+ field_mapping->field = ev_field;
field_mapping->field->page = page;
retval = g_list_prepend (retval, field_mapping);
}
+
poppler_page_free_form_field_mapping (fields);
g_object_unref (poppler_page);
iface->form_field_choice_set_text = pdf_document_forms_form_field_choice_set_text;
iface->form_field_choice_get_text = pdf_document_forms_form_field_choice_get_text;
}
-#endif /* HAVE_FORMS */
+