[poppler] poppler/Annot.cc poppler/Annot.h poppler/Page.cc poppler/Page.h qt4/src

Carlos Garcia Campos carlosgc at kemper.freedesktop.org
Thu May 24 10:49:31 PDT 2012


 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(-)

New commits:
commit ba6406222f828e354323223fc4bdb01c1726fb49
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date:   Mon May 21 18:16:06 2012 +0200

    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

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);
 


More information about the poppler mailing list