diff options
author | Fabio D'Urso <fabiodurso@hotmail.it> | 2012-10-09 15:24:02 +0200 |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@gnome.org> | 2012-10-16 14:25:40 +0200 |
commit | 35c07fe40d7b18e19f6ef0f5615f9f5ac8195cf7 (patch) | |
tree | 5ba6f7954337f59de6f5811fe4141cdf5660ad9e | |
parent | 2127a977bbe9985aa58561116508ad4f08430a2c (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.cc | 40 | ||||
-rw-r--r-- | poppler/Annot.h | 1 |
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 }; //------------------------------------------------------------------------ |