Index: ChangeLog =================================================================== RCS file: /cvs/poppler/poppler/ChangeLog,v retrieving revision 1.345 diff -u -u -r1.345 ChangeLog --- ChangeLog 12 Apr 2006 06:52:07 -0000 1.345 +++ ChangeLog 16 Apr 2006 16:32:30 -0000 @@ -1,3 +1,15 @@ +2006-04-16 Carlos Garcia Campos + + * glib/poppler-action.cc: + * glib/poppler-action.h: + * glib/poppler-private.h: + * glib/poppler.h: + Add support for named destinations and named actions. + + * glib/poppler-document.cc: + * glib/poppler-document.h: + Allow to find named destinations in document. + 2006-04-12 Jeff Muizelaar * poppler/CairoOutputDev.cc: Index: glib/poppler-action.cc =================================================================== RCS file: /cvs/poppler/poppler/glib/poppler-action.cc,v retrieving revision 1.6 diff -u -u -r1.6 poppler-action.cc --- glib/poppler-action.cc 18 Jan 2006 22:32:13 -0000 1.6 +++ glib/poppler-action.cc 16 Apr 2006 16:32:30 -0000 @@ -16,12 +16,20 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include "poppler.h" #include "poppler-private.h" - -static PopplerDest * +/** + * poppler_dest_copy: + * @dest: a #PopplerDest + * + * Copies @dest, creating an identical #PopplerDest. + * + * Return value: a new destination identical to @dest + **/ +PopplerDest * poppler_dest_copy (PopplerDest *dest) { PopplerDest *new_dest; @@ -29,12 +37,28 @@ new_dest = g_new0 (PopplerDest, 1); memcpy (new_dest, dest, sizeof (PopplerDest)); + if (dest->named_dest) + new_dest->named_dest = g_strdup (dest->named_dest); + return new_dest; } -static void + +/** + * poppler_dest_free: + * @dest: a #PopplerDest + * + * Frees @dest + **/ +void poppler_dest_free (PopplerDest *dest) { + if (!dest) + return; + + if (dest->named_dest) + g_free (dest->named_dest); + g_free (dest); } @@ -64,15 +88,31 @@ return; /* Action specific stuff */ - if (action->type == POPPLER_ACTION_GOTO_DEST) { + switch (action->type) { + case POPPLER_ACTION_GOTO_DEST: poppler_dest_free (action->goto_dest.dest); - } else if (action->type == POPPLER_ACTION_GOTO_REMOTE) { + break; + case POPPLER_ACTION_GOTO_REMOTE: poppler_dest_free (action->goto_remote.dest); g_free (action->goto_remote.file_name); - } else if (action->type == POPPLER_ACTION_URI) { + break; + case POPPLER_ACTION_URI: g_free (action->uri.uri); + break; + case POPPLER_ACTION_LAUNCH: + g_free (action->launch.file_name); + g_free (action->launch.params); + break; + case POPPLER_ACTION_NAMED: + g_free (action->named.named_dest); + break; + case POPPLER_ACTION_MOVIE: + /* TODO */ + break; + default: + break; } - + g_free (action->any.title); g_free (action); } @@ -99,18 +139,42 @@ if (action->any.title != NULL) new_action->any.title = g_strdup (action->any.title); - if (action->type == POPPLER_ACTION_GOTO_DEST) { + switch (action->type) { + case POPPLER_ACTION_GOTO_DEST: new_action->goto_dest.dest = poppler_dest_copy (action->goto_dest.dest); - } else if (action->type == POPPLER_ACTION_GOTO_REMOTE) { + break; + case POPPLER_ACTION_GOTO_REMOTE: new_action->goto_remote.dest = poppler_dest_copy (action->goto_remote.dest); + if (action->goto_remote.file_name) + new_action->goto_remote.file_name = g_strdup (action->goto_remote.file_name); + break; + case POPPLER_ACTION_URI: + if (action->uri.uri) + new_action->uri.uri = g_strdup (action->uri.uri); + break; + case POPPLER_ACTION_LAUNCH: + if (action->launch.file_name) + new_action->launch.file_name = g_strdup (action->launch.file_name); + if (action->launch.params) + new_action->launch.params = g_strdup (action->launch.params); + break; + case POPPLER_ACTION_NAMED: + if (action->named.named_dest) + new_action->named.named_dest = g_strdup (action->named.named_dest); + break; + case POPPLER_ACTION_MOVIE: + /* TODO */ + break; + default: + break; } return new_action; } -static PopplerDest * -build_dest (PopplerDocument *document, - LinkDest *link_dest) +PopplerDest * +dest_new_goto (PopplerDocument *document, + LinkDest *link_dest) { PopplerDest *dest; @@ -176,6 +240,24 @@ return dest; } +static PopplerDest * +dest_new_named (UGooString *named_dest) +{ + PopplerDest *dest; + + dest = g_new0 (PopplerDest, 1); + + if (named_dest == NULL) { + dest->type = POPPLER_DEST_UNKNOWN; + return dest; + } + + dest->type = POPPLER_DEST_NAMED; + dest->named_dest = g_strdup (named_dest->getCString ()); + + return dest; +} + static void build_goto_dest (PopplerDocument *document, PopplerAction *action, @@ -186,7 +268,7 @@ /* Return if it isn't OK */ if (! link->isOk ()) { - action->goto_dest.dest = build_dest (NULL, NULL); + action->goto_dest.dest = dest_new_goto (NULL, NULL); return; } @@ -194,13 +276,11 @@ named_dest = link->getNamedDest (); if (link_dest != NULL) { - action->goto_dest.dest = build_dest (document, link_dest); + action->goto_dest.dest = dest_new_goto (document, link_dest); } else if (named_dest != NULL) { - link_dest = document->doc->findDest (named_dest); - action->goto_dest.dest = build_dest (document, link_dest); - delete link_dest; + action->goto_dest.dest = dest_new_named (named_dest); } else { - action->goto_dest.dest = build_dest (document, NULL); + action->goto_dest.dest = dest_new_goto (document, NULL); } } @@ -208,17 +288,28 @@ build_goto_remote (PopplerAction *action, LinkGoToR *link) { + LinkDest *link_dest; + UGooString *named_dest; + /* Return if it isn't OK */ if (! link->isOk ()) { - action->goto_remote.dest = build_dest (NULL, NULL); + action->goto_remote.dest = dest_new_goto (NULL, NULL); return; } if (link->getFileName()->getCString ()) action->goto_remote.file_name = g_strdup (link->getFileName()->getCString ()); - /* FIXME, we don't handle named dest yet. */ - action->goto_dest.dest = build_dest (NULL, link->getDest ()); + link_dest = link->getDest (); + named_dest = link->getNamedDest (); + + if (link_dest != NULL) { + action->goto_remote.dest = dest_new_goto (NULL, link_dest); + } else if (named_dest != NULL) { + action->goto_remote.dest = dest_new_named (named_dest); + } else { + action->goto_remote.dest = dest_new_goto (NULL, NULL); + } } static void @@ -229,7 +320,7 @@ action->launch.file_name = link->getFileName()->getCString (); } if (link->getParams()) { - action->launch.file_name = link->getParams()->getCString (); + action->launch.params = link->getParams()->getCString (); } } @@ -246,9 +337,13 @@ static void build_named (PopplerAction *action, - LinkAction *link) + LinkNamed *link) { - /* FIXME: Write */ + gchar *name; + + name = link->getName ()->getCString (); + if (name != NULL) + action->named.named_dest = g_strdup (name); } static void @@ -294,7 +389,7 @@ break; case actionNamed: action->type = POPPLER_ACTION_NAMED; - build_named (action, link); + build_named (action, dynamic_cast (link)); break; case actionMovie: action->type = POPPLER_ACTION_MOVIE; @@ -308,3 +403,10 @@ return action; } + +PopplerDest * +_poppler_dest_new_goto (PopplerDocument *document, + LinkDest *link_dest) +{ + return dest_new_goto (document, link_dest); +} Index: glib/poppler-action.h =================================================================== RCS file: /cvs/poppler/poppler/glib/poppler-action.h,v retrieving revision 1.4 diff -u -u -r1.4 poppler-action.h --- glib/poppler-action.h 31 Dec 2005 02:10:33 -0000 1.4 +++ glib/poppler-action.h 16 Apr 2006 16:32:30 -0000 @@ -47,6 +47,7 @@ POPPLER_DEST_FITB, POPPLER_DEST_FITBH, POPPLER_DEST_FITBV, + POPPLER_DEST_NAMED } PopplerDestType; /* Define the PopplerAction types */ @@ -58,8 +59,6 @@ typedef struct _PopplerActionNamed PopplerActionNamed; typedef struct _PopplerActionMovie PopplerActionMovie; -typedef struct _PopplerDest PopplerDest; - struct _PopplerDest { PopplerDestType type; @@ -70,6 +69,7 @@ double right; double top; double zoom; + gchar *named_dest; guint change_left : 1; guint change_top : 1; guint change_zoom : 1; @@ -146,9 +146,12 @@ #define POPPLER_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_ACTION, PopplerAction)) GType poppler_action_get_type (void) G_GNUC_CONST; + void poppler_action_free (PopplerAction *action); PopplerAction *poppler_action_copy (PopplerAction *action); +void poppler_dest_free (PopplerDest *dest); +PopplerDest *poppler_dest_copy (PopplerDest *dest); G_END_DECLS Index: glib/poppler-document.cc =================================================================== RCS file: /cvs/poppler/poppler/glib/poppler-document.cc,v retrieving revision 1.33 diff -u -u -r1.33 poppler-document.cc --- glib/poppler-document.cc 20 Mar 2006 19:12:29 -0000 1.33 +++ glib/poppler-document.cc 16 Apr 2006 16:32:31 -0000 @@ -315,6 +315,43 @@ return g_list_reverse (retval); } +/** + * poppler_document_find_dest: + * @document: A #PopplerDocument + * @link_name: a named destination + * + * Finds named destination @link_name in @document + * + * Return value: The #PopplerDest destination or %NULL if + * @link_name is not a destination. Returned value must + * be freed with #poppler_dest_free + **/ +PopplerDest * +poppler_document_find_dest (PopplerDocument *document, + const gchar *link_name) +{ + PopplerDest *dest = NULL; + LinkDest *link_dest = NULL; + UGooString *g_link_name; + + g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL); + g_return_val_if_fail (link_name != NULL, NULL); + + g_link_name = new UGooString (link_name); + + if (g_link_name) { + link_dest = document->doc->findDest (g_link_name); + delete g_link_name; + } + + if (link_dest) { + dest = _poppler_dest_new_goto (document, link_dest); + delete link_dest; + } + + return dest; +} + char *_poppler_goo_string_to_utf8(GooString *s) { char *result; Index: glib/poppler-document.h =================================================================== RCS file: /cvs/poppler/poppler/glib/poppler-document.h,v retrieving revision 1.18 diff -u -u -r1.18 poppler-document.h --- glib/poppler-document.h 24 Jan 2006 06:21:39 -0000 1.18 +++ glib/poppler-document.h 16 Apr 2006 16:32:31 -0000 @@ -104,7 +104,9 @@ gboolean poppler_document_has_attachments (PopplerDocument *document); GList *poppler_document_get_attachments (PopplerDocument *document); - +/* Links */ +PopplerDest *poppler_document_find_dest (PopplerDocument *document, + const gchar *link_name); /* Interface for getting the Index of a poppler_document */ GType poppler_index_iter_get_type (void) G_GNUC_CONST; Index: glib/poppler-private.h =================================================================== RCS file: /cvs/poppler/poppler/glib/poppler-private.h,v retrieving revision 1.14 diff -u -u -r1.14 poppler-private.h --- glib/poppler-private.h 28 Feb 2006 18:25:00 -0000 1.14 +++ glib/poppler-private.h 16 Apr 2006 16:32:31 -0000 @@ -64,6 +64,8 @@ PopplerAction *_poppler_action_new (PopplerDocument *document, LinkAction *link, const gchar *title); +PopplerDest *_poppler_dest_new_goto (PopplerDocument *document, + LinkDest *link_dest); PopplerAttachment *_poppler_attachment_new (PopplerDocument *document, EmbFile *file); Index: glib/poppler.h =================================================================== RCS file: /cvs/poppler/poppler/glib/poppler.h,v retrieving revision 1.11 diff -u -u -r1.11 poppler.h --- glib/poppler.h 12 Apr 2006 02:07:07 -0000 1.11 +++ glib/poppler.h 16 Apr 2006 16:32:31 -0000 @@ -51,6 +51,7 @@ typedef struct _PopplerFontInfo PopplerFontInfo; typedef struct _PopplerPSFile PopplerPSFile; typedef union _PopplerAction PopplerAction; +typedef struct _PopplerDest PopplerDest; typedef enum