From ceed61215c8d3e8f7a91d7b741b9cd85a421f49d Mon Sep 17 00:00:00 2001
From: Adrian Perez de Castro <aperez@igalia.com>
Date: Thu, 26 Sep 2013 18:46:04 +0300
Subject: [PATCH v12 08/11] 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_get_form_field()
- poppler_structure_element_get_form_field_mapping()

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-structure-element.cc | 65 +++++++++++++++++++++++++++++++++++++++
 glib/poppler-structure-element.h  |  2 ++
 2 files changed, 67 insertions(+)

diff --git a/glib/poppler-structure-element.cc b/glib/poppler-structure-element.cc
index 3ddbaa9..5e50b50 100644
--- a/glib/poppler-structure-element.cc
+++ b/glib/poppler-structure-element.cc
@@ -818,6 +818,71 @@ poppler_structure_element_free_text_spans (PopplerTextSpan **poppler_text_spans)
 }
 
 /**
+ * poppler_structure_element_get_form_field:
+ * @poppler_structure_element: A #PopplerStructureElement
+ *
+ * Return value: (transfer full): A #PopplerFormField, or %NULL if
+ *    the element is not a %POPPLER_STRUCTURE_ELEMENT_FORM.
+ */
+PopplerFormField *
+poppler_structure_element_get_form_field (PopplerStructureElement *poppler_structure_element)
+{
+  g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), NULL);
+  g_assert (poppler_structure_element->elem);
+
+  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 ())
+    {
+      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 (field_id < 0) ? NULL : poppler_document_get_form_field (poppler_structure_element->document,
+                                                                  field_id);
+}
+
+/**
+ * poppler_structure_element_get_form_field_mapping:
+ * @poppler_structure_element: a #PopplerStructureElement
+ *
+ * Return value: (transfer full): A #PopplerFormFieldMapping, or %NULL if
+ *    the element is not a %POPPLER_STRUCTURE_ELEMENT_FORM
+ */
+PopplerFormFieldMapping *
+poppler_structure_element_get_form_field_mapping (PopplerStructureElement *poppler_structure_element)
+{
+  g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), NULL);
+  g_assert (poppler_structure_element->elem);
+
+  PopplerFormField *field = poppler_structure_element_get_form_field (poppler_structure_element);
+  if (field == NULL)
+    return NULL;
+
+  gint page_num = poppler_structure_element_get_page (poppler_structure_element);
+  return _poppler_form_field_mapping_new_from_form_field (field, page_num);
+}
+
+/**
  * poppler_text_span_copy:
  * @poppler_text_span: a #PopplerTextSpan
  *
diff --git a/glib/poppler-structure-element.h b/glib/poppler-structure-element.h
index 613f6e7..4738d5d 100644
--- a/glib/poppler-structure-element.h
+++ b/glib/poppler-structure-element.h
@@ -102,6 +102,8 @@ gchar                       *poppler_structure_element_get_actual_text
 PopplerTextSpan            **poppler_structure_element_get_text_spans             (PopplerStructureElement  *poppler_structure_element,
                                                                                    guint                    *n_text_spans);
 void                         poppler_structure_element_free_text_spans            (PopplerTextSpan         **poppler_text_spans);
+PopplerFormField            *poppler_structure_element_get_form_field             (PopplerStructureElement  *poppler_structure_element);
+PopplerFormFieldMapping     *poppler_structure_element_get_form_field_mapping     (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;
-- 
1.8.4.2