Hi,

attached are three patches
- poppler.add-support-for-file-attachment-annotations.patch
  As mentioned on IRC know, I'm wondering whether it'd be better to
  avoid creating an own GType for each annotation type, in particular
  if there is nothing to know beyond the type for users.
  For now this patch follows the AnootText example and has its own type.
  An alternative could be to just check the type field and make the
  interface take PopplerAnnot.
- poppler.extend-test-poppler-glib-to-show-more-page-annotatio.patch
  Makes test-poppler-glib print information about PopplerAnnotation and
  PopplerAction items associated with a page.
  This currently depends on the aforementioned patch, but if adopting
  that is difficult, I could also separate it out.
- poppler.signedness-of-PopplerAttachment.size.patch
  While running test-poppler-glib, I noticed that EmbFile will use size
  -1 to indicate that no size has been specified. This could be captured
  better by making PopplerAttachment.size gssize instead of gsize.

Kind regards

T.
-- 
Thomas Viehmann, http://thomas.viehmann.net/
>From 11d545692404100ec70c52ad1f16b870ee3df728 Mon Sep 17 00:00:00 2001
From: Thomas Viehmann <[email protected]>
Date: Sat, 17 Jan 2009 19:08:37 +0100
Subject: [PATCH] add support for file attachment annotations

---
 glib/poppler-annot.cc      |   63 ++++++++++++++++++++++++++++++++++++++++++++
 glib/poppler-annot.h       |    8 +++++
 glib/poppler-attachment.cc |    4 +--
 glib/poppler-document.cc   |    2 +-
 glib/poppler-page.cc       |    3 ++
 glib/poppler-private.h     |    4 +-
 glib/poppler.h             |    1 +
 7 files changed, 79 insertions(+), 6 deletions(-)

diff --git a/glib/poppler-annot.cc b/glib/poppler-annot.cc
index 067afcc..15d7178 100644
--- a/glib/poppler-annot.cc
+++ b/glib/poppler-annot.cc
@@ -24,6 +24,8 @@ typedef struct _PopplerAnnotClass         PopplerAnnotClass;
 typedef struct _PopplerAnnotMarkupClass   PopplerAnnotMarkupClass;
 typedef struct _PopplerAnnotFreeTextClass PopplerAnnotFreeTextClass;
 typedef struct _PopplerAnnotTextClass     PopplerAnnotTextClass;
+typedef struct _PopplerAnnotMovieClass    PopplerAnnotMovieClass;
+typedef struct _PopplerAnnotFileAttachmentClass PopplerAnnotFileAttachmentClass;
 
 struct _PopplerAnnot
 {
@@ -46,6 +48,16 @@ struct _PopplerAnnotMarkupClass
   PopplerAnnotClass parent_class;
 };
 
+struct _PopplerAnnotFileAttachment
+{
+  PopplerAnnotMarkup parent_instance;
+};
+
+struct _PopplerAnnotFileAttachmentClass
+{
+  PopplerAnnotMarkupClass parent_class;
+};
+
 struct _PopplerAnnotText
 {
   PopplerAnnotMarkup parent_instance;
@@ -68,6 +80,7 @@ struct _PopplerAnnotFreeTextClass
 
 G_DEFINE_TYPE (PopplerAnnot, poppler_annot, G_TYPE_OBJECT)
 G_DEFINE_TYPE (PopplerAnnotMarkup, poppler_annot_markup, POPPLER_TYPE_ANNOT)
+G_DEFINE_TYPE (PopplerAnnotFileAttachment, poppler_annot_file_attachment, POPPLER_TYPE_ANNOT_MARKUP)
 G_DEFINE_TYPE (PopplerAnnotText, poppler_annot_text, POPPLER_TYPE_ANNOT_MARKUP)
 G_DEFINE_TYPE (PopplerAnnotFreeText, poppler_annot_free_text, POPPLER_TYPE_ANNOT_MARKUP)
 
@@ -116,6 +129,27 @@ poppler_annot_markup_class_init (PopplerAnnotMarkupClass *klass)
 }
 
 static void
