From 9f95a14e916191b327ebe34eba41b9992b0572ca Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Mon, 24 Oct 2022 15:26:00 +0200 Subject: [PATCH] [Form] Don't use field appearances when /NeedAppearances is set to true (bug 1796741) When a form isn't changed, we used the appearances we had in the file, but when /NeedAppearances is true, all the appearances have to be regenerated whatever they're. --- src/core/annotation.js | 53 ++++++++++++++++++++++++++------------- test/pdfs/.gitignore | 1 + test/pdfs/bug1796741.pdf | Bin 0 -> 7068 bytes test/test_manifest.json | 7 ++++++ 4 files changed, 44 insertions(+), 17 deletions(-) create mode 100755 test/pdfs/bug1796741.pdf diff --git a/src/core/annotation.js b/src/core/annotation.js index aa312e157..54073b4c7 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -126,6 +126,8 @@ class AnnotationFactory { let subtype = dict.get("Subtype"); subtype = subtype instanceof Name ? subtype.name : null; + const acroFormDict = acroForm instanceof Dict ? acroForm : Dict.empty; + // Return the right annotation object based on the subtype and field type. const parameters = { xref, @@ -134,10 +136,12 @@ class AnnotationFactory { subtype, id, pdfManager, - acroForm: acroForm instanceof Dict ? acroForm : Dict.empty, + acroForm: acroFormDict, attachments, xfaDatasets, collectFields, + needAppearances: + !collectFields && acroFormDict.get("NeedAppearances") === true, pageIndex, }; @@ -508,6 +512,7 @@ class Annotation { } this._fallbackFontDict = null; + this._needAppearances = false; } /** @@ -1483,6 +1488,7 @@ class WidgetAnnotation extends Annotation { const dict = params.dict; const data = this.data; this.ref = params.ref; + this._needAppearances = params.needAppearances; data.annotationType = AnnotationType.WIDGET; if (data.fieldName === undefined) { @@ -1535,6 +1541,12 @@ class WidgetAnnotation extends Annotation { this._defaultAppearance ); + data.hasAppearance = + (this._needAppearances && + data.fieldValue !== undefined && + data.fieldValue !== null) || + data.hasAppearance; + const fieldType = getInheritableProperty({ dict, key: "FT" }); data.fieldType = fieldType instanceof Name ? fieldType.name : null; @@ -1909,18 +1921,25 @@ class WidgetAnnotation extends Annotation { rotation = storageEntry.rotation; } - if (rotation === undefined && value === undefined) { + if ( + rotation === undefined && + value === undefined && + !this._needAppearances + ) { if (!this._hasValueFromXFA || this.appearance) { // The annotation hasn't been rendered so use the appearance. return null; } } + // Empty or it has a trailing whitespace. + const colors = this.getBorderAndBackgroundAppearances(annotationStorage); + if (value === undefined) { // The annotation has its value in XFA datasets but not in the V field. value = this.data.fieldValue; if (!value) { - return ""; + return `/Tx BMC q ${colors}Q EMC`; } } @@ -1934,7 +1953,7 @@ class WidgetAnnotation extends Annotation { if (value === "") { // the field is empty: nothing to render - return ""; + return `/Tx BMC q ${colors}Q EMC`; } if (rotation === undefined) { @@ -2024,9 +2043,6 @@ class WidgetAnnotation extends Annotation { ); } - // Empty or it has a trailing whitespace. - const colors = this.getBorderAndBackgroundAppearances(annotationStorage); - if (alignment === 0 || alignment > 2) { // Left alignment: nothing to do return ( @@ -3020,18 +3036,21 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { return super._getAppearance(evaluator, task, annotationStorage); } - if (!annotationStorage) { - return null; + let exportedValue, rotation; + const storageEntry = annotationStorage + ? annotationStorage.get(this.data.id) + : undefined; + + if (storageEntry) { + rotation = storageEntry.rotation; + exportedValue = storageEntry.value; } - const storageEntry = annotationStorage.get(this.data.id); - if (!storageEntry) { - return null; - } - - const rotation = storageEntry.rotation; - let exportedValue = storageEntry.value; - if (rotation === undefined && exportedValue === undefined) { + if ( + rotation === undefined && + exportedValue === undefined && + !this._needAppearances + ) { // The annotation hasn't been rendered so use the appearance return null; } diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index dd308124f..64540ada1 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -548,3 +548,4 @@ !issue15340.pdf !bug1795263.pdf !issue15597.pdf +!bug1796741.pdf diff --git a/test/pdfs/bug1796741.pdf b/test/pdfs/bug1796741.pdf new file mode 100755 index 0000000000000000000000000000000000000000..78973b03c2d913b2c7c49d9db4a7c872bad00f8b GIT binary patch literal 7068 zcmeHMO>^V68MZe$bd*CUm!!=Jqs~se(@NlnM2Q+(8QHQMH!It>t#4u|k6;!H_=%cFO2pc3H~8_y7=wUCkvdE}?$HF_dNew4i|3q>}aDLV*j zWqmv%J5*Ul22BH~&Vm0C0#1*ngify!jPInHba6&3opfjh8kBfT{3Ai9MNSG%l z9W3Tyq#Q&%fVHxig!2W;%P`JiXT_6jA@Y>PzU~wp%>ZUqD)d!{(Wcc^vDQ+rR$dDm zS;Bn2WC;)mLR=Wb(=<{&KRrb7HIy&?5J;II? zmBMs7h)ABuc-^1`NN0(-C<|B74WXwxAD(Fo&$NYSbqmib&6m1;x)6z+7d%-a+h-B7pJ@|Ji?F&0 zyu9RWrK~c=3YZvbG23;>kO*?_Qm&2gx)BJiGdt9Bp_U8la$zOMB}}n)F0_)+N}{eL z)DTS{?m!9i4zro6XJ-A-3me}=>>tz(DgX_H}le>rko@F&{5+#yd?lp_;#f!-qIS>ga z{kGBa3%Zo(fu~(87=!cik@knuUUQLU zs{y4~S6A&TyDgGAHC@-GhD9x_1&LOA6KCwY6{o)|jI8a9dFmzMO0Cz@E}Mxw+iNzZ zqw-G=Y`H2O#c5j&vh9f_y=E(Fwhg*T$@fZ~Rh~quYrcoK2w!65Nug(M)B~oINvXQg z-Ez56b5+CRmL3}5&fciR{DttYDj;tu>h0i2$~+gzC0=w_#eh{j3Yd1$;{i5>VQ?e& zg+m#}mT9!C&eXI9wlh#W!+~M!(hnpnsFe-17v-C5bO&nBTH2^deqdvr>YJ?G>51O3 zE7=e1=zZ~2h-i3sYpi$1^^I{cxVl=+qVEj?oD^6#WUEz#cbv>Rim>d`s;MTga$tZh zXD)N)cs$JW&>sY|zGKY1pyk=V(dw9;eyiU#x~*VlIUWye7tN|0lSy6oj@{!p&E$@E zZMW-srfWF;R3jCtZcVpl7b6+0_x$&T>y}Qpm!zG7oT-P~7L?0j~R?RLXn|u10kr z0>!h}yuxt@54Xulv(5z<@HD~zZ zrJQ)<+Kh`}SbJ3l%r2`%)fy z3%Y!xe@UZ$)PE0@@c;4;X7&Tx@)cVJWAK5XzClbBOr>IRe}<{N3ydT?*B#s67uSH; zXoHuCD)K}U)sl1F#5^k+I1%0j zPV%q82;-zoC7rAI<{I0pzFKHz;RTXb^2KXvz_hJetR%<0KRFP~8QKP6Eps4Wy15%wnnfi?#@V${BPssF519UW)K|@ueYwb6wu6NrOzGxH; zIAun@5neAxR4mfaUihDsPUc)(Di!k7vXzOEG$3AnCZJg*X)@yd**q4BXB!G-}U;v zUeCj40T;is;jY!ev(Fu7AbO6~=SJVQO&&O&+wFLkH&mZ3^eVW8zwNDG<4U(4;eUJk zFZlgbUfZ}H;rayEr`x~!$JX{2U!ndpd7VogGqLs@Sx%JdS>JC