From 7363c25e1d83332932d9b4fe16d7fb4e364da628 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Sun, 26 Oct 2008 19:47:35 +0100 Subject: [glib] Add Optional Content support --- glib/Makefile.am | 2 + glib/poppler-document.cc | 377 ++++++++++++++++++++++++++++++++++++++++++++++ glib/poppler-document.h | 12 ++ glib/poppler-layer.cc | 201 ++++++++++++++++++++++++ glib/poppler-layer.h | 43 ++++++ glib/poppler-private.h | 21 +++ glib/poppler.h | 3 + glib/test-poppler-glib.cc | 52 ++++++- 8 files changed, 710 insertions(+), 1 deletion(-) create mode 100644 glib/poppler-layer.cc create mode 100644 glib/poppler-layer.h (limited to 'glib') 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 #include #include +#include #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 + * + * 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 + * + * 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 +#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 #include #include +#include #if defined (HAVE_CAIRO) #include @@ -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,12 +46,51 @@ 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) { @@ -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)); -- cgit v1.2.3