From 58e4d92884a118937abb1569c16b501cbba42b68 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Thu, 9 Feb 2023 14:58:41 +0100 Subject: [PATCH] [Annotation] For choice widget, use the I entry instead of the V one (bug 1770750) It isn't really conform to the specifications but Acrobat is working like that... --- src/core/annotation.js | 57 ++++++++++++++++++++++++++++++++++----- test/pdfs/.gitignore | 1 + test/pdfs/bug1770750.pdf | Bin 0 -> 7170 bytes test/test_manifest.json | 8 ++++++ 4 files changed, 59 insertions(+), 7 deletions(-) create mode 100755 test/pdfs/bug1770750.pdf diff --git a/src/core/annotation.js b/src/core/annotation.js index 690ecace3..add90e7c6 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -1791,6 +1791,8 @@ class WidgetAnnotation extends Annotation { return mk.size > 0 ? mk : null; } + amendSavedDict(annotationStorage, dict) {} + async save(evaluator, task, annotationStorage) { const storageEntry = annotationStorage ? annotationStorage.get(this.data.id) @@ -1868,6 +1870,7 @@ class WidgetAnnotation extends Annotation { : stringToUTF16String(val, /* bigEndian = */ true); }; dict.set("V", Array.isArray(value) ? value.map(encoder) : encoder(value)); + this.amendSavedDict(annotationStorage, dict); const maybeMK = this._getMKDict(rotation); if (maybeMK) { @@ -3144,6 +3147,10 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { super(params); const { dict, xref } = params; + + this.indices = dict.getArray("I"); + this.hasIndices = Array.isArray(this.indices) && this.indices.length > 0; + // Determine the options. The options array may consist of strings or // arrays. If the array consists of arrays, then the first element of // each array is the export value and the second element of each array is @@ -3172,14 +3179,28 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { } } - // The field value can be `null` if no item is selected, a string if one - // item is selected or an array of strings if multiple items are selected. - // For consistency in the API and convenience in the display layer, we - // always make the field value an array with zero, one or multiple items. - if (typeof this.data.fieldValue === "string") { - this.data.fieldValue = [this.data.fieldValue]; - } else if (!this.data.fieldValue) { + if (!this.hasIndices) { + // The field value can be `null` if no item is selected, a string if one + // item is selected or an array of strings if multiple items are selected. + // For consistency in the API and convenience in the display layer, we + // always make the field value an array with zero, one or multiple items. + if (typeof this.data.fieldValue === "string") { + this.data.fieldValue = [this.data.fieldValue]; + } else if (!this.data.fieldValue) { + this.data.fieldValue = []; + } + } else { + // The specs say that we should have an indices array only with + // multiselectable Choice and the "V" entry should have the + // precedence, but Acrobat itself is using it whatever the + // the "V" entry is (see bug 1770750). this.data.fieldValue = []; + const ii = this.data.options.length; + for (const i of this.indices) { + if (Number.isInteger(i) && i >= 0 && i < ii) { + this.data.fieldValue.push(this.data.options[i].exportValue); + } + } } // Process field flags for the display layer. @@ -3212,6 +3233,28 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation { }; } + amendSavedDict(annotationStorage, dict) { + if (!this.hasIndices) { + return; + } + const storageEntry = annotationStorage + ? annotationStorage.get(this.data.id) + : undefined; + let values = storageEntry && storageEntry.value; + if (!Array.isArray(values)) { + values = [values]; + } + const indices = []; + const { options } = this.data; + for (let i = 0, j = 0, ii = options.length; i < ii; i++) { + if (options[i].exportValue === values[j]) { + indices.push(i); + j += 1; + } + } + dict.set("I", indices); + } + async _getAppearance(evaluator, task, intent, annotationStorage) { if (this.data.combo) { return super._getAppearance(evaluator, task, intent, annotationStorage); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 73ddec55f..17b77b87e 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -573,3 +573,4 @@ !bug1811510.pdf !bug1815476.pdf !issue16021.pdf +!bug1770750.pdf diff --git a/test/pdfs/bug1770750.pdf b/test/pdfs/bug1770750.pdf new file mode 100755 index 0000000000000000000000000000000000000000..1e5ee370605d14d1c3b17e6e84468fed13cf7bc1 GIT binary patch literal 7170 zcmeHM$!_Dw8MZrfiRKXGl1y?cC}@luiBu#-QVVPkWXtX`rqyjzHpNnN zY0C}d1p?$Hl0zOMhk1>>MUFu(LB1*$7q^uj2bg2qpjgYlRDJc=_VMA_%APUw_pEMOTUrco4}=2;ZRJSC=86r8bz%(+Ew zcC+Gy9zr7$3$nl8;&C8tOX1Q-A#>`zxyY7;KH>2qyCmjdKVAXX7wN5DWd62*}<^Z z*6Ri$f{GT(2L6HUFuad3@bq|wF}%ckE<0-UEkaM=#)b!71GprZIU656T2aLz|>U`CKllJ z68;Vbe3pn9uQ2iR%+76-afaO45ZI#=kc2BS`^t8AmD zS**MkHnM~Te900ZFc0yd4^PrawfOXi&B3f!Cv~I~#KbQMPvCgCVZO#&CDbY(7p?S)cF2;s3L^sAo zJkhcCJ8lN+xClc!t|1v0@j1qr99C^P(ngN7k)x)Oqgwey%bjSslcwBBEq8?7iayoO zPqosiRyu7eot8qi@-mOIa24HPdD8LlOj~%SEj(*lcvfq^)b+DVk;r+$lO>|vixB-x zn_yamHBDg0l(Utx+7v5bVkpII*F%OtkaL%EZG<h zN1e&zX7cDVLRuEnHc=wk)n2fp%RG^1 zd+oM#RQ>6GEmxJJIPI!Fc73s=Yqp};x#=dQz^`;xc@n9n1wJ+rzQn?lLeJc&2S}&W zN_C^V<#MCus)5HXJygJ5Z=(_mE`@(x19?kPA3?`b=DA3&u+Lo=9aiH}z_g1Nk8ltT z=Qr{!x-XBn9mDDv!6@(F zX^FlhDA^C}=(G4th-m-raa^Cqn}_kDb4|5|#lRoUaXVqzK3lCKY;iK`D28R1)>RF8 z6$2w2b8{IhCzJg=4}+261)k#@ZfDNsy^ihhVP|Lr{Z5a$eRtp({lIipGp5s~?j5@) zahfq4tV+9m-|TsFi*?Lk?sn{eTb*HGI33%wT#K`TG4RaNZbP?W7d;u3_l*0(bxWsV zO9$i#ZA37^@$G^QlJ9tu0?&QSs9L%#)bhJj&hf^aFBTM4iWLQm8Ld{cMr>CL!H=J) zJM!b(t}K3XQbBQ_#3#7!gHk2)39br?`y@WWbsv-}nNM(4P~0c+39kE~RLOh{u2y{? z0>iV{zQ%0_iQ9yz+2o&#OWKFra35U5Q-Ys@8wL%D+nctccxbanoB`N5Vw##N7CBg~ zicLnnqO+ecP|IaT`zi@-&6ka(86|wiK*K;>6Wy~AR1VpZd^dTA>+k|RVac&cW=#|1 zFJ8WadLQ&f3W9J=kLk(WsX?7i?dqIqsz5OOsgsg5$ zb?GfQ`i=f2cl%NQeelr#%RlH~<-evaU$NDE0zMFYJBW#bsZ`YQ4=|N?fstfq*|38H zu?EB?*W0&1@>(*79?Gv33OEe*lx0aMB_#`7N;lJxKj*2)6Ul~3c61ZhEy-gX!u<j?uUH#P zT9US&y=fiIVC86fcsJZsV3epT9y-O>1QqRvVEyHN8l1K+0C9aAcNZ+T3he^i^4`&a+o+Wz(5@cd)z Z?vUg9mt^aN&s*-GZ?zsiJUTsY{TCg_+baM7 literal 0 HcmV?d00001 diff --git a/test/test_manifest.json b/test/test_manifest.json index 75e67684c..2137c1ce7 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -7356,5 +7356,13 @@ "md5": "78a12254cac90ba5219a4c5555ea35ed", "rounds": 1, "type": "eq" + }, + { + "id": "bug1770750-annotations", + "file": "pdfs/bug1770750.pdf", + "md5": "01e6d77eac90b4b08d75240d3db2b826", + "rounds": 1, + "type": "eq", + "annotations": true } ]