From c45c05cd20be470929ecae48679a61b9de0abecb Mon Sep 17 00:00:00 2001 From: Adrian Perez de Castro Date: Thu, 26 Sep 2013 19:21:34 +0300 Subject: [PATCH v17 4/5] glib: Accessors for document structure references Implements functions to work with PopplerStructureElement objects which are references to other entities in the document. Whether an element is a reference can be checked with poppler_structure_element_is_reference(), and poppler_structure_element_get_reference_type() returns the type of object referenced. For POPPLER_STRUCTURE_REFERENCE_LINK references, a PopplerAction (or PopplerLinkMapping) can be retrieved using the poppler_structure_element_get_reference_link_action() or poppler_structure_element_get_reference_link_mapping() methods. --- glib/poppler-structure-element.cc | 120 ++++++++++++++++++++++++++++++++++++++ glib/poppler-structure-element.h | 17 ++++++ 2 files changed, 137 insertions(+) diff --git a/glib/poppler-structure-element.cc b/glib/poppler-structure-element.cc index f9e0b74..11a25db 100644 --- a/glib/poppler-structure-element.cc +++ b/glib/poppler-structure-element.cc @@ -926,6 +926,126 @@ poppler_text_span_is_bold_font (PopplerTextSpan *poppler_text_span) } /** + * poppler_structure_element_is_reference: + * @poppler_structure_element: A #PopplerStructureElement + * + * Return value: Whether the element is a reference to another object. + */ +gboolean +poppler_structure_element_is_reference (PopplerStructureElement *poppler_structure_element) +{ + g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), FALSE); + g_return_val_if_fail (poppler_structure_element->elem != NULL, FALSE); + + return poppler_structure_element->elem->isObjectRef (); +} + +/** + * poppler_structure_element_get_reference_type: + * @poppler_structure_element: A #PopplerStructureElement + * + * Return value: The type of object pointed to by the reference, a value of + * #PopplerStructureReference. + */ +PopplerStructureReference +poppler_structure_element_get_reference_type (PopplerStructureElement *poppler_structure_element) +{ + PopplerStructureReference reftype = POPPLER_STRUCTURE_REFERENCE_UNKNOWN; + + g_return_val_if_fail (POPPLER_IS_STRUCTURE_ELEMENT (poppler_structure_element), reftype); + g_return_val_if_fail (poppler_structure_element->elem != NULL, reftype); + + if (poppler_structure_element->elem->isObjectRef ()) + { + Object obj; + const Ref ref = poppler_structure_element->elem->getObjectRef (); + XRef *xref = poppler_structure_element->document->doc->getXRef (); + + if (xref->fetch(ref.num, ref.gen, &obj)->isDict("Annot")) + { + reftype = POPPLER_STRUCTURE_REFERENCE_ANNOT; + Object subtype; + if (obj.dictLookup("Subtype", &subtype)->isName("Link")) + reftype = POPPLER_STRUCTURE_REFERENCE_LINK; + subtype.free(); + } + + obj.free(); + } + + return reftype; +} + + +static AnnotLink * +_poppler_structure_element_find_annot_link (PopplerStructureElement *poppler_structure_element) +{ + if (poppler_structure_element_get_reference_type (poppler_structure_element) + != POPPLER_STRUCTURE_REFERENCE_LINK) + return NULL; + + gint num = poppler_structure_element_get_page (poppler_structure_element); + if (num < 0 || num >= poppler_document_get_n_pages (poppler_structure_element->document)) + return NULL; + + Page *page = poppler_structure_element->document->doc->getPage (num + 1); + Links links(page->getAnnots ()); + + for (gint i = 0; i < links.getNumLinks (); i++) + { + AnnotLink *link = links.getLink (i); + const StructElement *parent = poppler_structure_element->document->doc->getStructTreeRoot ()->findParentElement (link->getTreeKey()); + if (parent == poppler_structure_element->elem) + return link; + } + + return NULL; +} + +/** + * poppler_structure_element_get_reference_link: + * @poppler_structure_element: A #PopplerStructureElement + * + * Return value: (transfer full): The #PopplerAction associated to the + * link, or %NULL if the element is not a reference pointing to + * a link. + */ +PopplerAction * +poppler_structure_element_get_reference_link_action (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); + + AnnotLink *link = _poppler_structure_element_find_annot_link (poppler_structure_element); + return link ? _poppler_action_new (poppler_structure_element->document, link->getAction (), NULL) : NULL; +} + +/** + * poppler_structure_element_get_reference_link_mapping: + * @poppler_structure_element: a #PopplerStructureElement + * + * Return value: (transfer full): The #PopplerLinkMapping for the pointed + * object, or %NULL if the element is not a reference pointing to + * a link. + */ +PopplerLinkMapping * +poppler_structure_element_get_reference_link_mapping (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); + + AnnotLink *link = _poppler_structure_element_find_annot_link (poppler_structure_element); + if (link == NULL) + return NULL; + + gint page_num = poppler_structure_element_get_page (poppler_structure_element); + + return _poppler_link_mapping_new_from_annot_link (poppler_structure_element->document, + page_num, + link); +} + +/** * poppler_text_span_get_color: * @poppler_text_span: a #PopplerTextSpan * @color: (out): a return location for a #PopplerColor diff --git a/glib/poppler-structure-element.h b/glib/poppler-structure-element.h index 975a0e2..bc6063e 100644 --- a/glib/poppler-structure-element.h +++ b/glib/poppler-structure-element.h @@ -86,6 +86,19 @@ typedef enum { POPPLER_STRUCTURE_ELEMENT_FORM, } PopplerStructureElementKind; +/** + * PopplerStructureReference: + */ +typedef enum { + POPPLER_STRUCTURE_REFERENCE_UNKNOWN, + POPPLER_STRUCTURE_REFERENCE_ANNOT, + POPPLER_STRUCTURE_REFERENCE_LINK, +} PopplerStructureReference; + + +typedef struct _PopplerTextSpan PopplerTextSpan; + + GType poppler_structure_element_get_type (void) G_GNUC_CONST; PopplerStructureElementKind poppler_structure_element_get_kind (PopplerStructureElement *poppler_structure_element); gint poppler_structure_element_get_page (PopplerStructureElement *poppler_structure_element); @@ -103,6 +116,10 @@ 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); +gboolean poppler_structure_element_is_reference (PopplerStructureElement *poppler_structure_element); +PopplerStructureReference poppler_structure_element_get_reference_type (PopplerStructureElement *poppler_structure_element); +PopplerAction *poppler_structure_element_get_reference_link_action (PopplerStructureElement *poppler_structure_element); +PopplerLinkMapping *poppler_structure_element_get_reference_link_mapping (PopplerStructureElement *poppler_structure_element); PopplerFormField *poppler_structure_element_get_form_field (PopplerStructureElement *poppler_structure_element); PopplerFormFieldMapping *poppler_structure_element_get_form_field_mapping (PopplerStructureElement *poppler_structure_element); -- 1.9.0