From d5fe7102505afadb8bb6c83f469245988049bc6e Mon Sep 17 00:00:00 2001 From: Adrian Perez de Castro Date: Thu, 26 Sep 2013 18:46:04 +0300 Subject: [PATCH v18 3/5] glib: Accessors for form fields of structure elements Implements two methods which can be used on PopplerStructureElement objects of type POPPLER_STRUCTURE_ELEMENT_FORM: - poppler_structure_element_form_get_field() - poppler_page_get_form_field_mapping_for_structure_element() The only difference is that the later returns a PopplerFormFieldMapping, which itself contains the PopplerFormField, plus the rectangle covered by the form widget in the page. --- glib/poppler-page.cc | 32 +++++++++++++++++++++++ glib/poppler-page.h | 3 +++ glib/poppler-structure-element.cc | 51 +++++++++++++++++++++++++++++++++++++ glib/poppler-structure-element.h | 2 ++ glib/reference/poppler-sections.txt | 1 + 5 files changed, 89 insertions(+) diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc index f5271b5..7e9c30e 100644 --- a/glib/poppler-page.cc +++ b/glib/poppler-page.cc @@ -1380,6 +1380,38 @@ poppler_page_free_form_field_mapping (GList *list) } /** + * poppler_page_get_form_field_mapping_for_structure_element: + * @page: A #PopplerPage. + * @structure_element: a #PopplerStructureElement. + * + * Obtains the #PopplerFormFieldMapping for a single form field associated + * with a structure element of type %POPPLER_STRUCTURE_ELEMENT_FORM. The + * returned value must be freed with g_object_unref(). + * + * Return value: (transfer full): A #PopplerFormFieldMapping; or %NULL if + * the element is not a %POPPLER_STRUCTURE_ELEMENT_FORM or if the given + * structure element does not have content in the page. + * + * Since: 0.26 + */ +PopplerFormFieldMapping * +poppler_page_get_form_field_mapping_for_structure_element (PopplerPage *page, + PopplerStructureElement *structure_element) +{ + g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL); + g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (structure_element), NULL); + + if (page->index != poppler_structure_element_get_page (structure_element)) + return NULL; + + PopplerFormField *field = poppler_structure_element_form_get_field (structure_element); + if (field == NULL) + return NULL; + + return _poppler_form_field_mapping_new_from_form_field (field, page->index); +} + +/** * poppler_page_get_annot_mapping: * @page: A #PopplerPage * diff --git a/glib/poppler-page.h b/glib/poppler-page.h index 63fe362..23f6ee7 100644 --- a/glib/poppler-page.h +++ b/glib/poppler-page.h @@ -89,6 +89,9 @@ void poppler_page_free_image_mapping (GList *li cairo_surface_t *poppler_page_get_image (PopplerPage *page, gint image_id); GList *poppler_page_get_form_field_mapping (PopplerPage *page); +PopplerFormFieldMapping* +poppler_page_get_form_field_mapping_for_structure_element(PopplerPage *page, + PopplerStructureElement *structure_element); void poppler_page_free_form_field_mapping (GList *list); GList *poppler_page_get_annot_mapping (PopplerPage *page); void poppler_page_free_annot_mapping (GList *list); diff --git a/glib/poppler-structure-element.cc b/glib/poppler-structure-element.cc index 3e7b679..750ccda 100644 --- a/glib/poppler-structure-element.cc +++ b/glib/poppler-structure-element.cc @@ -764,6 +764,57 @@ text_span_poppler_text_span (const TextSpan& span) } /** + * poppler_structure_element_form_get_field: + * @poppler_structure_element: A #PopplerStructureElement + * + * Obtains the #PopplerFormField out of an element of type + * %POPPLER_STRUCTURE_ELEMENT_FORM. The returned value must be freed + * with g_object_unref(). Note that there is one structure element + * per form field. + * + * Return value: (transfer full): A #PopplerFormField, or %NULL if + * the element is not a %POPPLER_STRUCTURE_ELEMENT_FORM. + * + * Since: 0.26 + */ +PopplerFormField * +poppler_structure_element_form_get_field (PopplerStructureElement *poppler_structure_element) +{ + g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), NULL); + g_return_val_if_fail (poppler_structure_element->elem != NULL, NULL); + + if (poppler_structure_element->elem->getType () != StructElement::Form) + return NULL; + + // TODO Handle elements which have a Role attribute (used sometimes for + // non-editable widgets, to describe their appearance). Editable + // fields have only a single child, with the field identifier. + if (poppler_structure_element->elem->getNumElements () != 1) + return NULL; + + gint field_id = -1; + const StructElement *child = poppler_structure_element->elem->getElement (0); + + if (!child->isContent ()) + return NULL; + + if (child->isObjectRef ()) + { + // TODO Handle this case -- I have yet to see a PDF using this. + } + else + { + // Element contains the form field ID as the MCID attribute. + field_id = child->getMCID (); + } + + if (field_id < 0) + return NULL; + + return poppler_document_get_form_field (poppler_structure_element->document, field_id); +} + +/** * poppler_text_span_copy: * @poppler_text_span: a #PopplerTextSpan * diff --git a/glib/poppler-structure-element.h b/glib/poppler-structure-element.h index 4b20c36..4e7824c 100644 --- a/glib/poppler-structure-element.h +++ b/glib/poppler-structure-element.h @@ -103,6 +103,8 @@ gchar *poppler_structure_element_get_alt_text gchar *poppler_structure_element_get_actual_text (PopplerStructureElement *poppler_structure_element); PopplerTextSpan **poppler_structure_element_get_text_spans (PopplerStructureElement *poppler_structure_element, guint *n_text_spans); +PopplerFormField *poppler_structure_element_form_get_field (PopplerStructureElement *poppler_structure_element); + #define POPPLER_TYPE_STRUCTURE_ELEMENT_ITER (poppler_structure_element_iter_get_type ()) GType poppler_structure_element_iter_get_type (void) G_GNUC_CONST; diff --git a/glib/reference/poppler-sections.txt b/glib/reference/poppler-sections.txt index 528ba07..4f8bfef 100644 --- a/glib/reference/poppler-sections.txt +++ b/glib/reference/poppler-sections.txt @@ -611,6 +611,7 @@ poppler_structure_element_get_text poppler_structure_element_get_alt_text poppler_structure_element_get_actual_text poppler_structure_element_get_text_spans +poppler_structure_element_form_get_field poppler_text_span_copy poppler_text_span_free poppler_text_span_is_fixed_width_font -- 1.9.0