X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=backend%2Fpdf%2Fev-poppler.cc;h=5b0398047c458ec8e84f286739270951c9b20a58;hb=f792ebcef8eab6e0b8fc5ff185851d038afbab56;hp=09edfb4165ea8067817d2fdce9ef4d87df0d3e9f;hpb=982600bbceb76a22d5c7b3e0cbe6e20421105ad6;p=evince.git diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc index 09edfb41..5b039804 100644 --- a/backend/pdf/ev-poppler.cc +++ b/backend/pdf/ev-poppler.cc @@ -19,10 +19,6 @@ #include "config.h" -#ifdef HAVE_POPPLER_FORM_FIELD_BUTTON_GET_BUTTON_TYPE -#define HAVE_FORMS -#endif - #include #include #include @@ -52,7 +48,7 @@ #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 @@ -68,15 +64,13 @@ typedef struct { 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; @@ -129,11 +123,8 @@ static EvLink *ev_link_from_action (PdfDocument *pdf_document, 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, @@ -155,31 +146,6 @@ G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT, 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, @@ -891,7 +857,10 @@ ev_link_dest_from_dest (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; @@ -906,13 +875,15 @@ ev_link_dest_from_dest (PdfDocument *pdf_document, 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; @@ -1062,8 +1033,11 @@ build_tree (PdfDocument *pdf_document, break; } - if (!link) { + if (!link || strlen (ev_link_get_title (link)) <= 0) { poppler_action_free (action); + if (link) + g_object_unref (link); + continue; } @@ -1549,9 +1523,8 @@ pdf_document_file_exporter_begin (EvFileExporter *exporter, { 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 @@ -1560,10 +1533,12 @@ pdf_document_file_exporter_begin (EvFileExporter *exporter, 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: @@ -1572,7 +1547,6 @@ pdf_document_file_exporter_begin (EvFileExporter *exporter, ctx->pages_y = 1; break; case 2: - landscape = !landscape; ctx->pages_x = 1; ctx->pages_y = 2; break; @@ -1581,7 +1555,6 @@ pdf_document_file_exporter_begin (EvFileExporter *exporter, ctx->pages_y = 2; break; case 6: - landscape = !landscape; ctx->pages_x = 2; ctx->pages_y = 3; break; @@ -1595,67 +1568,60 @@ pdf_document_file_exporter_begin (EvFileExporter *exporter, 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 @@ -1666,8 +1632,12 @@ pdf_document_file_exporter_do_page (EvFileExporter *exporter, 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); @@ -1678,29 +1648,89 @@ pdf_document_file_exporter_do_page (EvFileExporter *exporter, 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) @@ -1710,6 +1740,19 @@ pdf_document_file_exporter_do_page (EvFileExporter *exporter, 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) { @@ -1748,7 +1791,9 @@ static void 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; } @@ -1928,12 +1973,6 @@ pdf_document_page_transition_iface_init (EvDocumentTransitionIface *iface) iface->get_page_duration = pdf_document_get_page_duration; } -PdfDocument * -pdf_document_new (void) -{ - return PDF_DOCUMENT (g_object_new (PDF_TYPE_DOCUMENT, NULL)); -} - /* Forms */ static void pdf_document_get_crop_box (EvDocument *document, @@ -1953,7 +1992,6 @@ pdf_document_get_crop_box (EvDocument *document, rect->y2 = poppler_rect.y2; } -#ifdef HAVE_FORMS static EvFormField * ev_form_field_from_poppler_field (PopplerFormField *poppler_field) { @@ -1990,10 +2028,7 @@ 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); } @@ -2052,7 +2087,7 @@ ev_form_field_from_poppler_field (PopplerFormField *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; @@ -2071,7 +2106,6 @@ pdf_document_forms_get_form_fields (EvDocumentForms *document, GList *fields; GList *list; double height; - pdf_document = PDF_DOCUMENT (document); poppler_page = poppler_document_get_page (pdf_document->document, page); @@ -2081,19 +2115,25 @@ pdf_document_forms_get_form_fields (EvDocumentForms *document, 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); @@ -2322,4 +2362,4 @@ pdf_document_document_forms_iface_init (EvDocumentFormsIface *iface) 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 */ +