+poppler_annot_file_attachment_init (PopplerAnnotFileAttachment *poppler_annot)
+{
+}
+
+static void
+poppler_annot_file_attachment_class_init (PopplerAnnotFileAttachmentClass *klass)
+{
+}
+
+PopplerAnnot *
+_poppler_annot_file_attachment_new (Annot *annot)
+{
+  PopplerAnnot *poppler_annot;
+
+  poppler_annot = POPPLER_ANNOT (g_object_new (POPPLER_TYPE_ANNOT_FILE_ATTACHMENT, NULL));
+  poppler_annot->annot = annot;
+
+  return poppler_annot;
+}
+
+static void
 poppler_annot_text_init (PopplerAnnotText *poppler_annot)
 {
 }
@@ -532,6 +566,35 @@ poppler_annot_markup_get_external_data (PopplerAnnotMarkup *poppler_annot)
   return POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN;
 }
 
+/* PopplerAnnotFileAttachment */
+/**
+ * poppler_annot_file_attachment_get_attachment:
+ * @annot: a #PopplerAnnotFileAttachment
+ *
+ * Creates a #PopplerAttachment for the file of the file attachment annotation @annot.
+ * The #PopplerAttachment must be freed with g_free by the caller.
+ *
+ * Return value: @PopplerAttachment
+ **/
+PopplerAttachment*
+poppler_annot_file_attachment_get_attachment (PopplerAnnotFileAttachment *annot)
+{
+  AnnotFileAttachment *annot_file_attachment;
+  PopplerAttachment *attachment;
+
+  g_return_val_if_fail (POPPLER_IS_ANNOT_FILE_ATTACHMENT (annot), FALSE);
+
+
+  annot_file_attachment = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT (annot)->annot);
+
+  EmbFile* emb_file = new EmbFile (annot_file_attachment->getFile(), annot_file_attachment->getContents());
+  attachment = _poppler_attachment_new (emb_file);
+  delete emb_file;
+
+
+  return attachment;
+}
+
 /* PopplerAnnotText */
 /**
  * poppler_annot_text_get_is_open:
diff --git a/glib/poppler-annot.h b/glib/poppler-annot.h
index 3e38975..22a246e 100644
--- a/glib/poppler-annot.h
+++ b/glib/poppler-annot.h
@@ -33,6 +33,10 @@ G_BEGIN_DECLS
 #define POPPLER_ANNOT_MARKUP(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ANNOT_MARKUP, PopplerAnnotMarkup))
 #define POPPLER_IS_ANNOT_MARKUP(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ANNOT_MARKUP))
 
+#define POPPLER_TYPE_ANNOT_FILE_ATTACHMENT   (poppler_annot_file_attachment_get_type ())
+#define POPPLER_ANNOT_FILE_ATTACHMENT(obj)   (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ANNOT_MARKUP, PopplerAnnotFileAttachment))
+#define POPPLER_IS_ANNOT_FILE_ATTACHMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ANNOT_FILE_ATTACHMENT))
+
 #define POPPLER_TYPE_ANNOT_TEXT              (poppler_annot_text_get_type ())
 #define POPPLER_ANNOT_TEXT(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ANNOT_TEXT, PopplerAnnotText))
 #define POPPLER_IS_ANNOT_TEXT(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_ANNOT_TEXT))
@@ -148,6 +152,10 @@ gchar                        *poppler_annot_markup_get_subject                 (
 PopplerAnnotMarkupReplyType   poppler_annot_markup_get_reply_to                (PopplerAnnotMarkup *poppler_annot);
 PopplerAnnotExternalDataType  poppler_annot_markup_get_external_data           (PopplerAnnotMarkup *poppler_annot);
 
+/* PopplerAnnotFileAttachment */
+GType                         poppler_annot_file_attachment_get_type           (void) G_GNUC_CONST;
+PopplerAttachment            *poppler_annot_file_attachment_get_attachment     (PopplerAnnotFileAttachment *annot);
+
 /* PopplerAnnotText */
 GType                         poppler_annot_text_get_type                      (void) G_GNUC_CONST;
 gboolean                      poppler_annot_text_get_is_open                   (PopplerAnnotText *poppler_annot);
