Merge pull request #18824 from calixteman/issue18072

Write the display flags in F entry when saving an annotation (issue 18072)
This commit is contained in:
calixteman 2024-10-02 09:13:06 +02:00 committed by GitHub
commit 0308b8075f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 120 additions and 11 deletions

View File

@ -27,6 +27,7 @@ import {
getModificationDate, getModificationDate,
IDENTITY_MATRIX, IDENTITY_MATRIX,
info, info,
isArrayEqual,
LINE_DESCENT_FACTOR, LINE_DESCENT_FACTOR,
LINE_FACTOR, LINE_FACTOR,
OPS, OPS,
@ -723,6 +724,38 @@ class Annotation {
return !!(flags & flag); 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 * @private
*/ */
@ -2073,10 +2106,15 @@ class WidgetAnnotation extends Annotation {
async save(evaluator, task, annotationStorage) { async save(evaluator, task, annotationStorage) {
const storageEntry = annotationStorage?.get(this.data.id); const storageEntry = annotationStorage?.get(this.data.id);
const flags = this._buildFlags(storageEntry?.noView, storageEntry?.noPrint);
let value = storageEntry?.value, let value = storageEntry?.value,
rotation = storageEntry?.rotation; rotation = storageEntry?.rotation;
if (value === this.data.fieldValue || value === undefined) { if (value === this.data.fieldValue || value === undefined) {
if (!this._hasValueFromXFA && rotation === undefined) { if (
!this._hasValueFromXFA &&
rotation === undefined &&
flags === undefined
) {
return null; return null;
} }
value ||= this.data.fieldValue; value ||= this.data.fieldValue;
@ -2088,8 +2126,8 @@ class WidgetAnnotation extends Annotation {
!this._hasValueFromXFA && !this._hasValueFromXFA &&
Array.isArray(value) && Array.isArray(value) &&
Array.isArray(this.data.fieldValue) && Array.isArray(this.data.fieldValue) &&
value.length === this.data.fieldValue.length && isArrayEqual(value, this.data.fieldValue) &&
value.every((x, i) => x === this.data.fieldValue[i]) flags === undefined
) { ) {
return null; return null;
} }
@ -2106,7 +2144,7 @@ class WidgetAnnotation extends Annotation {
RenderingIntentFlag.SAVE, RenderingIntentFlag.SAVE,
annotationStorage annotationStorage
); );
if (appearance === null) { if (appearance === null && flags === undefined) {
// Appearance didn't change. // Appearance didn't change.
return null; return null;
} }
@ -2134,6 +2172,15 @@ class WidgetAnnotation extends Annotation {
dict.set(key, originalDict.getRaw(key)); 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 = { const xfa = {
path: this.data.fieldName, path: this.data.fieldName,
@ -3019,10 +3066,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
return null; return null;
} }
const storageEntry = annotationStorage.get(this.data.id); const storageEntry = annotationStorage.get(this.data.id);
const flags = this._buildFlags(storageEntry?.noView, storageEntry?.noPrint);
let rotation = storageEntry?.rotation, let rotation = storageEntry?.rotation,
value = storageEntry?.value; value = storageEntry?.value;
if (rotation === undefined) { if (rotation === undefined && flags === undefined) {
if (value === undefined) { if (value === undefined) {
return null; 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)) { if (!(dict instanceof Dict)) {
return null; return null;
} }
dict = dict.clone();
if (rotation === undefined) { if (rotation === undefined) {
rotation = this.rotation; rotation = this.rotation;
@ -3054,6 +3103,9 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
dict.set("V", name); dict.set("V", name);
dict.set("AS", name); dict.set("AS", name);
dict.set("M", `D:${getModificationDate()}`); dict.set("M", `D:${getModificationDate()}`);
if (flags !== undefined) {
dict.set("F", flags);
}
const maybeMK = this._getMKDict(rotation); const maybeMK = this._getMKDict(rotation);
if (maybeMK) { if (maybeMK) {
@ -3071,10 +3123,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
return null; return null;
} }
const storageEntry = annotationStorage.get(this.data.id); const storageEntry = annotationStorage.get(this.data.id);
const flags = this._buildFlags(storageEntry?.noView, storageEntry?.noPrint);
let rotation = storageEntry?.rotation, let rotation = storageEntry?.rotation,
value = storageEntry?.value; value = storageEntry?.value;
if (rotation === undefined) { if (rotation === undefined && flags === undefined) {
if (value === undefined) { if (value === undefined) {
return null; 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)) { if (!(dict instanceof Dict)) {
return null; return null;
} }
dict = dict.clone();
if (value === undefined) { if (value === undefined) {
value = this.data.fieldValue === this.data.buttonValue; value = this.data.fieldValue === this.data.buttonValue;
@ -3121,6 +3175,9 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
dict.set("AS", name); dict.set("AS", name);
dict.set("M", `D:${getModificationDate()}`); dict.set("M", `D:${getModificationDate()}`);
if (flags !== undefined) {
dict.set("F", flags);
}
const maybeMK = this._getMKDict(rotation); const maybeMK = this._getMKDict(rotation);
if (maybeMK) { if (maybeMK) {

View File

@ -378,9 +378,6 @@ class Page {
return this._parsedAnnotations.then(function (annotations) { return this._parsedAnnotations.then(function (annotations) {
const newRefsPromises = []; const newRefsPromises = [];
for (const annotation of annotations) { for (const annotation of annotations) {
if (!annotation.mustBePrinted(annotationStorage)) {
continue;
}
newRefsPromises.push( newRefsPromises.push(
annotation annotation
.save(partialEvaluator, task, annotationStorage) .save(partialEvaluator, task, annotationStorage)

View File

@ -671,3 +671,4 @@
!bug1919513.pdf !bug1919513.pdf
!issue16038.pdf !issue16038.pdf
!highlight_popup.pdf !highlight_popup.pdf
!issue18072.pdf

BIN
test/pdfs/issue18072.pdf Normal file

Binary file not shown.

View File

@ -10524,5 +10524,59 @@
"md5": "47262993e04689c327b7ce85396bce99", "md5": "47262993e04689c327b7ce85396bce99",
"rounds": 1, "rounds": 1,
"type": "eq" "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
}
}
} }
] ]