Carlos, thanks for the review. Here is an updated patch. I finally decided to have only one enum for TriggerEvents, so we can have methods AnnotScreen::getAdditionAction(AnnotTriggerEvent event) and AnnotWidget::getAdditionAction(AnnotTriggerEvent event) of giving eventFocusOut or eventFocusIn to a screen Annotation will just give you a NULL.
I changed to use a stack allocated pointer of LinkActions. If you feel there is a better data struct for this, let me know. On Tue, Mar 29, 2011 at 1:31 PM, Carlos Garcia Campos <[email protected]> wrote: > Excerpts from [email protected]'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?= <[email protected]> >> 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 >
From e1576c8d6be31721ffeab52c4aa936eef1195d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Aliste?= <[email protected]> Date: Tue, 29 Mar 2011 04:27:15 -0400 Subject: [PATCH] Parse additionActions dictionary for Widget annots. --- poppler/Annot.cc | 102 +++++++++++++++++++++++++++++++++++++++++++++++++----- poppler/Annot.h | 31 +++++++++++++--- 2 files changed, 118 insertions(+), 15 deletions(-) diff --git a/poppler/Annot.cc b/poppler/Annot.cc index 1f77c71..faab471 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -1350,6 +1350,72 @@ void Annot::draw(Gfx *gfx, GBool printing) { obj.free(); } +// Parse Actions in AdditionActions dictionary that are common to Screen and Widget annots +void Annot::parseAdditionActions (LinkAction **additionActions, Object *addActionDict, GooString *baseURI) +{ + Object obj2; + + if (addActionDict->dictLookup("E", &obj2)->isDict()) + additionActions[eventCursorEnter] = LinkAction::parseAction (&obj2, baseURI); + obj2.free(); + + if (addActionDict->dictLookup("X", &obj2)->isDict()) + additionActions[eventCursorExit] = LinkAction::parseAction (&obj2, baseURI); + obj2.free(); + + if (addActionDict->dictLookup("D", &obj2)->isDict()) + additionActions[eventMouseDown] = LinkAction::parseAction (&obj2, baseURI); + obj2.free(); + + if (addActionDict->dictLookup("U", &obj2)->isDict()) + additionActions[eventMouseUp] = LinkAction::parseAction (&obj2, baseURI); + obj2.free(); + + if (addActionDict->dictLookup("PO", &obj2)->isDict()) + additionActions[eventPageOpen] = LinkAction::parseAction (&obj2, baseURI); + obj2.free(); + + if (addActionDict->dictLookup("PC", &obj2)->isDict()) + additionActions[eventPageClose] = LinkAction::parseAction (&obj2, baseURI); + obj2.free(); + + if (addActionDict->dictLookup("PV", &obj2)->isDict()) + additionActions[eventPageVisible] = LinkAction::parseAction (&obj2, baseURI); + obj2.free(); + + if (addActionDict->dictLookup("PI", &obj2)->isDict()) + additionActions[eventPageInvisible] = LinkAction::parseAction (&obj2, baseURI); + obj2.free(); + + } + +// Delete additionActions that are common to Screen and Widget annots +void Annot::deleteAdditionActions(LinkAction **additionActions) { + if (additionActions[eventCursorEnter]) + delete additionActions[eventCursorEnter]; + + if (additionActions[eventCursorExit]) + delete additionActions[eventCursorExit]; + + if (additionActions[eventMouseDown]) + delete additionActions[eventMouseDown]; + + if (additionActions[eventMouseUp]) + delete additionActions[eventMouseUp]; + + if (additionActions[eventPageOpen]) + delete additionActions[eventPageOpen]; + + if (additionActions[eventPageClose]) + delete additionActions[eventPageClose]; + + if (additionActions[eventPageVisible]) + delete additionActions[eventPageVisible]; + + if (additionActions[eventPageInvisible]) + delete additionActions[eventPageInvisible]; +} + //------------------------------------------------------------------------ // AnnotPopup //------------------------------------------------------------------------ @@ -2715,12 +2781,16 @@ AnnotWidget::~AnnotWidget() { if (action) delete action; - - if (additionActions) - delete additionActions; - + + Annot::deleteAdditionActions(additionActions); + if (additionActions[eventFocusIn]) + delete additionActions[eventFocusIn]; + if (additionActions[eventFocusOut]) + delete additionActions[eventFocusOut]; + if (parent) delete parent; + } void AnnotWidget::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) { @@ -2758,10 +2828,20 @@ void AnnotWidget::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) { } obj1.free(); + memset (additionActions, 0, EventsNumber); + if(dict->lookup("AA", &obj1)->isDict()) { - additionActions = NULL; - } else { - additionActions = NULL; + Object obj2; + + Annot::parseAdditionActions(additionActions, &obj1, catalog->getBaseURI()); + + if (obj1.dictLookup("Fo", &obj2)->isDict()) + additionActions[eventFocusIn] = LinkAction::parseAction(&obj2, catalog->getBaseURI()); + obj2.free(); + + if (obj1.dictLookup("Bl", &obj2)->isDict()) + additionActions[eventFocusOut] = LinkAction::parseAction(&obj2, catalog->getBaseURI()); + obj2.free(); } obj1.free(); @@ -4066,7 +4146,7 @@ AnnotScreen::~AnnotScreen() { if (action) delete action; - additionAction.free(); + Annot::deleteAdditionActions(additionActions); } void AnnotScreen::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) { @@ -4088,8 +4168,12 @@ void AnnotScreen::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) { ok = gFalse; } } + obj1.free(); - dict->lookup("AA", &additionAction); + memset(additionActions, 0, EventsNumber); + if (dict->lookup("AA", &obj1)->isDict()) { + Annot::parseAdditionActions (additionActions, &obj1, catalog->getBaseURI()); + } appearCharacs = NULL; if(dict->lookup("MK", &obj1)->isDict()) { diff --git a/poppler/Annot.h b/poppler/Annot.h index 93f82bf..ad31118 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 + EventsNumber + }; + + Annot(XRef *xrefA, PDFRectangle *rectA, Catalog *catalog); Annot(XRef *xrefA, Dict *dict, Catalog *catalog); Annot(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj); @@ -525,7 +540,9 @@ protected: void createResourcesDict(char *formName, Object *formStream, char *stateName, double opacity, char *blendMode, Object *resDict); GBool isVisible(GBool printing); - + static void parseAdditionActions(LinkAction **additionActions, Object *additionActionsDict, + GooString *baseURI); + static void deleteAdditionActions (LinkAction **additionActions); // Updates the field key of the annotation dictionary // and sets M to the current time void update(const char *key, Object *value); @@ -721,8 +738,9 @@ class AnnotScreen: public Annot { AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs; } LinkAction* getAction() { return action; } - Object* getAdditionActions() { return &additionAction; } - + LinkAction **getAdditionActions() { return additionActions; } + LinkAction *getAdditionAction(AnnotTriggerEvent event) { return additionActions[event]; } + private: void initialize(XRef *xrefA, Catalog *catalog, Dict *dict); @@ -732,7 +750,7 @@ class AnnotScreen: public Annot { AnnotAppearanceCharacs* appearCharacs; // MK LinkAction *action; // A - Object additionAction; // AA + LinkAction *additionActions[EventsNumber]; // AA }; //------------------------------------------------------------------------ @@ -1147,7 +1165,8 @@ public: AnnotWidgetHighlightMode getMode() { return mode; } AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs; } LinkAction *getAction() { return action; } - Dict *getAdditionActions() { return additionActions; } + LinkAction **getAdditionActions() { return additionActions; } + LinkAction *getAdditionAction(AnnotTriggerEvent event) { return additionActions[event]; } Dict *getParent() { return parent; } private: @@ -1170,7 +1189,7 @@ private: AnnotWidgetHighlightMode mode; // H (Default I) AnnotAppearanceCharacs *appearCharacs; // MK LinkAction *action; // A - Dict *additionActions; // AA + LinkAction *additionActions[EventsNumber]; // AA // inherited from Annot // AnnotBorderBS border; // BS Dict *parent; // Parent -- 1.7.3.5
_______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
