[poppler] [Patch] Parse Additional Actions for Widget Annots.
Carlos Garcia Campos
carlosgc at gnome.org
Tue Mar 29 10:31:06 PDT 2011
Excerpts from jose.aliste at gmail.com's message of mar mar 29 10:35:08 +0200 2011:
> Hi,
>
> Here is a patch to parse the additional actions dict that is present
> in Widget Annots. This is one of the first patches we will need to get
> javascript support as many of the javascript in the pdfs are encoded
> in JavascriptActions that are associated to the AditionalActions
> dictionary. All comments welcome, specially about the way I am saving
> the AditionalActions as an Array of Pointers to LinkActions.
>
>
> Greetings,
>
>
> José
> From deb6fa54b20858d1aff74f87262b6ddc7b303335 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Jos=C3=A9=20Aliste?= <jaliste at src.gnome.org>
> Date: Tue, 29 Mar 2011 04:27:15 -0400
> Subject: [PATCH] Parse additionActions dictionary for Widget annots.
> ---
> poppler/Annot.cc | 45 ++++++++++++++++++++++++++++++++++++++++++++-
> poppler/Annot.h | 19 +++++++++++++++++--
> 2 files changed, 61 insertions(+), 3 deletions(-)
Additional actions are not specific to Widget annotations, Screen
annotation also have an AA entry, only Fo and Bl (focus-in, focus-out)
events are specific to widget annots.
> diff --git a/poppler/Annot.cc b/poppler/Annot.cc
> index 1f77c71..2996be9 100644
> --- a/poppler/Annot.cc
> +++ b/poppler/Annot.cc
> @@ -2759,7 +2759,50 @@ void AnnotWidget::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
> obj1.free();
> if(dict->lookup("AA", &obj1)->isDict()) {
> - additionActions = NULL;
> + Dict *addActionDict = obj1.getDict();
> + Object obj2;
> + additionActions = (LinkAction **) gmallocn ((NumberOfEvents), sizeof(LinkAction *));
We know the array size at compile time so we can use a stack allocated
array instead.
> + for (int i = 0; i < NumberOfEvents; i++) {
> + additionActions[i] = NULL;
> + }
Use memset instead.
> + for (int i = 0; i < addActionDict->getLength(); i++) {
> + GooString key(addActionDict->getKey(i));
> + int triggerEvent = -1;
> +
> + if (key.cmp("E")) {
> + triggerEvent = eventCursorEnter;
> + } else if (key.cmp("X")) {
> + triggerEvent = eventCursorExit;
> + } else if (key.cmp("D")) {
> + triggerEvent = eventMouseDown;
> + } else if (key.cmp("U")) {
> + triggerEvent = eventMouseUp;
> + } else if (key.cmp("Fo")) {
> + triggerEvent = eventFocusIn;
> + } else if (key.cmp("Bl")) {
> + triggerEvent = eventFocusOut;
> + } else if (key.cmp("PO")) {
> + triggerEvent = eventPageOpen;
> + } else if (key.cmp("PC")) {
> + triggerEvent = eventPageClose;
> + } else if (key.cmp("PV")) {
> + triggerEvent = eventPageVisible;
> + } else if (key.cmp("PI")) {
> + triggerEvent = eventPageInvisible;
> + }
We don't usually do this in poppler, instead of iterate the whole
dictionary comparing every entry we check the entries we are
interested in.
if (additionalActions.dictLookup("E", &obj1)->isDict())
additionActions[eventCursorEnter] = LinkAction::parseAction (&obj1, catalog->getBaseURI());
obj1.free();
if (additionalActions.dictLookup("X", &obj1)->isDict())
additionActions[eventCursorExit] = LinkAction::parseAction (&obj1, catalog->getBaseURI());
obj1.free();
......
something like that.
> + if (triggerEvent > 0) {
> + Object obj3;
> +
> + addActionDict->getVal(i,&obj3);
> + additionActions[triggerEvent] = LinkAction::parseAction (&obj3, catalog->getBaseURI());
> + obj3.free();
> + }
> +
> + }
> +
> } else {
> additionActions = NULL;
> }
The actions should be freed (deleted) in the destructor.
> diff --git a/poppler/Annot.h b/poppler/Annot.h
> index 93f82bf..4f522d7 100644
> --- a/poppler/Annot.h
> +++ b/poppler/Annot.h
> @@ -453,6 +453,21 @@ public:
> type3D // 3D 25
> };
> + enum AnnotTriggerEvent {
> + eventCursorEnter, // E
> + eventCursorExit, // X
> + eventMouseDown, // D
> + eventMouseUp, // U
> + eventFocusIn, // Fo
> + eventFocusOut, // Bl
> + eventPageOpen, // PO
> + eventPageClose, // PC
> + eventPageVisible, // PV
> + eventPageInvisible, // PI
> + NumberOfEvents
> + };
> +
> +
> Annot(XRef *xrefA, PDFRectangle *rectA, Catalog *catalog);
> Annot(XRef *xrefA, Dict *dict, Catalog *catalog);
> Annot(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj);
> @@ -1147,7 +1162,7 @@ public:
> AnnotWidgetHighlightMode getMode() { return mode; }
> AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs; }
> LinkAction *getAction() { return action; }
> - Dict *getAdditionActions() { return additionActions; }
> + LinkAction **getAdditionActions() { return additionActions; }
A method that returns the action for a given event might be useful
too.
LinkAction* getAdditionalAction(AnnotTriggerEvent event);
> Dict *getParent() { return parent; }
> private:
> @@ -1170,7 +1185,7 @@ private:
> AnnotWidgetHighlightMode mode; // H (Default I)
> AnnotAppearanceCharacs *appearCharacs; // MK
> LinkAction *action; // A
> - Dict *additionActions; // AA
> + LinkAction **additionActions; // AA
> // inherited from Annot
> // AnnotBorderBS border; // BS
> Dict *parent; // Parent
> --
> 1.7.3.5
Regards,
--
Carlos Garcia Campos
PGP key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/poppler/attachments/20110329/a9e171d3/attachment.pgp>
More information about the poppler
mailing list