[poppler] 3 commits - poppler/Annot.cc poppler/Annot.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Mon Apr 23 13:08:26 PDT 2012
poppler/Annot.cc | 104 +++++++++++++++++++++++++++++++++++++++++++++++--------
poppler/Annot.h | 6 +++
2 files changed, 95 insertions(+), 15 deletions(-)
New commits:
commit 26fd142a3608283fd41e07b54067a51a9db76e93
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat Apr 21 18:16:46 2012 +0200
Preserve z-index after annotation removal
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index b3bc97d..24ef57d 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -6446,7 +6446,7 @@ void Annots::appendAnnot(Annot *annot) {
GBool Annots::removeAnnot(Annot *annot) {
int idx = -1;
- // Search annot and remove it by swapping with last element
+ // Search annot and determine its index
for (int i = 0; idx == -1 && i < nAnnots; i++) {
if (annots[i] == annot) {
idx = i;
@@ -6455,7 +6455,8 @@ GBool Annots::removeAnnot(Annot *annot) {
if (idx == -1) {
return gFalse;
} else {
- annots[idx] = annots[--nAnnots];
+ --nAnnots;
+ memmove( annots + idx, annots + idx + 1, sizeof(annots[0]) * (nAnnots - idx) );
annot->decRefCnt();
return gTrue;
}
commit 7b10014c1fe9ef1cba57fd6b01c63129ac31386a
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat Apr 21 17:53:22 2012 +0200
Do not remove appearance stream if it's shared with other annotations
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 06d08d5..b3bc97d 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -774,6 +774,7 @@ AnnotIconFit::AnnotIconFit(Dict* dict) {
AnnotAppearance::AnnotAppearance(PDFDoc *docA, Object *dict) {
assert(dict->isDict());
+ doc = docA;
xref = docA->getXRef();
dict->copy(&appearDict);
}
@@ -841,19 +842,88 @@ int AnnotAppearance::getNumStates() {
return res;
}
+// Test if stateObj (a Ref or a Dict) points to the specified stream
+GBool AnnotAppearance::referencesStream(Object *stateObj, Ref refToStream) {
+ if (stateObj->isRef()) {
+ Ref r = stateObj->getRef();
+ if (r.num == refToStream.num && r.gen == refToStream.gen) {
+ return gTrue;
+ }
+ } else if (stateObj->isDict()) { // Test each value
+ const int size = stateObj->dictGetLength();
+ for (int i = 0; i < size; ++i) {
+ Object obj1;
+ stateObj->dictGetValNF(i, &obj1);
+ if (obj1.isRef()) {
+ Ref r = obj1.getRef();
+ if (r.num == refToStream.num && r.gen == refToStream.gen) {
+ return gTrue;
+ }
+ }
+ obj1.free();
+ }
+ }
+ return gFalse; // Not found
+}
+
+// Test if this AnnotAppearance references the specified stream
+GBool AnnotAppearance::referencesStream(Ref refToStream) {
+ Object obj1;
+ GBool found;
+
+ // Scan each state's ref/subdictionary
+ appearDict.dictLookupNF("N", &obj1);
+ found = referencesStream(&obj1, refToStream);
+ obj1.free();
+ if (found)
+ return gTrue;
+
+ appearDict.dictLookupNF("R", &obj1);
+ found = referencesStream(&obj1, refToStream);
+ obj1.free();
+ if (found)
+ return gTrue;
+
+ appearDict.dictLookupNF("D", &obj1);
+ found = referencesStream(&obj1, refToStream);
+ obj1.free();
+ return found;
+}
+
+// If this is the only annotation in the document that references the
+// specified appearance stream, remove the appearance stream
+void AnnotAppearance::removeStream(Ref refToStream) {
+ const int lastpage = doc->getNumPages();
+ for (int pg = 1; pg <= lastpage; ++pg) { // Scan all annotations in the document
+ Page *page = doc->getPage(pg);
+ if (!page) {
+ error(errSyntaxError, -1, "Failed check for shared annotation stream at page {0:d}", pg);
+ continue;
+ }
+ Annots *annots = page->getAnnots();
+ for (int i = 0; i < annots->getNumAnnots(); ++i) {
+ AnnotAppearance *annotAp = annots->getAnnot(i)->getAppearStreams();
+ if (annotAp && annotAp != this && annotAp->referencesStream(refToStream)) {
+ return; // Another annotation points to the stream -> Don't delete it
+ }
+ }
+ }
+
+ // TODO: stream resources (e.g. font), AP name tree
+ xref->removeIndirectObject(refToStream);
+}
+
// Removes stream if obj is a Ref, or removes pointed streams if obj is a Dict
void AnnotAppearance::removeStateStreams(Object *obj1) {
- // TODO: Remove XObject resources, check for XObjects shared by multiple
- // annotations, delete streams from name table (if any)
if (obj1->isRef()) {
- xref->removeIndirectObject(obj1->getRef());
+ removeStream(obj1->getRef());
} else if (obj1->isDict()) {
const int size = obj1->dictGetLength();
for (int i = 0; i < size; ++i) {
Object obj2;
obj1->dictGetValNF(i, &obj2);
if (obj2.isRef()) {
- xref->removeIndirectObject(obj2.getRef());
+ removeStream(obj2.getRef());
}
obj2.free();
}
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 98e4d70..04a1301 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -382,10 +382,16 @@ public:
// reset parent annotation's AP and AS after this call.
void removeAllStreams();
+ // Test if this AnnotAppearance references the specified stream
+ GBool referencesStream(Ref targetStreamRef);
+
private:
+ static GBool referencesStream(Object *stateObj, Ref targetStreamRef);
+ void removeStream(Ref refToStream);
void removeStateStreams(Object *state);
protected:
+ PDFDoc *doc;
XRef *xref; // the xref table for this PDF file
Object appearDict; // Annotation's AP
};
commit 7684c325929493ad9de01a891de0aef197e176dd
Author: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat Apr 21 20:26:49 2012 +0200
AnnotText: Always force 24x24 size with custom stamps, not only on first rendering
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 130b9bb..06d08d5 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -2248,8 +2248,6 @@ void AnnotText::draw(Gfx *gfx, GBool printing) {
if (!isVisible (printing))
return;
- double rectx2 = rect->x2;
- double recty2 = rect->y2;
if (appearance.isNull()) {
ca = opacity;
@@ -2280,9 +2278,11 @@ void AnnotText::draw(Gfx *gfx, GBool printing) {
appearBuf->append (ANNOT_TEXT_AP_CIRCLE);
appearBuf->append ("Q\n");
+ // Force 24x24 rectangle
+ PDFRectangle fixedRect(rect->x1, rect->y1, rect->x1 + 24, rect->y1 + 24);
+ appearBBox = new AnnotAppearanceBBox(&fixedRect);
double bbox[4];
- bbox[0] = bbox[1] = 0;
- bbox[2] = bbox[3] = 24;
+ appearBBox->getBBoxRect(bbox);
if (ca == 1) {
createForm(bbox, gFalse, NULL, &appearance);
} else {
@@ -2296,15 +2296,18 @@ void AnnotText::draw(Gfx *gfx, GBool printing) {
createForm(bbox, gFalse, &resDict, &appearance);
}
delete appearBuf;
-
- rectx2 = rect->x1 + 24;
- recty2 = rect->y1 + 24;
}
// draw the appearance stream
appearance.fetch(xref, &obj);
- gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
- rect->x1, rect->y1, rectx2, recty2);
+ if (appearBBox) {
+ gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+ appearBBox->getPageXMin(), appearBBox->getPageYMin(),
+ appearBBox->getPageXMax(), appearBBox->getPageYMax());
+ } else {
+ gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
+ rect->x1, rect->y1, rect->x2, rect->y2);
+ }
obj.free();
}
More information about the poppler
mailing list