summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabio D'Urso <fabiodurso@hotmail.it>2012-10-09 15:24:02 +0200
committerCarlos Garcia Campos <carlosgc@gnome.org>2012-10-16 14:25:40 +0200
commit35c07fe40d7b18e19f6ef0f5615f9f5ac8195cf7 (patch)
tree5ba6f7954337f59de6f5811fe4141cdf5660ad9e
parent2127a977bbe9985aa58561116508ad4f08430a2c (diff)
AnnotWidget: Avoid repeatedly deleting and creating xref entries for appearance streams
Previously updating the appearance stream always involved deleting the old stream's xref entry and creating a new one. Since xref entry deletion causes the generation number to be incremented, this behavior caused the generation number to quickly rise during user input. This patch stops it by reusing the same entry as the old appearance stream in case of repeated modifications.
-rw-r--r--poppler/Annot.cc40
-rw-r--r--poppler/Annot.h1
2 files changed, 29 insertions, 12 deletions
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index dfbc6a33..675ec840 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -3774,6 +3774,8 @@ void AnnotWidget::initialize(PDFDoc *docA, Dict *dict) {
parent = NULL;
}
obj1.free();
+
+ updatedAppearanceStream.num = updatedAppearanceStream.gen = -1;
}
// Grand unified handler for preparing text strings to be drawn into form
@@ -4867,8 +4869,11 @@ void AnnotWidget::generateFieldAppearance() {
void AnnotWidget::updateAppearanceStream()
{
- // Destroy the old appearance if any
- invalidateAppearance();
+ // If this the first time updateAppearanceStream() is called on this widget,
+ // destroy the AP dictionary because we are going to create a new one.
+ if (updatedAppearanceStream.num == -1) {
+ invalidateAppearance(); // Delete AP dictionary and all referenced streams
+ }
// There's no need to create a new appearance stream if NeedAppearances is
// set, because it will be ignored next time anyway.
@@ -4879,19 +4884,30 @@ void AnnotWidget::updateAppearanceStream()
generateFieldAppearance();
// Fetch the appearance stream we've just created
- Object obj1, obj2;
- Ref apRef;
+ Object obj1;
appearance.fetch(xref, &obj1);
- apRef = xref->addIndirectObject(&obj1);
- obj1.free();
- // Write the AP dictionary
- obj1.initDict(xref);
- obj1.dictAdd(copyString("N"), obj2.initRef(apRef.num, apRef.gen));
- update("AP", &obj1);
+ // If this the first time updateAppearanceStream() is called on this widget,
+ // create a new AP dictionary containing the new appearance stream.
+ // Otherwise, just update the stream we had created previously.
+ if (updatedAppearanceStream.num == -1) {
+ // Write the appearance stream
+ updatedAppearanceStream = xref->addIndirectObject(&obj1);
+ obj1.free();
- // Update our internal pointers to the appearance dictionary
- appearStreams = new AnnotAppearance(doc, &obj1);
+ // Write the AP dictionary
+ Object obj2;
+ obj1.initDict(xref);
+ obj1.dictAdd(copyString("N"), obj2.initRef(updatedAppearanceStream.num, updatedAppearanceStream.gen));
+ update("AP", &obj1);
+
+ // Update our internal pointers to the appearance dictionary
+ appearStreams = new AnnotAppearance(doc, &obj1);
+ } else {
+ // Replace the existing appearance stream
+ xref->setModifiedObject(&obj1, updatedAppearanceStream);
+ obj1.free();
+ }
}
void AnnotWidget::draw(Gfx *gfx, GBool printing) {
diff --git a/poppler/Annot.h b/poppler/Annot.h
index c208bc76..7cbc1437 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -1298,6 +1298,7 @@ private:
// AnnotBorderBS border; // BS
Dict *parent; // Parent
GBool addDingbatsResource;
+ Ref updatedAppearanceStream; // {-1,-1} if updateAppearanceStream has never been called
};
//------------------------------------------------------------------------