On Sunday, May 20, 2012 07:04:45 PM Fabio D'Urso wrote: > On Sunday, May 20, 2012 12:27:52 PM Carlos Garcia Campos wrote: > > Why doesn't Page::removeAnnot() also remove the appearances? I've > > noticed that the qt4 implementation removes the popup and appearances > > manually. [...] > > What happens with all other objects referenced by annotations? I guess > > they are all left in the document, should we remove them too? like the > > appearances? [...] > > Maybe we could add a Annot::removeAnnotFromPage (or something like > > that) so that every annotation can implement it to remove the objects > > it references and not referenced by others.
The attached patch defines a virtual Annot::removeReferencedObjects method that each annotation type can reimplement. The base implementation takes care of removing the appearance stream. The AnnotMarkup implementation takes care of removing the popup too. > I have some doubts about setting /P if the annotation has no /P or a wrong > value, because that would mean that annotations are automatically modified > as soon as the document is loaded. This patch implements the following behavior: - When parsing existing annotations, /P is ignored and the in-memory page field is always set to the page which the annotation was read from (without setting or changing the actual /P value). - When adding a new annotation to a given page, /P is set accordingly. Fabio
From e798145619ea6d59eb1b24a6a3680363f54e9c8a Mon Sep 17 00:00:00 2001 From: Fabio D'Urso <[email protected]> Date: Mon, 21 May 2012 18:16:06 +0200 Subject: [PATCH] Added Annot::removeReferencedObjects + Always set annotations' page field - Now Page::removeAnnot calls Annot::removeReferencedObjects, which takes care of removing referenced objects (such as the annot popup and the appearance streams). - Previously, Annot's page field was set only if the annotation dictionary contained /P --- poppler/Annot.cc | 40 ++++++++++++++++++++++++++++++++++------ poppler/Annot.h | 13 +++++++++---- poppler/Page.cc | 7 ++++--- poppler/Page.h | 2 +- qt4/src/poppler-annotation.cc | 8 -------- 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/poppler/Annot.cc b/poppler/Annot.cc index 8e1e760..9778bd2 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -1185,6 +1185,7 @@ void Annot::initialize(PDFDoc *docA, Dict *dict) { } obj1.free(); + // Note: This value is overwritten by Annots ctor if (dict->lookupNF("P", &obj1)->isRef()) { Ref ref = obj1.getRef(); @@ -1416,13 +1417,22 @@ void Annot::setColor(AnnotColor *new_color) { } } -void Annot::setPage(Ref *pageRef, int pageIndex) -{ +void Annot::setPage(int pageIndex, GBool updateP) { + Page *pageobj = doc->getPage(pageIndex); Object obj1; - obj1.initRef(pageRef->num, pageRef->gen); - update("P", &obj1); - page = pageIndex; + if (pageobj) { + Ref pageRef = pageobj->getRef(); + obj1.initRef(pageRef.num, pageRef.gen); + page = pageIndex; + } else { + obj1.initNull(); + page = 0; + } + + if (updateP) { + update("P", &obj1); + } } void Annot::setAppearanceState(const char *state) { @@ -1484,6 +1494,11 @@ void Annot::readArrayNum(Object *pdfArray, int key, double *value) { valueObject.free(); } +void Annot::removeReferencedObjects() { + // Remove appearance streams (if any) + invalidateAppearance(); +} + void Annot::incRefCnt() { refCnt++; } @@ -1934,6 +1949,18 @@ void AnnotMarkup::setDate(GooString *new_date) { update ("CreationDate", &obj1); } +void AnnotMarkup::removeReferencedObjects() { + Page *pageobj = doc->getPage(page); + assert(pageobj != NULL); // We're called when removing an annot from a page + + // Remove popup + if (popup) { + pageobj->removeAnnot(popup); + } + + Annot::removeReferencedObjects(); +} + //------------------------------------------------------------------------ // AnnotText //------------------------------------------------------------------------ @@ -6400,7 +6427,7 @@ Annot3D::Activation::Activation(Dict *dict) { // Annots //------------------------------------------------------------------------ -Annots::Annots(PDFDoc *docA, Object *annotsObj) { +Annots::Annots(PDFDoc *docA, int page, Object *annotsObj) { Annot *annot; Object obj1; int i; @@ -6421,6 +6448,7 @@ Annots::Annots(PDFDoc *docA, Object *annotsObj) { annot = createAnnot (obj1.getDict(), &obj2); if (annot) { if (annot->isOk()) { + annot->setPage(page, gFalse); // Don't change /P appendAnnot(annot); } annot->decRefCnt(); diff --git a/poppler/Annot.h b/poppler/Annot.h index 04a1301..0d20cc7 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -43,6 +43,7 @@ class Gfx; class CharCodeToUnicode; class GfxFont; class GfxResources; +class Page; class PDFDoc; class Form; class FormWidget; @@ -471,6 +472,8 @@ private: //------------------------------------------------------------------------ class Annot { + friend class Annots; + friend class Page; public: enum AnnotFlag { flagUnknown = 0x0000, @@ -551,8 +554,6 @@ public: // new_color. void setColor(AnnotColor *new_color); - void setPage(Ref *pageRef, int pageIndex); - void setAppearanceState(const char *state); // Delete appearance streams and reset appearance state @@ -587,10 +588,12 @@ private: // write vStr[i:j[ in appearBuf void initialize (PDFDoc *docA, Dict *dict); + void setPage (int new_page, GBool updateP); // Called by Page::addAnnot and Annots ctor protected: virtual ~Annot(); + virtual void removeReferencedObjects(); // Called by Page::removeAnnot void setColor(AnnotColor *color, GBool fill); void drawCircle(double cx, double cy, double r, GBool fill); void drawCircleTopLeft(double cx, double cy, double r); @@ -699,6 +702,8 @@ public: void setDate(GooString *new_date); protected: + virtual void removeReferencedObjects(); + GooString *label; // T (Default autor) AnnotPopup *popup; // Popup double opacity; // CA (Default 1.0) @@ -1365,8 +1370,8 @@ private: class Annots { public: - // Build a list of Annot objects. - Annots(PDFDoc *docA, Object *annotsObj); + // Build a list of Annot objects and call setPage on them + Annots(PDFDoc *docA, int page, Object *annotsObj); ~Annots(); diff --git a/poppler/Page.cc b/poppler/Page.cc index eccc198..87bc3a4 100644 --- a/poppler/Page.cc +++ b/poppler/Page.cc @@ -348,7 +348,7 @@ Page::~Page() { Annots *Page::getAnnots() { if (!annots) { Object obj; - annots = new Annots(doc, getAnnots(&obj)); + annots = new Annots(doc, num, getAnnots(&obj)); obj.free(); } @@ -391,8 +391,7 @@ void Page::addAnnot(Annot *annot) { } annots->appendAnnot(annot); - - annot->setPage(&pageRef, num); + annot->setPage(num, gTrue); } void Page::removeAnnot(Annot *annot) { @@ -428,6 +427,8 @@ void Page::removeAnnot(Annot *annot) { } } annArray.free(); + annot->removeReferencedObjects(); // Note: Might recurse in removeAnnot again + annot->setPage(0, gFalse); } Links *Page::getLinks() { diff --git a/poppler/Page.h b/poppler/Page.h index e2e666c..78cedc4 100644 --- a/poppler/Page.h +++ b/poppler/Page.h @@ -164,6 +164,7 @@ public: Dict *getPieceInfo() { return attrs->getPieceInfo(); } Dict *getSeparationInfo() { return attrs->getSeparationInfo(); } PDFDoc *getDoc() { return doc; } + Ref getRef() { return pageRef; } // Get resource dictionary. Dict *getResourceDict() { return attrs->getResourceDict(); } @@ -173,7 +174,6 @@ public: // Add a new annotation to the page void addAnnot(Annot *annot); // Remove an existing annotation from the page - // Note: Caller is responsible for deleting popup and appearance streams too void removeAnnot(Annot *annot); // Return a list of links. diff --git a/qt4/src/poppler-annotation.cc b/qt4/src/poppler-annotation.cc index 4d7cd84..59db52d 100644 --- a/qt4/src/poppler-annotation.cc +++ b/qt4/src/poppler-annotation.cc @@ -510,14 +510,6 @@ void AnnotationPrivate::removeAnnotationFromPage(::Page *pdfPage, const Annotati return; } - // Remove popup window - AnnotMarkup *markupann = dynamic_cast<AnnotMarkup*>(ann->d_ptr->pdfAnnot); - if (markupann && markupann->getPopup()) - pdfPage->removeAnnot(markupann->getPopup()); - - // Remove appearance streams (if any) - ann->d_ptr->pdfAnnot->invalidateAppearance(); - // Remove annotation pdfPage->removeAnnot(ann->d_ptr->pdfAnnot); -- 1.7.6.5
_______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
