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=4b6b114e23b7b0d97b0773c9d67694fab83b442d;hb=e70119b293ab8a26bdea4a56407bb0f41f1e43aa;hp=e3b80b450d8d93e02fc5232fe442500613c3c2d0;hpb=217797d63b2d3b1c9a7a0511af1bbf3d99f0d482;p=evince.git diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc index e3b80b45..4b6b114e 100644 --- a/backend/pdf/ev-poppler.cc +++ b/backend/pdf/ev-poppler.cc @@ -19,6 +19,10 @@ #include "config.h" +#ifdef HAVE_POPPLER_FORM_FIELD_BUTTON_GET_BUTTON_TYPE +#define HAVE_FORMS +#endif + #include #include #include @@ -40,6 +44,7 @@ #include "ev-document-security.h" #include "ev-document-thumbnails.h" #include "ev-document-transition.h" +#include "ev-document-forms.h" #include "ev-selection.h" #include "ev-attachment.h" #include "ev-image.h" @@ -86,6 +91,7 @@ static void pdf_document_security_iface_init (EvDocumentSecurityIface static void pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface); static void pdf_document_document_links_iface_init (EvDocumentLinksIface *iface); static void pdf_document_document_images_iface_init (EvDocumentImagesIface *iface); +static void pdf_document_document_forms_iface_init (EvDocumentFormsIface *iface); static void pdf_document_document_fonts_iface_init (EvDocumentFontsIface *iface); static void pdf_document_find_iface_init (EvDocumentFindIface *iface); static void pdf_document_file_exporter_iface_init (EvFileExporterIface *iface); @@ -104,7 +110,6 @@ 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); - G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT, { G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT, @@ -117,6 +122,10 @@ G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT, 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, @@ -448,7 +457,7 @@ pdf_document_render (EvDocument *document, width = (int) ((width_points * rc->scale) + 0.5); height = (int) ((height_points * rc->scale) + 0.5); } - + #ifdef HAVE_POPPLER_PAGE_RENDER cairo_t *cr; @@ -1283,10 +1292,10 @@ pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnail poppler_page_get_size (poppler_page, &page_width, &page_height); - *width = (gint) (page_width * rc->scale); - *height = (gint) (page_height * rc->scale); + *width = (gint) MAX (page_width * rc->scale, 1); + *height = (gint) MAX (page_height * rc->scale, 1); } - + if (rc->rotation == 90 || rc->rotation == 270) { gint temp; @@ -1497,17 +1506,6 @@ 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_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) { @@ -1527,22 +1525,9 @@ pdf_print_context_free (PdfPrintContext *ctx) 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; @@ -1551,22 +1536,22 @@ pdf_document_file_exporter_begin (EvFileExporter *exporter, pdf_print_context_free (pdf_document->print_ctx); pdf_document->print_ctx = g_new0 (PdfPrintContext, 1); ctx = pdf_document->print_ctx; - ctx->format = format; + ctx->format = fc->format; - switch (format) { + switch (fc->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); + 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); break; case EV_FILE_FORMAT_PDF: { #ifdef HAVE_CAIRO_PDF cairo_surface_t *surface; - surface = cairo_pdf_surface_create (filename, width, height); + surface = cairo_pdf_surface_create (fc->filename, fc->paper_width, fc->paper_height); ctx->pdf_cairo = cairo_create (surface); cairo_surface_destroy (surface); #endif @@ -1578,7 +1563,8 @@ pdf_document_file_exporter_begin (EvFileExporter *exporter, } 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; @@ -1620,13 +1606,30 @@ pdf_document_file_exporter_end (EvFileExporter *exporter) 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_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 @@ -1775,3 +1778,393 @@ pdf_document_new (void) { return PDF_DOCUMENT (g_object_new (PDF_TYPE_DOCUMENT, NULL)); } + +/* Forms */ +static void +pdf_document_get_crop_box (EvDocument *document, + int page, + EvRectangle *rect) +{ + PdfDocument *pdf_document; + PopplerPage *poppler_page; + PopplerRectangle poppler_rect; + + pdf_document = PDF_DOCUMENT (document); + poppler_page = poppler_document_get_page (pdf_document->document, page); + poppler_page_get_crop_box (poppler_page, &poppler_rect); + rect->x1 = poppler_rect.x1; + rect->x2 = poppler_rect.x2; + rect->y1 = poppler_rect.y1; + rect->y2 = poppler_rect.y2; +} + +#ifdef HAVE_FORMS +static EvFormField * +ev_form_field_from_poppler_field (PopplerFormField *poppler_field) +{ + EvFormField *ev_field = NULL; + gint id; + gdouble font_size; + gboolean is_read_only; + + id = poppler_form_field_get_id (poppler_field); + font_size = poppler_form_field_get_font_size (poppler_field); + is_read_only = poppler_form_field_is_read_only (poppler_field); + + switch (poppler_form_field_get_field_type (poppler_field)) { + case POPPLER_FORM_FIELD_TEXT: { + EvFormFieldText *field_text; + EvFormFieldTextType ev_text_type = EV_FORM_FIELD_TEXT_NORMAL; + + switch (poppler_form_field_text_get_text_type (poppler_field)) { + case POPPLER_FORM_TEXT_NORMAL: + ev_text_type = EV_FORM_FIELD_TEXT_NORMAL; + break; + case POPPLER_FORM_TEXT_MULTILINE: + ev_text_type = EV_FORM_FIELD_TEXT_MULTILINE; + break; + case POPPLER_FORM_TEXT_FILE_SELECT: + ev_text_type = EV_FORM_FIELD_TEXT_FILE_SELECT; + break; + } + + ev_field = ev_form_field_text_new (id, ev_text_type); + field_text = EV_FORM_FIELD_TEXT (ev_field); + + field_text->do_spell_check = poppler_form_field_text_do_spell_check (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); + + } + break; + case POPPLER_FORM_FIELD_BUTTON: { + EvFormFieldButton *field_button; + EvFormFieldButtonType ev_button_type = EV_FORM_FIELD_BUTTON_PUSH; + + switch (poppler_form_field_button_get_button_type (poppler_field)) { + case POPPLER_FORM_BUTTON_PUSH: + ev_button_type = EV_FORM_FIELD_BUTTON_PUSH; + break; + case POPPLER_FORM_BUTTON_CHECK: + ev_button_type = EV_FORM_FIELD_BUTTON_CHECK; + break; + case POPPLER_FORM_BUTTON_RADIO: + ev_button_type = EV_FORM_FIELD_BUTTON_RADIO; + break; + } + + ev_field = ev_form_field_button_new (id, ev_button_type); + field_button = EV_FORM_FIELD_BUTTON (ev_field); + + field_button->state = poppler_form_field_button_get_state (poppler_field); + } + break; + case POPPLER_FORM_FIELD_CHOICE: { + EvFormFieldChoice *field_choice; + EvFormFieldChoiceType ev_choice_type = EV_FORM_FIELD_CHOICE_COMBO; + + switch (poppler_form_field_choice_get_choice_type (poppler_field)) { + case POPPLER_FORM_CHOICE_COMBO: + ev_choice_type = EV_FORM_FIELD_CHOICE_COMBO; + break; + case EV_FORM_FIELD_CHOICE_LIST: + ev_choice_type = EV_FORM_FIELD_CHOICE_LIST; + break; + } + + ev_field = ev_form_field_choice_new (id, ev_choice_type); + field_choice = EV_FORM_FIELD_CHOICE (ev_field); + + field_choice->is_editable = poppler_form_field_choice_is_editable (poppler_field); + field_choice->multi_select = poppler_form_field_choice_can_select_multiple (poppler_field); + field_choice->do_spell_check = poppler_form_field_choice_do_spell_check (poppler_field); + field_choice->commit_on_sel_change = poppler_form_field_choice_commit_on_change (poppler_field); + + /* TODO: we need poppler_form_field_choice_get_selected_items in poppler + field_choice->selected_items = poppler_form_field_choice_get_selected_items (poppler_field);*/ + if (field_choice->is_editable) + field_choice->text = poppler_form_field_choice_get_text (poppler_field); + } + break; + case POPPLER_FORM_FIELD_SIGNATURE: + /* TODO */ + ev_field = ev_form_field_signature_new (id); + break; + case POPPLER_FORM_FIELD_UNKNOWN: + break; + } + + ev_field->font_size = font_size; + ev_field->is_read_only = is_read_only; + + return ev_field; +} + +static GList * +pdf_document_forms_get_form_fields (EvDocumentForms *document, + gint page) +{ + PdfDocument *pdf_document; + PopplerPage *poppler_page; + GList *retval = NULL; + GList *fields; + GList *list; + double height; + + + pdf_document = PDF_DOCUMENT (document); + poppler_page = poppler_document_get_page (pdf_document->document, page); + fields = poppler_page_get_form_field_mapping (poppler_page); + poppler_page_get_size (poppler_page, NULL, &height); + + for (list = fields; list; list = list->next) { + PopplerFormFieldMapping *mapping; + EvFormFieldMapping *field_mapping; + + mapping = (PopplerFormFieldMapping *)list->data; + + 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->page = page; + + retval = g_list_prepend (retval, field_mapping); + } + poppler_page_free_form_field_mapping (fields); + g_object_unref (poppler_page); + + return g_list_reverse (retval); +} + +static gchar * +pdf_document_forms_form_field_text_get_text (EvDocumentForms *document, + EvFormField *field) + +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + gchar *text; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return NULL; + + text = poppler_form_field_text_get_text (poppler_field); + g_object_unref (poppler_field); + + return text; +} + +static void +pdf_document_forms_form_field_text_set_text (EvDocumentForms *document, + EvFormField *field, + const gchar *text) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return; + poppler_form_field_text_set_text (poppler_field, text); + g_object_unref (poppler_field); +} + +static void +pdf_document_forms_form_field_button_set_state (EvDocumentForms *document, + EvFormField *field, + gboolean state) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return; + + poppler_form_field_button_set_state (poppler_field, state); + g_object_unref (poppler_field); +} + +static gboolean +pdf_document_forms_form_field_button_get_state (EvDocumentForms *document, + EvFormField *field) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + gboolean state; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return FALSE; + + state = poppler_form_field_button_get_state (poppler_field); + g_object_unref (poppler_field); + + return state; +} + +static gchar * +pdf_document_forms_form_field_choice_get_item (EvDocumentForms *document, + EvFormField *field, + gint index) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + gchar *text; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return NULL; + + text = poppler_form_field_choice_get_item (poppler_field, index); + g_object_unref (poppler_field); + + return text; +} + +static int +pdf_document_forms_form_field_choice_get_n_items (EvDocumentForms *document, + EvFormField *field) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + gint n_items; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return -1; + + n_items = poppler_form_field_choice_get_n_items (poppler_field); + g_object_unref (poppler_field); + + return n_items; +} + +static gboolean +pdf_document_forms_form_field_choice_is_item_selected (EvDocumentForms *document, + EvFormField *field, + gint index) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + gboolean selected; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return FALSE; + + selected = poppler_form_field_choice_is_item_selected (poppler_field, index); + g_object_unref (poppler_field); + + return selected; +} + +static void +pdf_document_forms_form_field_choice_select_item (EvDocumentForms *document, + EvFormField *field, + gint index) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return; + + poppler_form_field_choice_select_item (poppler_field, index); + g_object_unref (poppler_field); +} + +static void +pdf_document_forms_form_field_choice_toggle_item (EvDocumentForms *document, + EvFormField *field, + gint index) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return; + + poppler_form_field_choice_toggle_item (poppler_field, index); + g_object_unref (poppler_field); +} + +static void +pdf_document_forms_form_field_choice_unselect_all (EvDocumentForms *document, + EvFormField *field) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return; + + poppler_form_field_choice_unselect_all (poppler_field); + g_object_unref (poppler_field); +} + +static void +pdf_document_forms_form_field_choice_set_text (EvDocumentForms *document, + EvFormField *field, + const gchar *text) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return; + + poppler_form_field_choice_set_text (poppler_field, text); + g_object_unref (poppler_field); +} + +static gchar * +pdf_document_forms_form_field_choice_get_text (EvDocumentForms *document, + EvFormField *field) +{ + PdfDocument *pdf_document = PDF_DOCUMENT (document); + PopplerFormField *poppler_field; + gchar *text; + + poppler_field = poppler_document_get_form_field (pdf_document->document, field->id); + if (!poppler_field) + return NULL; + + text = poppler_form_field_choice_get_text (poppler_field); + g_object_unref (poppler_field); + + return text; +} + +static void +pdf_document_document_forms_iface_init (EvDocumentFormsIface *iface) +{ + iface->get_form_fields = pdf_document_forms_get_form_fields; + iface->form_field_text_get_text = pdf_document_forms_form_field_text_get_text; + iface->form_field_text_set_text = pdf_document_forms_form_field_text_set_text; + iface->form_field_button_set_state = pdf_document_forms_form_field_button_set_state; + iface->form_field_button_get_state = pdf_document_forms_form_field_button_get_state; + iface->form_field_choice_get_item = pdf_document_forms_form_field_choice_get_item; + iface->form_field_choice_get_n_items = pdf_document_forms_form_field_choice_get_n_items; + iface->form_field_choice_is_item_selected = pdf_document_forms_form_field_choice_is_item_selected; + iface->form_field_choice_select_item = pdf_document_forms_form_field_choice_select_item; + iface->form_field_choice_toggle_item = pdf_document_forms_form_field_choice_toggle_item; + iface->form_field_choice_unselect_all = pdf_document_forms_form_field_choice_unselect_all; + 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 */