diff --git a/glib/poppler-attachment.cc b/glib/poppler-attachment.cc
index 1c3eef0..e959a06 100644
--- a/glib/poppler-attachment.cc
+++ b/glib/poppler-attachment.cc
@@ -77,12 +77,10 @@ poppler_attachment_finalize (GObject *obj)
 /* Public functions */
 
 PopplerAttachment *
-_poppler_attachment_new (PopplerDocument *document,
-			 EmbFile         *emb_file)
+_poppler_attachment_new (EmbFile         *emb_file)
 {
   PopplerAttachment *attachment;
 
-  g_assert (document != NULL);
   g_assert (emb_file != NULL);
 
   attachment = (PopplerAttachment *) g_object_new (POPPLER_TYPE_ATTACHMENT, NULL);
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
index 352149b..b83dd6e 100644
--- a/glib/poppler-document.cc
+++ b/glib/poppler-document.cc
@@ -430,7 +430,7 @@ poppler_document_get_attachments (PopplerDocument *document)
       EmbFile *emb_file;
 
       emb_file = catalog->embeddedFile (i);
-      attachment = _poppler_attachment_new (document, emb_file);
+      attachment = _poppler_attachment_new (emb_file);
       delete emb_file;
 
       retval = g_list_prepend (retval, attachment);
diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
index 29d124d..9d48198 100644
--- a/glib/poppler-page.cc
+++ b/glib/poppler-page.cc
@@ -1692,6 +1692,9 @@ poppler_page_get_annot_mapping (PopplerPage *page)
 
     switch (annot->getType ())
       {
+      case Annot::typeFileAttachment:
+        mapping->annot = _poppler_annot_file_attachment_new (annot);
+	break;
       case Annot::typeText:
         mapping->annot = _poppler_annot_text_new (annot);
 	break;
diff --git a/glib/poppler-private.h b/glib/poppler-private.h
index c4380ea..02c60d9 100644
--- a/glib/poppler-private.h
+++ b/glib/poppler-private.h
@@ -103,9 +103,9 @@ PopplerDest   *_poppler_dest_new_goto (PopplerDocument *document,
 				       LinkDest        *link_dest);
 PopplerFormField *_poppler_form_field_new (PopplerDocument *document,
 					   FormWidget      *field);
-PopplerAttachment *_poppler_attachment_new (PopplerDocument *document,
-					    EmbFile         *file);
+PopplerAttachment *_poppler_attachment_new (EmbFile         *file);
 PopplerAnnot      *_poppler_annot_new           (Annot *annot);
+PopplerAnnot      *_poppler_annot_file_attachment_new (Annot *annot);
 PopplerAnnot      *_poppler_annot_text_new      (Annot *annot);
 PopplerAnnot      *_poppler_annot_free_text_new (Annot *annot);
 
diff --git a/glib/poppler.h b/glib/poppler.h
index d554093..c9a6758 100644
--- a/glib/poppler.h
+++ b/glib/poppler.h
@@ -100,6 +100,7 @@ typedef struct _PopplerFormField        PopplerFormField;
 typedef struct _PopplerAttachment       PopplerAttachment;
 typedef struct _PopplerAnnot            PopplerAnnot;
 typedef struct _PopplerAnnotMarkup      PopplerAnnotMarkup;
+typedef struct _PopplerAnnotFileAttachment PopplerAnnotFileAttachment;
 typedef struct _PopplerAnnotText        PopplerAnnotText;
 typedef struct _PopplerAnnotFreeText    PopplerAnnotFreeText;
 typedef struct _PopplerAnnotCalloutLine PopplerAnnotCalloutLine;
-- 
1.5.6.5

>From 1cb2012d6d73f5f95931b929d7780c9e5a70b65b Mon Sep 17 00:00:00 2001
From: Thomas Viehmann <[email protected]>
Date: Sat, 17 Jan 2009 19:11:42 +0100
Subject: [PATCH] extend test-poppler-glib to show more page annotations and actions

---
 glib/test-poppler-glib.cc |  114 +++++++++++++++++++++++++++++++++++++-------
 1 files changed, 96 insertions(+), 18 deletions(-)

diff --git a/glib/test-poppler-glib.cc b/glib/test-poppler-glib.cc
index 1ff7010..7f2c1e5 100644
--- a/glib/test-poppler-glib.cc
+++ b/glib/test-poppler-glib.cc
@@ -364,6 +364,29 @@ form_field_print (PopplerFormField *field)
   printf ("\n");
 }
 
+static void
+dump_attachment(char* filename, PopplerAttachment* attachment)
+{
+  char *strdate;
+  g_print ("\t\tname: %s\n", attachment->name);
+  g_print ("\t\tdescription: %s\n", attachment->description);
+  g_print ("\t\tsize: %" G_GSIZE_FORMAT "\n", attachment->size);
+  strdate = poppler_format_date (attachment->ctime);
+  if (strdate)
+    {
+      g_print ("\t\tcreation date: %s\n", strdate);
+      g_free (strdate);
+    }
+  strdate = poppler_format_date (attachment->mtime);
+  if (strdate)
+    {
+      g_print ("\t\tmodification date: %s\n", strdate);
+      g_free (strdate);
+    }
+  poppler_attachment_save (attachment, filename, NULL);
+  g_print ("\n");
+}
+
 int main (int argc, char *argv[])
 {
   PopplerDocument *document;
@@ -539,7 +562,78 @@ int main (int argc, char *argv[])
       form_field_print (field);
       g_object_unref (field);
     }
+
+  list = poppler_page_get_link_mapping (page);
+  if (g_list_length (list)>0)
+      printf ("\tFound the following links:\n");
+  else
+      printf ("\tNo links found\n");
+
+  for (l = list; l != NULL; l = l->next)
+    {
+      PopplerLinkMapping *mapping = (PopplerLinkMapping *)l->data;
+
+      printf ("\t\t(%f, %f) - (%f, %f)\n",
+              mapping->area.x1,
+	      mapping->area.y1,
+	      mapping->area.x2,
+	      mapping->area.y2);
+      enum_value = g_enum_get_value ((GEnumClass *) g_type_class_ref (POPPLER_TYPE_ACTION_TYPE),
+                                     mapping->action->type);
+      g_print ("\t\t\tAction: %s (%d)\n", enum_value->value_name, mapping->action->type);
+      switch (mapping->action->type)
+        {
+        case POPPLER_ACTION_GOTO_DEST:
+            printf("\t\t\tDest title: %s\n", mapping->action->goto_dest.title);
+            printf("\t\t\tNamed dest: %s\n", mapping->action->goto_dest.dest->named_dest);
+            break;
+        default:
+            printf("\t\t\tDetails unimplemented for this dest\n");
+        }
+
+    }
   
+  poppler_page_free_link_mapping (list);
+
+  list = poppler_page_get_annot_mapping (page);
+  if (g_list_length (list)>0)
+    {
+      printf ("\tFound the following annotations:\n");
+      int i = 0;
+      for (l = list; l != NULL; l = l->next)
+	{
+	  PopplerAnnotMapping *mapping = (PopplerAnnotMapping *)l->data;
+
+	  printf ("\t\t(%f, %f) - (%f, %f)\n",
+		  mapping->area.x1,
+		  mapping->area.y1,
+		  mapping->area.x2,
+		  mapping->area.y2);
+	  enum_value = g_enum_get_value ((GEnumClass *) g_type_class_ref (POPPLER_TYPE_ANNOT_TYPE),
+					 poppler_annot_get_annot_type(mapping->annot));
+	  g_print ("\t\tAnnot type: %s (%d)\n", enum_value->value_name, 
+		   poppler_annot_get_annot_type (mapping->annot));
+	  PopplerAttachment* attachment;
+	  char *filename;
+	  switch (poppler_annot_get_annot_type(mapping->annot))
+	    {
+	    case POPPLER_ANNOT_FILE_ATTACHMENT:
+	      attachment = poppler_annot_file_attachment_get_attachment((PopplerAnnotFileAttachment*) mapping->annot);
+	      filename = g_strdup_printf ("annot-attach%d", i);
+	      dump_attachment(filename, attachment);
+	      g_free (filename);
+	      i++;
+	      break;
+	    default:
+	      printf("\t\tDetails unimplemented for this annotation type\n");
+	    }
+	}
+    }
+  else
+    printf ("\tNo annotations found\n");
+
+  poppler_page_free_annot_mapping (list);
+
   if (poppler_document_has_attachments (document))
     {
       int i = 0;
@@ -550,28 +644,12 @@ int main (int argc, char *argv[])
       for (l = list; l; l = l->next)
 	{
 	  PopplerAttachment *attachment;
-	  char *filename, *strdate;
+	  char *filename;
 
 	  filename = g_strdup_printf ("/tmp/attach%d", i);
 	  attachment = (PopplerAttachment *)l->data;
-	  g_print ("\tname: %s\n", attachment->name);
-	  g_print ("\tdescription: %s\n", attachment->description);
-	  g_print ("\tsize: %" G_GSIZE_FORMAT "\n", attachment->size);
-	  strdate = poppler_format_date (attachment->ctime);
-	  if (strdate)
-	    {
-	      g_print ("\tcreation date: %s\n", strdate);
-	      g_free (strdate);
-	    }
-	  strdate = poppler_format_date (attachment->mtime);
-	  if (strdate)
-	    {
-	      g_print ("\tmodification date: %s\n", strdate);
-	      g_free (strdate);
-	    }
-	  poppler_attachment_save (attachment, filename, NULL);
+	  dump_attachment(filename, attachment);
 	  g_free (filename);
-	  g_print ("\n");
 	  i++;
 	}
       g_list_foreach (list, (GFunc) g_object_unref, NULL);
-- 
1.5.6.5

>From 481ad3678439afeb81f99ddbb8d21e6cfcc125fa Mon Sep 17 00:00:00 2001
From: Thomas Viehmann <[email protected]>
Date: Sat, 17 Jan 2009 19:29:15 +0100
Subject: [PATCH] PopplerAttachment.size should be signed
 The type of PopplerAttachment.size should be signed (i.e. gssize)
 because poppler uses -1 to indicate that no size was given.

---
 glib/poppler-attachment.h |    2 +-
 glib/test-poppler-glib.cc |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/glib/poppler-attachment.h b/glib/poppler-attachment.h
index d506167..6e95379 100644
--- a/glib/poppler-attachment.h
+++ b/glib/poppler-attachment.h
@@ -43,7 +43,7 @@ struct _PopplerAttachment
 
   gchar *name;
   gchar *description;
-  gsize size;
+  gssize size;
   GTime mtime;
   GTime ctime;
   GString *checksum;
diff --git a/glib/test-poppler-glib.cc b/glib/test-poppler-glib.cc
index 7f2c1e5..c7f0a9f 100644
--- a/glib/test-poppler-glib.cc
+++ b/glib/test-poppler-glib.cc
@@ -370,7 +370,7 @@ dump_attachment(char* filename, PopplerAttachment* attachment)
   char *strdate;
   g_print ("\t\tname: %s\n", attachment->name);
   g_print ("\t\tdescription: %s\n", attachment->description);
-  g_print ("\t\tsize: %" G_GSIZE_FORMAT "\n", attachment->size);
+  g_print ("\t\tsize: %" G_GSSIZE_FORMAT "\n", attachment->size);
   strdate = poppler_format_date (attachment->ctime);
   if (strdate)
     {
-- 
1.5.6.5

_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to