diff --git a/src/core/annotation.js b/src/core/annotation.js index 9f2719499..9b794afc5 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -27,6 +27,7 @@ import { getModificationDate, IDENTITY_MATRIX, info, + isArrayEqual, LINE_DESCENT_FACTOR, LINE_FACTOR, OPS, @@ -723,6 +724,38 @@ class Annotation { return !!(flags & flag); } + _buildFlags(noView, noPrint) { + let { flags } = this; + if (noView === undefined) { + if (noPrint === undefined) { + return undefined; + } + if (noPrint) { + return flags & ~AnnotationFlag.PRINT; + } + return (flags & ~AnnotationFlag.HIDDEN) | AnnotationFlag.PRINT; + } + + if (noView) { + flags |= AnnotationFlag.PRINT; + if (noPrint) { + // display === 1. + return (flags & ~AnnotationFlag.NOVIEW) | AnnotationFlag.HIDDEN; + } + // display === 3. + return (flags & ~AnnotationFlag.HIDDEN) | AnnotationFlag.NOVIEW; + } + + flags &= ~(AnnotationFlag.HIDDEN | AnnotationFlag.NOVIEW); + if (noPrint) { + // display === 2. + return flags & ~AnnotationFlag.PRINT; + } + + // display === 0. + return flags | AnnotationFlag.PRINT; + } + /** * @private */ @@ -2073,10 +2106,15 @@ class WidgetAnnotation extends Annotation { async save(evaluator, task, annotationStorage) { const storageEntry = annotationStorage?.get(this.data.id); + const flags = this._buildFlags(storageEntry?.noView, storageEntry?.noPrint); let value = storageEntry?.value, rotation = storageEntry?.rotation; if (value === this.data.fieldValue || value === undefined) { - if (!this._hasValueFromXFA && rotation === undefined) { + if ( + !this._hasValueFromXFA && + rotation === undefined && + flags === undefined + ) { return null; } value ||= this.data.fieldValue; @@ -2088,8 +2126,8 @@ class WidgetAnnotation extends Annotation { !this._hasValueFromXFA && Array.isArray(value) && Array.isArray(this.data.fieldValue) && - value.length === this.data.fieldValue.length && - value.every((x, i) => x === this.data.fieldValue[i]) + isArrayEqual(value, this.data.fieldValue) && + flags === undefined ) { return null; } @@ -2106,7 +2144,7 @@ class WidgetAnnotation extends Annotation { RenderingIntentFlag.SAVE, annotationStorage ); - if (appearance === null) { + if (appearance === null && flags === undefined) { // Appearance didn't change. return null; } @@ -2134,6 +2172,15 @@ class WidgetAnnotation extends Annotation { dict.set(key, originalDict.getRaw(key)); } } + if (flags !== undefined) { + dict.set("F", flags); + if (appearance === null && !needAppearances) { + const ap = originalDict.getRaw("AP"); + if (ap) { + dict.set("AP", ap); + } + } + } const xfa = { path: this.data.fieldName, @@ -3019,10 +3066,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { return null; } const storageEntry = annotationStorage.get(this.data.id); + const flags = this._buildFlags(storageEntry?.noView, storageEntry?.noPrint); let rotation = storageEntry?.rotation, value = storageEntry?.value; - if (rotation === undefined) { + if (rotation === undefined && flags === undefined) { if (value === undefined) { return null; } @@ -3033,10 +3081,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { } } - const dict = evaluator.xref.fetchIfRef(this.ref); + let dict = evaluator.xref.fetchIfRef(this.ref); if (!(dict instanceof Dict)) { return null; } + dict = dict.clone(); if (rotation === undefined) { rotation = this.rotation; @@ -3054,6 +3103,9 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { dict.set("V", name); dict.set("AS", name); dict.set("M", `D:${getModificationDate()}`); + if (flags !== undefined) { + dict.set("F", flags); + } const maybeMK = this._getMKDict(rotation); if (maybeMK) { @@ -3071,10 +3123,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { return null; } const storageEntry = annotationStorage.get(this.data.id); + const flags = this._buildFlags(storageEntry?.noView, storageEntry?.noPrint); let rotation = storageEntry?.rotation, value = storageEntry?.value; - if (rotation === undefined) { + if (rotation === undefined && flags === undefined) { if (value === undefined) { return null; } @@ -3085,10 +3138,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { } } - const dict = evaluator.xref.fetchIfRef(this.ref); + let dict = evaluator.xref.fetchIfRef(this.ref); if (!(dict instanceof Dict)) { return null; } + dict = dict.clone(); if (value === undefined) { value = this.data.fieldValue === this.data.buttonValue; @@ -3121,6 +3175,9 @@ class ButtonWidgetAnnotation extends WidgetAnnotation { dict.set("AS", name); dict.set("M", `D:${getModificationDate()}`); + if (flags !== undefined) { + dict.set("F", flags); + } const maybeMK = this._getMKDict(rotation); if (maybeMK) { diff --git a/src/core/document.js b/src/core/document.js index 982033dcb..59f36f97f 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -378,9 +378,6 @@ class Page { return this._parsedAnnotations.then(function (annotations) { const newRefsPromises = []; for (const annotation of annotations) { - if (!annotation.mustBePrinted(annotationStorage)) { - continue; - } newRefsPromises.push( annotation .save(partialEvaluator, task, annotationStorage) diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 187a90b76..cda431a14 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -671,3 +671,4 @@ !bug1919513.pdf !issue16038.pdf !highlight_popup.pdf +!issue18072.pdf diff --git a/test/pdfs/issue18072.pdf b/test/pdfs/issue18072.pdf new file mode 100644 index 000000000..0012ff3c5 Binary files /dev/null and b/test/pdfs/issue18072.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index b078193a4..fa1496654 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -10524,5 +10524,59 @@ "md5": "47262993e04689c327b7ce85396bce99", "rounds": 1, "type": "eq" + }, + { + "id": "issue18072-save-print", + "file": "pdfs/issue18072.pdf", + "md5": "231fe6f035da1f2ddf84f2a78ada20c5", + "rounds": 1, + "type": "eq", + "save": true, + "print": true, + "annotationStorage": { + "28R": { + "noView": true, + "noPrint": true + }, + "29R": { + "noView": true, + "noPrint": false + }, + "30R": { + "noView": false, + "noPrint": true + }, + "31R": { + "noView": false, + "noPrint": false + } + } + }, + { + "id": "issue18072-save-annotations", + "file": "pdfs/issue18072.pdf", + "md5": "231fe6f035da1f2ddf84f2a78ada20c5", + "rounds": 1, + "type": "eq", + "save": true, + "annotations": true, + "annotationStorage": { + "28R": { + "noView": true, + "noPrint": true + }, + "29R": { + "noView": true, + "noPrint": false + }, + "30R": { + "noView": false, + "noPrint": true + }, + "31R": { + "noView": false, + "noPrint": false + } + } } ]