summaryrefslogtreecommitdiff
path: root/glib
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2008-10-26 19:47:35 +0100
committerCarlos Garcia Campos <carlosgc@gnome.org>2008-11-08 20:57:05 +0100
commit7363c25e1d83332932d9b4fe16d7fb4e364da628 (patch)
treeeb3bf1528cfcca2cf2fe7df2620b112b3c856da6 /glib
parentc674566f458b54097f21aae0d4bf8637146565c5 (diff)
[glib] Add Optional Content support
Diffstat (limited to 'glib')
-rw-r--r--glib/Makefile.am2
-rw-r--r--glib/poppler-document.cc377
-rw-r--r--glib/poppler-document.h12
-rw-r--r--glib/poppler-layer.cc201
-rw-r--r--glib/poppler-layer.h43
-rw-r--r--glib/poppler-private.h21
-rw-r--r--glib/poppler.h3
-rw-r--r--glib/test-poppler-glib.cc52
8 files changed, 710 insertions, 1 deletions
diff --git a/glib/Makefile.am b/glib/Makefile.am
index 187caed3..806a37a2 100644
--- a/glib/Makefile.am
+++ b/glib/Makefile.am
@@ -67,6 +67,7 @@ poppler_glib_public_headers = \
poppler-attachment.h \
poppler-form-field.h \
poppler-annot.h \
+ poppler-layer.h \
poppler.h
poppler_glib_includedir = $(includedir)/poppler/glib
@@ -85,6 +86,7 @@ libpoppler_glib_la_SOURCES = \
poppler-attachment.cc \
poppler-form-field.cc \
poppler-annot.cc \
+ poppler-layer.cc \
poppler.cc \
poppler-private.h
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
index ef5deb0b..352149bf 100644
--- a/glib/poppler-document.cc
+++ b/glib/poppler-document.cc
@@ -29,6 +29,7 @@
#include <FontInfo.h>
#include <PDFDocEncoding.h>
#include <DateInfo.h>
+#include <OptionalContent.h>
#include "poppler.h"
#include "poppler-private.h"
@@ -53,6 +54,8 @@ enum {
PROP_METADATA
};
+static void poppler_document_layers_free (PopplerDocument *document);
+
typedef struct _PopplerDocumentClass PopplerDocumentClass;
struct _PopplerDocumentClass
{
@@ -294,6 +297,7 @@ poppler_document_finalize (GObject *object)
{
PopplerDocument *document = POPPLER_DOCUMENT (object);
+ poppler_document_layers_free (document);
delete document->output_dev;
delete document->doc;
}
@@ -1353,6 +1357,379 @@ poppler_font_info_free (PopplerFontInfo *font_info)
}
+/* Optional content (layers) */
+static Layer *
+layer_new (OptionalContentGroup *oc)
+{
+ Layer *layer;
+
+ layer = g_new0 (Layer, 1);
+ layer->oc = oc;
+
+ return layer;
+}
+
+static void
+layer_free (Layer *layer)
+{
+ if (!layer)
+ return;
+
+ if (layer->kids) {
+ g_list_foreach (layer->kids, (GFunc)layer_free, NULL);
+ g_list_free (layer->kids);
+ }
+
+ if (layer->label) {
+ g_free (layer->label);
+ }
+
+ g_free (layer);
+}
+
+static GList *
+get_optional_content_rbgroups (OCGs *ocg)
+{
+ Array *rb;
+ GList *groups = NULL;
+
+ rb = ocg->getRBGroupsArray ();
+
+ if (rb) {
+ int i, j;
+
+ for (i = 0; i < rb->getLength (); ++i) {
+ Object obj;
+ Array *rb_array;
+ GList *group = NULL;
+
+ rb->get (i, &obj);
+ if (!obj.isArray ()) {
+ obj.free ();
+ continue;
+ }
+
+ rb_array = obj.getArray ();
+ for (j = 0; j < rb_array->getLength (); ++j) {
+ Object ref;
+ OptionalContentGroup *oc;
+
+ rb_array->getNF (j, &ref);
+ if (!ref.isRef ()) {
+ ref.free ();
+ continue;
+ }
+
+ oc = ocg->findOcgByRef (ref.getRef ());
+ group = g_list_prepend (group, oc);
+ ref.free ();
+ }
+ obj.free ();
+
+ groups = g_list_prepend (groups, group);
+ }
+ }
+
+ return groups;
+}
+
+static GList *
+poppler_document_get_layer_rbgroup (PopplerDocument *document,
+ Layer *layer)
+{
+ GList *l;
+
+ for (l = document->layers_rbgroups; l && l->data; l = g_list_next (l)) {
+ GList *group = (GList *)l->data;
+
+ if (g_list_find (group, layer->oc))
+ return group;
+ }
+
+ return NULL;
+}
+
+static GList *
+get_optional_content_items_sorted (OCGs *ocg, Layer *parent, Array *order)
+{
+ GList *items = NULL;
+ Layer *last_item = parent;
+ int i;
+
+ for (i = 0; i < order->getLength (); ++i) {
+ Object orderItem;
+
+ order->get (i, &orderItem);
+
+ if (orderItem.isDict ()) {
+ Object ref;
+
+ order->getNF (i, &ref);
+ if (ref.isRef ()) {
+ OptionalContentGroup *oc = ocg->findOcgByRef (ref.getRef ());
+ Layer *layer = layer_new (oc);
+
+ items = g_list_prepend (items, layer);
+ last_item = layer;
+ }
+ ref.free ();
+ } else if (orderItem.isArray () && orderItem.arrayGetLength () > 0) {
+ if (!last_item) {
+ last_item = layer_new (NULL);
+ items = g_list_prepend (items, last_item);
+ }
+ last_item->kids = get_optional_content_items_sorted (ocg, last_item, orderItem.getArray ());
+ } else if (orderItem.isString ()) {
+ last_item->label = _poppler_goo_string_to_utf8 (orderItem.getString ());
+ }
+ orderItem.free ();
+ }
+
+ return g_list_reverse (items);
+}
+
+static GList *
+get_optional_content_items (OCGs *ocg)
+{
+ Array *order;
+ GList *items = NULL;
+
+ order = ocg->getOrderArray ();
+
+ if (order) {
+ items = get_optional_content_items_sorted (ocg, NULL, order);
+ } else {
+ GooList *ocgs;
+ int i;
+
+ ocgs = ocg->getOCGs ();
+
+ for (i = 0; i < ocgs->getLength (); ++i) {
+ OptionalContentGroup *oc = (OptionalContentGroup *) ocgs->get (i);
+ Layer *layer = layer_new (oc);
+
+ items = g_list_prepend (items, layer);
+ }
+
+ items = g_list_reverse (items);
+ }
+
+ return items;
+}
+
+static GList *
+poppler_document_get_layers (PopplerDocument *document)
+{
+ if (!document->layers) {
+ Catalog *catalog = document->doc->getCatalog ();
+ OCGs *ocg = catalog->getOptContentConfig ();
+
+ if (!ocg)
+ return NULL;
+
+ document->layers = get_optional_content_items (ocg);
+ document->layers_rbgroups = get_optional_content_rbgroups (ocg);
+ }
+
+ return document->layers;
+}
+
+static void
+poppler_document_layers_free (PopplerDocument *document)
+{
+ if (!document->layers)
+ return;
+
+ g_list_foreach (document->layers, (GFunc)layer_free, NULL);
+ g_list_free (document->layers);
+
+ g_list_foreach (document->layers_rbgroups, (GFunc)g_list_free, NULL);
+ g_list_free (document->layers_rbgroups);
+
+ document->layers = NULL;
+ document->layers_rbgroups = NULL;
+}
+
+/* PopplerLayersIter */
+struct _PopplerLayersIter {
+ PopplerDocument *document;
+ GList *items;
+ int index;
+};
+
+GType
+poppler_layers_iter_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (our_type == 0)
+ our_type = g_boxed_type_register_static ("PopplerLayersIter",
+ (GBoxedCopyFunc) poppler_layers_iter_copy,
+ (GBoxedFreeFunc) poppler_layers_iter_free);
+ return our_type;
+}
+
+/**
+ * poppler_layers_iter_copy:
+ * @iter: a #PopplerLayersIter
+ *
+ * Creates a new #PopplerLayersIter as a copy of @iter. This must be freed with
+ * poppler_layers_iter_free().
+ *
+ * Return value: a new #PopplerLayersIter
+ **/
+PopplerLayersIter *
+poppler_layers_iter_copy (PopplerLayersIter *iter)
+{
+ PopplerLayersIter *new_iter;
+
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ new_iter = g_new0 (PopplerLayersIter, 1);
+ *new_iter = *iter;
+ new_iter->document = (PopplerDocument *) g_object_ref (new_iter->document);
+
+ return new_iter;
+}
+
+/**
+ * poppler_layers_iter_free:
+ * @iter: a #PopplerLayersIter
+ *
+ * Frees @iter.
+ **/
+void
+poppler_layers_iter_free (PopplerLayersIter *iter)
+{
+ if (iter == NULL)
+ return;
+
+ g_object_unref (iter->document);
+ g_free (iter);
+}
+
+/**
+ * poppler_layers_iter_new:
+ **/
+PopplerLayersIter *
+poppler_layers_iter_new (PopplerDocument *document)
+{
+ PopplerLayersIter *iter;
+ GList *items;
+
+ items = poppler_document_get_layers (document);
+
+ if (!items)
+ return NULL;
+
+ iter = g_new0 (PopplerLayersIter, 1);
+ iter->document = (PopplerDocument *)g_object_ref (document);
+ iter->items = items;
+
+ return iter;
+}
+
+/**
+ * poppler_layers_iter_get_child:
+ * @parent: a #PopplerLayersIter
+ *
+ * Returns a newly created child of @parent, or %NULL if the iter has no child.
+ * See poppler_layers_iter_new() for more information on this function.
+ *
+ * Return value: a new #PopplerLayersIter, or %NULL
+ **/
+PopplerLayersIter *
+poppler_layers_iter_get_child (PopplerLayersIter *parent)
+{
+ PopplerLayersIter *child;
+ Layer *layer;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+
+ layer = (Layer *) g_list_nth_data (parent->items, parent->index);
+ if (!layer || !layer->kids)
+ return NULL;
+
+ child = g_new0 (PopplerLayersIter, 1);
+ child->document = (PopplerDocument *)g_object_ref (parent->document);
+ child->items = layer->kids;
+
+ g_assert (child->items);
+
+ return child;
+}
+
+/**
+ * poppler_layers_iter_get_title:
+ * @iter: a #PopplerLayersIter
+ *
+ * Returns the title associated with @iter. It must be freed with
+ * g_free().
+ *
+ * Return value: a new string containing the @iter's title or %NULL if @iter doesn't have a title.
+ * The returned string should be freed with g_free() when no longer needed.
+ **/
+gchar *
+poppler_layers_iter_get_title (PopplerLayersIter *iter)
+{
+ Layer *layer;
+
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ layer = (Layer *)g_list_nth_data (iter->items, iter->index);
+
+ return layer->label ? g_strdup (layer->label) : NULL;
+}
+
+/**
+ * poppler_layers_iter_get_layer:
+ * @iter: a #PopplerLayersIter
+ *
+ * Returns the #PopplerLayer associated with @iter. It must be freed with
+ * poppler_layer_free().
+ *
+ * Return value: a new #PopplerLayer, or %NULL if there isn't any layer associated with @iter
+ **/
+PopplerLayer *
+poppler_layers_iter_get_layer (PopplerLayersIter *iter)
+{
+ Layer *layer;
+ PopplerLayer *poppler_layer = NULL;
+
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ layer = (Layer *)g_list_nth_data (iter->items, iter->index);
+ if (layer->oc) {
+ GList *rb_group = NULL;
+
+ rb_group = poppler_document_get_layer_rbgroup (iter->document, layer);
+ poppler_layer = _poppler_layer_new (iter->document, layer, rb_group);
+ }
+
+ return poppler_layer;
+}
+
+/**
+ * poppler_layers_iter_next:
+ * @iter: a #PopplerLayersIter
+ *
+ * Sets @iter to point to the next action at the current level, if valid. See
+ * poppler_layers_iter_new() for more information.
+ *
+ * Return value: %TRUE, if @iter was set to the next action
+ **/
+gboolean
+poppler_layers_iter_next (PopplerLayersIter *iter)
+{
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ iter->index++;
+ if (iter->index >= (gint)g_list_length (iter->items))
+ return FALSE;
+
+ return TRUE;
+}
+
typedef struct _PopplerPSFileClass PopplerPSFileClass;
struct _PopplerPSFileClass
{
diff --git a/glib/poppler-document.h b/glib/poppler-document.h
index 45854258..2f4f50ac 100644
--- a/glib/poppler-document.h
+++ b/glib/poppler-document.h
@@ -157,6 +157,18 @@ gboolean poppler_fonts_iter_is_embedded (PopplerFontsIter *iter);
gboolean poppler_fonts_iter_is_subset (PopplerFontsIter *iter);
gboolean poppler_fonts_iter_next (PopplerFontsIter *iter);
+/* Interface for getting the Layers of a poppler_document */
+#define POPPLER_TYPE_LAYERS_ITER (poppler_layers_iter_get_type ())
+GType poppler_layers_iter_get_type (void) G_GNUC_CONST;
+PopplerLayersIter *poppler_layers_iter_new (PopplerDocument *document);
+PopplerLayersIter *poppler_layers_iter_copy (PopplerLayersIter *iter);
+void poppler_layers_iter_free (PopplerLayersIter *iter);
+
+PopplerLayersIter *poppler_layers_iter_get_child (PopplerLayersIter *parent);
+gchar *poppler_layers_iter_get_title (PopplerLayersIter *iter);
+PopplerLayer *poppler_layers_iter_get_layer (PopplerLayersIter *iter);
+gboolean poppler_layers_iter_next (PopplerLayersIter *iter);
+
/* Export to ps */
#define POPPLER_TYPE_PS_FILE (poppler_ps_file_get_type ())
#define POPPLER_PS_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_PS_FILE, PopplerPSFile))
diff --git a/glib/poppler-layer.cc b/glib/poppler-layer.cc
new file mode 100644
index 00000000..2049dc74
--- /dev/null
+++ b/glib/poppler-layer.cc
@@ -0,0 +1,201 @@
+/* poppler-layer.cc: glib interface to poppler
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "poppler-layer.h"
+#include "poppler-private.h"
+
+typedef struct _PopplerLayerClass PopplerLayerClass;
+struct _PopplerLayerClass
+{
+ GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (PopplerLayer, poppler_layer, G_TYPE_OBJECT)
+
+static void
+poppler_layer_finalize (GObject *object)
+{
+ PopplerLayer *poppler_layer = POPPLER_LAYER (object);
+
+ if (poppler_layer->document)
+ {
+ g_object_unref (poppler_layer->document);
+ poppler_layer->document = NULL;
+ }
+
+ if (poppler_layer->title)
+ {
+ g_free (poppler_layer->title);
+ poppler_layer->title = NULL;
+ }
+ poppler_layer->layer = NULL;
+ poppler_layer->rbgroup = NULL;
+
+ G_OBJECT_CLASS (poppler_layer_parent_class)->finalize (object);
+}
+
+static void
+poppler_layer_init (PopplerLayer *layer)
+{
+}
+
+static void
+poppler_layer_class_init (PopplerLayerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = poppler_layer_finalize;
+}
+
+PopplerLayer *
+_poppler_layer_new (PopplerDocument *document,
+ Layer *layer,
+ GList *rbgroup)
+{
+ PopplerLayer *poppler_layer;
+
+ g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
+ g_return_val_if_fail (layer != NULL, NULL);
+
+ poppler_layer = POPPLER_LAYER (g_object_new (POPPLER_TYPE_LAYER, NULL));
+
+ poppler_layer->document = (PopplerDocument *)g_object_ref (document);
+ poppler_layer->layer = layer;
+ poppler_layer->rbgroup = rbgroup;
+ poppler_layer->title = _poppler_goo_string_to_utf8 (layer->oc->getName ());
+
+ return poppler_layer;
+}
+
+/**
+ * poppler_layer_get_title
+ * @layer: a #PopplerLayer
+ *
+ * Returns the name of the layer suitable for
+ * presentation as a title in a viewer's GUI
+ *
+ * Return value: a string containing the title of the layer
+ **/
+const gchar *
+poppler_layer_get_title (PopplerLayer *poppler_layer)
+{
+ g_return_val_if_fail (POPPLER_IS_LAYER (poppler_layer), NULL);
+
+ return poppler_layer->title;
+}
+
+/**
+ * poppler_layer_is_visible
+ * @layer: a #PopplerLayer
+ *
+ * Returns whether @layer is visible
+ *
+ * Return value: %TRUE if @layer is visible
+ **/
+gboolean
+poppler_layer_is_visible (PopplerLayer *poppler_layer)
+{
+ g_return_val_if_fail (POPPLER_IS_LAYER (poppler_layer), FALSE);
+
+ return poppler_layer->layer->oc->getState () == OptionalContentGroup::On;
+}
+
+/**
+ * poppler_layer_show
+ * @layer: a #PopplerLayer
+ *
+ * Shows @layer
+ **/
+void
+poppler_layer_show (PopplerLayer *poppler_layer)
+{
+ GList *l;
+ Layer *layer;
+
+ g_return_if_fail (POPPLER_IS_LAYER (poppler_layer));
+
+ layer = poppler_layer->layer;
+
+ if (layer->oc->getState () == OptionalContentGroup::On)
+ return;
+
+ layer->oc->setState (OptionalContentGroup::On);
+
+ for (l = poppler_layer->rbgroup; l && l->data; l = g_list_next (l)) {
+ OptionalContentGroup *oc = (OptionalContentGroup *)l->data;
+
+ if (oc != layer->oc)
+ oc->setState (OptionalContentGroup::Off);
+ }
+}
+
+/**
+ * poppler_layer_hide
+ * @layer: a #PopplerLayer
+ *
+ * Hides @layer. If @layer is the parent of other nested layers,
+ * such layers will be also hidden and will be blocked until @layer
+ * is shown again
+ **/
+void
+poppler_layer_hide (PopplerLayer *poppler_layer)
+{
+ Layer *layer;
+
+ g_return_if_fail (POPPLER_IS_LAYER (poppler_layer));
+
+ layer = poppler_layer->layer;
+
+ if (layer->oc->getState () == OptionalContentGroup::Off)
+ return;
+
+ layer->oc->setState (OptionalContentGroup::Off);
+}
+
+
+/**
+ * poppler_layer_is_parent
+ *
+ * Returns whether @layer is parent of other nested layers.
+ *
+ * Return value: %TRUE if @layer is a parent layer
+ **/
+gboolean
+poppler_layer_is_parent (PopplerLayer *poppler_layer)
+{
+ g_return_val_if_fail (POPPLER_IS_LAYER (poppler_layer), FALSE);
+
+ return poppler_layer->layer->kids != NULL;
+}
+
+/**
+ * poppler_layer_get_radio_button_group_id
+ *
+ * Returns the numeric ID the radio button group associated with @layer.
+ *
+ * Return value: the ID of the radio button group associated with @layer,
+ * or 0 if the layer is not associated to any radio button group
+ **/
+gint
+poppler_layer_get_radio_button_group_id (PopplerLayer *poppler_layer)
+{
+ g_return_val_if_fail (POPPLER_IS_LAYER (poppler_layer), FALSE);
+
+ return GPOINTER_TO_INT (poppler_layer->rbgroup);
+}
diff --git a/glib/poppler-layer.h b/glib/poppler-layer.h
new file mode 100644
index 00000000..2434e275
--- /dev/null
+++ b/glib/poppler-layer.h
@@ -0,0 +1,43 @@
+/* poppler-layer.h: glib interface to poppler
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __POPPLER_LAYER_H__
+#define __POPPLER_LAYER_H__
+
+#include <glib-object.h>
+#include "poppler.h"
+
+G_BEGIN_DECLS
+
+#define POPPLER_TYPE_LAYER (poppler_layer_get_type ())
+#define POPPLER_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_LAYER, PopplerLayer))
+#define POPPLER_IS_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_LAYER))
+
+GType poppler_layer_get_type (void) G_GNUC_CONST;
+
+const gchar *poppler_layer_get_title (PopplerLayer *layer);
+gboolean poppler_layer_is_visible (PopplerLayer *layer);
+void poppler_layer_show (PopplerLayer *layer);
+void poppler_layer_hide (PopplerLayer *layer);
+gboolean poppler_layer_is_parent (PopplerLayer *layer);
+gint poppler_layer_get_radio_button_group_id (PopplerLayer *layer);
+
+G_END_DECLS
+
+#endif /* __POPPLER_LAYER_H__ */
diff --git a/glib/poppler-private.h b/glib/poppler-private.h
index 539714cf..663b8e80 100644
--- a/glib/poppler-private.h
+++ b/glib/poppler-private.h
@@ -10,6 +10,7 @@
#include <FontInfo.h>
#include <TextOutputDev.h>
#include <Catalog.h>
+#include <OptionalContent.h>
#if defined (HAVE_CAIRO)
#include <CairoOutputDev.h>
@@ -22,6 +23,8 @@ struct _PopplerDocument
GObject parent_instance;
PDFDoc *doc;
+ GList *layers;
+ GList *layers_rbgroups;
#if defined (HAVE_CAIRO)
CairoOutputDev *output_dev;
#elif defined (HAVE_SPLASH)
@@ -68,12 +71,30 @@ struct _PopplerFormField
FormWidget *widget;
};
+typedef struct _Layer {
+ GList *kids;
+ gchar *label;
+ OptionalContentGroup *oc;
+} Layer;
+
+struct _PopplerLayer
+{
+ GObject parent_instance;
+ PopplerDocument *document;
+ Layer *layer;
+ GList *rbgroup;
+ gchar *title;
+};
+
PopplerPage *_poppler_page_new (PopplerDocument *document,
Page *page,
int index);
PopplerAction *_poppler_action_new (PopplerDocument *document,
LinkAction *link,
const gchar *title);
+PopplerLayer *_poppler_layer_new (PopplerDocument *document,
+ Layer *layer,
+ GList *rbgroup);
PopplerDest *_poppler_dest_new_goto (PopplerDocument *document,
LinkDest *link_dest);
PopplerFormField *_poppler_form_field_new (PopplerDocument *document,
diff --git a/glib/poppler.h b/glib/poppler.h
index 88a330c5..d554093b 100644
--- a/glib/poppler.h
+++ b/glib/poppler.h
@@ -82,6 +82,7 @@ typedef enum
typedef struct _PopplerDocument PopplerDocument;
typedef struct _PopplerIndexIter PopplerIndexIter;
typedef struct _PopplerFontsIter PopplerFontsIter;
+typedef struct _PopplerLayersIter PopplerLayersIter;
typedef struct _PopplerRectangle PopplerRectangle;
typedef struct _PopplerColor PopplerColor;
typedef struct _PopplerLinkMapping PopplerLinkMapping;
@@ -91,6 +92,7 @@ typedef struct _PopplerFormFieldMapping PopplerFormFieldMapping;
typedef struct _PopplerAnnotMapping PopplerAnnotMapping;
typedef struct _PopplerPage PopplerPage;
typedef struct _PopplerFontInfo PopplerFontInfo;
+typedef struct _PopplerLayer PopplerLayer;
typedef struct _PopplerPSFile PopplerPSFile;
typedef union _PopplerAction PopplerAction;
typedef struct _PopplerDest PopplerDest;
@@ -117,6 +119,7 @@ G_END_DECLS
#include "poppler-features.h"
#include "poppler-document.h"
#include "poppler-page.h"
+#include "poppler-layer.h"
#include "poppler-action.h"
#include "poppler-form-field.h"
#include "poppler-enums.h"
diff --git a/glib/test-poppler-glib.cc b/glib/test-poppler-glib.cc
index 592a7c73..bd33f91f 100644
--- a/glib/test-poppler-glib.cc
+++ b/glib/test-poppler-glib.cc
@@ -46,13 +46,52 @@ print_index (PopplerIndexIter *iter, gint deph)
poppler_action_free (action);
child = poppler_index_iter_get_child (iter);
if (child)
- print_index (child, deph + 1);
+ print_index (child, deph + 1);
poppler_index_iter_free (child);
}
while (poppler_index_iter_next (iter));
}
static void
+print_layers (PopplerLayersIter *iter, gint deph)
+{
+ do
+ {
+ PopplerLayersIter *child;
+ PopplerLayer *layer;
+ gint i;
+
+ for (i = 0; i < deph; i++)
+ g_print (" ");
+
+ layer = poppler_layers_iter_get_layer (iter);
+ if (layer)
+ {
+ g_print ("+ %s (%s)\n", poppler_layer_get_title (layer),
+ poppler_layer_is_visible (layer) ?
+ "Visible" : "Hidden");
+ g_object_unref (layer);
+ }
+
+ child = poppler_layers_iter_get_child (iter);
+ if (child)
+ {
+ gchar *title;
+
+ title = poppler_layers_iter_get_title (iter);
+ if (title)
+ {
+ g_print ("+ %s\n", title);
+ g_free (title);
+ }
+ print_layers (child, deph + 1);
+ }
+ poppler_layers_iter_free (child);
+ }
+ while (poppler_layers_iter_next (iter));
+}
+
+static void
print_document_info (PopplerDocument *document)
{
gchar *title, *format, *author, *subject, *keywords, *creator, *producer, *linearized;
@@ -344,6 +383,7 @@ int main (int argc, char *argv[])
gint num_images;
gint num_forms;
gint form_id = 0;
+ PopplerLayersIter *layers_iter;
if (argc != 3)
FAIL ("usage: test-poppler-glib file://FILE PAGE");
@@ -540,6 +580,16 @@ int main (int argc, char *argv[])
else
g_print ("\tNo attachments found\n");
+ layers_iter = poppler_layers_iter_new (document);
+ if (layers_iter)
+ {
+ g_print ("\tLayers:\n");
+ print_layers (layers_iter, 0);
+ poppler_layers_iter_free (layers_iter);
+ }
+ else
+ g_print ("\tNo layers found\n");
+
g_object_unref (G_OBJECT (page));
g_object_unref (G_OBJECT (document));