pdfjs-dist 2.6.347 → 2.7.570

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pdfjs-dist might be problematic. Click here for more details.

Files changed (158) hide show
  1. package/README.md +3 -3
  2. package/bower.json +1 -1
  3. package/build/pdf.js +2050 -1087
  4. package/build/pdf.js.map +1 -1
  5. package/build/pdf.min.js +1 -1
  6. package/build/pdf.worker.js +18219 -10436
  7. package/build/pdf.worker.js.map +1 -1
  8. package/build/pdf.worker.min.js +1 -1
  9. package/es5/build/pdf.d.ts +1 -0
  10. package/es5/build/pdf.js +6623 -6654
  11. package/es5/build/pdf.js.map +1 -1
  12. package/es5/build/pdf.min.js +1 -1
  13. package/es5/build/pdf.worker.js +20815 -13888
  14. package/es5/build/pdf.worker.js.map +1 -1
  15. package/es5/build/pdf.worker.min.js +1 -1
  16. package/es5/image_decoders/pdf.image_decoders.js +3817 -4946
  17. package/es5/image_decoders/pdf.image_decoders.js.map +1 -1
  18. package/es5/image_decoders/pdf.image_decoders.min.js +1 -1
  19. package/es5/web/pdf_viewer.css +18 -15
  20. package/es5/web/pdf_viewer.js +1094 -514
  21. package/es5/web/pdf_viewer.js.map +1 -1
  22. package/image_decoders/pdf.image_decoders.js +774 -168
  23. package/image_decoders/pdf.image_decoders.js.map +1 -1
  24. package/image_decoders/pdf.image_decoders.min.js +1 -1
  25. package/lib/core/annotation.js +556 -108
  26. package/lib/core/cff_parser.js +7 -1
  27. package/lib/core/charsets.js +1 -1
  28. package/lib/core/cmap.js +20 -1
  29. package/lib/core/core_utils.js +162 -3
  30. package/lib/core/crypto.js +1 -1
  31. package/lib/core/default_appearance.js +132 -0
  32. package/lib/core/document.js +115 -9
  33. package/lib/core/encodings.js +1 -1
  34. package/lib/core/evaluator.js +168 -74
  35. package/lib/core/fonts.js +97 -11
  36. package/lib/core/function.js +5 -10
  37. package/lib/core/glyphlist.js +11 -4529
  38. package/lib/core/image_utils.js +30 -1
  39. package/lib/core/jpg.js +1 -1
  40. package/lib/core/jpx.js +5 -5
  41. package/lib/core/murmurhash3.js +1 -1
  42. package/lib/core/obj.js +123 -39
  43. package/lib/core/pattern.js +4 -4
  44. package/lib/core/primitives.js +24 -5
  45. package/lib/core/standard_fonts.js +1 -1
  46. package/lib/core/stream.js +5 -1
  47. package/lib/core/unicode.js +15 -1387
  48. package/lib/core/worker.js +58 -17
  49. package/lib/core/writer.js +68 -4
  50. package/lib/display/annotation_layer.js +712 -119
  51. package/lib/display/annotation_storage.js +21 -4
  52. package/lib/display/api.js +88 -18
  53. package/lib/display/canvas.js +414 -375
  54. package/lib/display/display_utils.js +11 -4
  55. package/lib/display/fetch_stream.js +3 -3
  56. package/lib/display/font_loader.js +2 -3
  57. package/lib/display/metadata.js +54 -20
  58. package/lib/display/node_stream.js +1 -1
  59. package/lib/display/optional_content_config.js +1 -1
  60. package/lib/display/pattern_helper.js +109 -113
  61. package/lib/display/svg.js +5 -5
  62. package/lib/display/text_layer.js +54 -54
  63. package/lib/display/transport_stream.js +4 -4
  64. package/lib/display/webgl.js +65 -68
  65. package/lib/examples/node/domstubs.js +9 -4
  66. package/lib/pdf.js +2 -2
  67. package/lib/pdf.sandbox.js +311 -0
  68. package/lib/pdf.worker.js +2 -2
  69. package/lib/shared/scripting_utils.js +84 -0
  70. package/lib/shared/util.js +129 -14
  71. package/lib/{display → shared}/xml_parser.js +112 -4
  72. package/lib/test/unit/annotation_spec.js +831 -109
  73. package/lib/test/unit/annotation_storage_spec.js +28 -10
  74. package/lib/test/unit/api_spec.js +190 -160
  75. package/lib/test/unit/bidi_spec.js +6 -6
  76. package/lib/test/unit/cff_parser_spec.js +73 -73
  77. package/lib/test/unit/clitests_helper.js +2 -0
  78. package/lib/test/unit/cmap_spec.js +48 -74
  79. package/lib/test/unit/core_utils_spec.js +34 -0
  80. package/lib/test/unit/crypto_spec.js +162 -199
  81. package/lib/test/unit/custom_spec.js +7 -18
  82. package/lib/test/unit/default_appearance_spec.js +54 -0
  83. package/lib/test/unit/display_svg_spec.js +24 -19
  84. package/lib/test/unit/display_utils_spec.js +1 -1
  85. package/lib/test/unit/document_spec.js +187 -20
  86. package/lib/test/unit/evaluator_spec.js +30 -30
  87. package/lib/test/unit/function_spec.js +165 -165
  88. package/lib/test/unit/jasmine-boot.js +52 -53
  89. package/lib/test/unit/metadata_spec.js +2 -2
  90. package/lib/test/unit/murmurhash3_spec.js +29 -16
  91. package/lib/test/unit/network_spec.js +21 -21
  92. package/lib/test/unit/pdf_find_controller_spec.js +131 -69
  93. package/lib/test/unit/pdf_find_utils_spec.js +10 -10
  94. package/lib/test/unit/scripting_spec.js +1104 -0
  95. package/lib/test/unit/stream_spec.js +8 -8
  96. package/lib/test/unit/test_utils.js +16 -19
  97. package/lib/test/unit/testreporter.js +11 -4
  98. package/lib/test/unit/type1_parser_spec.js +23 -23
  99. package/lib/test/unit/ui_utils_spec.js +78 -35
  100. package/lib/test/unit/unicode_spec.js +7 -7
  101. package/lib/test/unit/util_spec.js +26 -3
  102. package/lib/test/unit/writer_spec.js +16 -1
  103. package/lib/test/unit/xml_spec.js +117 -0
  104. package/lib/web/annotation_layer_builder.js +18 -6
  105. package/lib/web/app.js +579 -161
  106. package/lib/web/app_options.js +14 -0
  107. package/lib/web/base_tree_viewer.js +50 -0
  108. package/lib/web/base_viewer.js +350 -14
  109. package/lib/web/chromecom.js +9 -1
  110. package/lib/web/debugger.js +1 -2
  111. package/lib/web/download_manager.js +0 -15
  112. package/lib/web/firefox_print_service.js +6 -4
  113. package/lib/web/firefoxcom.js +84 -69
  114. package/lib/web/generic_scripting.js +55 -0
  115. package/lib/web/genericcom.js +9 -1
  116. package/lib/web/grab_to_pan.js +1 -1
  117. package/lib/web/interfaces.js +9 -3
  118. package/lib/web/pdf_attachment_viewer.js +1 -3
  119. package/lib/web/pdf_cursor_tools.js +20 -13
  120. package/lib/web/pdf_document_properties.js +48 -61
  121. package/lib/web/pdf_find_bar.js +1 -3
  122. package/lib/web/pdf_find_controller.js +58 -12
  123. package/lib/web/pdf_history.js +43 -21
  124. package/lib/web/pdf_layer_viewer.js +1 -9
  125. package/lib/web/pdf_link_service.js +108 -78
  126. package/lib/web/pdf_outline_viewer.js +166 -10
  127. package/lib/web/pdf_page_view.js +14 -14
  128. package/lib/web/pdf_presentation_mode.js +21 -31
  129. package/lib/web/pdf_rendering_queue.js +8 -1
  130. package/lib/web/pdf_sidebar.js +62 -107
  131. package/lib/web/pdf_sidebar_resizer.js +11 -21
  132. package/lib/web/pdf_single_page_viewer.js +8 -0
  133. package/lib/web/pdf_thumbnail_view.js +26 -26
  134. package/lib/web/pdf_thumbnail_viewer.js +13 -2
  135. package/lib/web/pdf_viewer.component.js +2 -2
  136. package/lib/web/pdf_viewer.js +3 -1
  137. package/lib/web/preferences.js +33 -44
  138. package/lib/web/text_layer_builder.js +2 -9
  139. package/lib/web/ui_utils.js +78 -46
  140. package/lib/web/viewer_compatibility.js +1 -2
  141. package/package.json +4 -1
  142. package/types/display/annotation_layer.d.ts +18 -3
  143. package/types/display/api.d.ts +110 -54
  144. package/types/display/canvas.d.ts +1 -1
  145. package/types/display/display_utils.d.ts +96 -95
  146. package/types/display/fetch_stream.d.ts +2 -2
  147. package/types/display/metadata.d.ts +4 -0
  148. package/types/display/pattern_helper.d.ts +1 -1
  149. package/types/display/text_layer.d.ts +7 -7
  150. package/types/display/transport_stream.d.ts +1 -1
  151. package/types/shared/scripting_utils.d.ts +12 -0
  152. package/types/shared/util.d.ts +281 -250
  153. package/types/shared/xml_parser.d.ts +64 -0
  154. package/web/pdf_viewer.css +18 -15
  155. package/web/pdf_viewer.js +809 -408
  156. package/web/pdf_viewer.js.map +1 -1
  157. package/webpack.js +1 -1
  158. package/types/display/xml_parser.d.ts +0 -35
@@ -31,12 +31,14 @@ var _util = require("../shared/util.js");
31
31
 
32
32
  var _obj = require("./obj.js");
33
33
 
34
+ var _core_utils = require("./core_utils.js");
35
+
36
+ var _default_appearance = require("./default_appearance.js");
37
+
34
38
  var _primitives = require("./primitives.js");
35
39
 
36
40
  var _colorspace = require("./colorspace.js");
37
41
 
38
- var _core_utils = require("./core_utils.js");
39
-
40
42
  var _operator_list = require("./operator_list.js");
41
43
 
42
44
  var _stream = require("./stream.js");
@@ -165,7 +167,7 @@ function getQuadPoints(dict, rect) {
165
167
 
166
168
  const quadPoints = dict.getArray("QuadPoints");
167
169
 
168
- if (!Array.isArray(quadPoints) || quadPoints.length % 8 > 0) {
170
+ if (!Array.isArray(quadPoints) || quadPoints.length === 0 || quadPoints.length % 8 > 0) {
169
171
  return null;
170
172
  }
171
173
 
@@ -178,7 +180,7 @@ function getQuadPoints(dict, rect) {
178
180
  const x = quadPoints[j];
179
181
  const y = quadPoints[j + 1];
180
182
 
181
- if (x < rect[0] || x > rect[2] || y < rect[1] || y > rect[3]) {
183
+ if (rect !== null && (x < rect[0] || x > rect[2] || y < rect[1] || y > rect[3])) {
182
184
  return null;
183
185
  }
184
186
 
@@ -189,7 +191,22 @@ function getQuadPoints(dict, rect) {
189
191
  }
190
192
  }
191
193
 
192
- return quadPointsLists;
194
+ return quadPointsLists.map(quadPointsList => {
195
+ const [minX, maxX, minY, maxY] = quadPointsList.reduce(([mX, MX, mY, MY], quadPoint) => [Math.min(mX, quadPoint.x), Math.max(MX, quadPoint.x), Math.min(mY, quadPoint.y), Math.max(MY, quadPoint.y)], [Number.MAX_VALUE, Number.MIN_VALUE, Number.MAX_VALUE, Number.MIN_VALUE]);
196
+ return [{
197
+ x: minX,
198
+ y: maxY
199
+ }, {
200
+ x: maxX,
201
+ y: maxY
202
+ }, {
203
+ x: minX,
204
+ y: minY
205
+ }, {
206
+ x: maxX,
207
+ y: minY
208
+ }];
209
+ });
193
210
  }
194
211
 
195
212
  function getTransformMatrix(rect, bbox, matrix) {
@@ -214,6 +231,12 @@ class Annotation {
214
231
  this.setColor(dict.getArray("C"));
215
232
  this.setBorderStyle(dict);
216
233
  this.setAppearance(dict);
234
+ this._streams = [];
235
+
236
+ if (this.appearance) {
237
+ this._streams.push(this.appearance);
238
+ }
239
+
217
240
  this.data = {
218
241
  annotationFlags: this.flags,
219
242
  borderStyle: this.borderStyle,
@@ -225,6 +248,7 @@ class Annotation {
225
248
  rect: this.rectangle,
226
249
  subtype: params.subtype
227
250
  };
251
+ this._fallbackFontDict = null;
228
252
  }
229
253
 
230
254
  _hasFlag(flags, flag) {
@@ -232,14 +256,28 @@ class Annotation {
232
256
  }
233
257
 
234
258
  _isViewable(flags) {
235
- return !this._hasFlag(flags, _util.AnnotationFlag.INVISIBLE) && !this._hasFlag(flags, _util.AnnotationFlag.HIDDEN) && !this._hasFlag(flags, _util.AnnotationFlag.NOVIEW);
259
+ return !this._hasFlag(flags, _util.AnnotationFlag.INVISIBLE) && !this._hasFlag(flags, _util.AnnotationFlag.NOVIEW);
236
260
  }
237
261
 
238
262
  _isPrintable(flags) {
239
- return this._hasFlag(flags, _util.AnnotationFlag.PRINT) && !this._hasFlag(flags, _util.AnnotationFlag.INVISIBLE) && !this._hasFlag(flags, _util.AnnotationFlag.HIDDEN);
263
+ return this._hasFlag(flags, _util.AnnotationFlag.PRINT) && !this._hasFlag(flags, _util.AnnotationFlag.INVISIBLE);
264
+ }
265
+
266
+ isHidden(annotationStorage) {
267
+ const data = annotationStorage && annotationStorage[this.data.id];
268
+
269
+ if (data && "hidden" in data) {
270
+ return data.hidden;
271
+ }
272
+
273
+ return this._hasFlag(this.flags, _util.AnnotationFlag.HIDDEN);
240
274
  }
241
275
 
242
276
  get viewable() {
277
+ if (this.data.quadPoints === null) {
278
+ return false;
279
+ }
280
+
243
281
  if (this.flags === 0) {
244
282
  return true;
245
283
  }
@@ -248,6 +286,10 @@ class Annotation {
248
286
  }
249
287
 
250
288
  get printable() {
289
+ if (this.data.quadPoints === null) {
290
+ return false;
291
+ }
292
+
251
293
  if (this.flags === 0) {
252
294
  return false;
253
295
  }
@@ -409,10 +451,11 @@ class Annotation {
409
451
  stream: appearance,
410
452
  task,
411
453
  resources,
412
- operatorList: opList
454
+ operatorList: opList,
455
+ fallbackFontDict: this._fallbackFontDict
413
456
  }).then(() => {
414
457
  opList.addOp(_util.OPS.endAnnotation, []);
415
- appearance.reset();
458
+ this.reset();
416
459
  return opList;
417
460
  });
418
461
  });
@@ -422,6 +465,16 @@ class Annotation {
422
465
  return null;
423
466
  }
424
467
 
468
+ getFieldObject() {
469
+ return null;
470
+ }
471
+
472
+ reset() {
473
+ for (const stream of this._streams) {
474
+ stream.reset();
475
+ }
476
+ }
477
+
425
478
  }
426
479
 
427
480
  exports.Annotation = Annotation;
@@ -585,6 +638,68 @@ class MarkupAnnotation extends Annotation {
585
638
  this.creationDate = (0, _util.isString)(creationDate) ? creationDate : null;
586
639
  }
587
640
 
641
+ _setDefaultAppearance({
642
+ xref,
643
+ extra,
644
+ strokeColor,
645
+ fillColor,
646
+ blendMode,
647
+ pointsCallback
648
+ }) {
649
+ let minX = Number.MAX_VALUE;
650
+ let minY = Number.MAX_VALUE;
651
+ let maxX = Number.MIN_VALUE;
652
+ let maxY = Number.MIN_VALUE;
653
+ const buffer = ["q"];
654
+
655
+ if (extra) {
656
+ buffer.push(extra);
657
+ }
658
+
659
+ if (strokeColor) {
660
+ buffer.push(`${strokeColor[0]} ${strokeColor[1]} ${strokeColor[2]} RG`);
661
+ }
662
+
663
+ if (fillColor) {
664
+ buffer.push(`${fillColor[0]} ${fillColor[1]} ${fillColor[2]} rg`);
665
+ }
666
+
667
+ for (const points of this.data.quadPoints) {
668
+ const [mX, MX, mY, MY] = pointsCallback(buffer, points);
669
+ minX = Math.min(minX, mX);
670
+ maxX = Math.max(maxX, MX);
671
+ minY = Math.min(minY, mY);
672
+ maxY = Math.max(maxY, MY);
673
+ }
674
+
675
+ buffer.push("Q");
676
+ const formDict = new _primitives.Dict(xref);
677
+ const appearanceStreamDict = new _primitives.Dict(xref);
678
+ appearanceStreamDict.set("Subtype", _primitives.Name.get("Form"));
679
+ const appearanceStream = new _stream.StringStream(buffer.join(" "));
680
+ appearanceStream.dict = appearanceStreamDict;
681
+ formDict.set("Fm0", appearanceStream);
682
+ const gsDict = new _primitives.Dict(xref);
683
+
684
+ if (blendMode) {
685
+ gsDict.set("BM", _primitives.Name.get(blendMode));
686
+ }
687
+
688
+ const stateDict = new _primitives.Dict(xref);
689
+ stateDict.set("GS0", gsDict);
690
+ const resources = new _primitives.Dict(xref);
691
+ resources.set("ExtGState", stateDict);
692
+ resources.set("XObject", formDict);
693
+ const appearanceDict = new _primitives.Dict(xref);
694
+ appearanceDict.set("Resources", resources);
695
+ const bbox = this.data.rect = [minX, minY, maxX, maxY];
696
+ appearanceDict.set("BBox", bbox);
697
+ this.appearance = new _stream.StringStream("/GS0 gs /Fm0 Do");
698
+ this.appearance.dict = appearanceDict;
699
+
700
+ this._streams.push(this.appearance, appearanceStream);
701
+ }
702
+
588
703
  }
589
704
 
590
705
  exports.MarkupAnnotation = MarkupAnnotation;
@@ -597,26 +712,47 @@ class WidgetAnnotation extends Annotation {
597
712
  this.ref = params.ref;
598
713
  data.annotationType = _util.AnnotationType.WIDGET;
599
714
  data.fieldName = this._constructFieldName(dict);
715
+ data.actions = (0, _core_utils.collectActions)(params.xref, dict, _util.AnnotationActionEventType);
600
716
  const fieldValue = (0, _core_utils.getInheritableProperty)({
601
717
  dict,
602
718
  key: "V",
603
719
  getArray: true
604
720
  });
605
721
  data.fieldValue = this._decodeFormValue(fieldValue);
722
+ const defaultFieldValue = (0, _core_utils.getInheritableProperty)({
723
+ dict,
724
+ key: "DV",
725
+ getArray: true
726
+ });
727
+ data.defaultFieldValue = this._decodeFormValue(defaultFieldValue);
606
728
  data.alternativeText = (0, _util.stringToPDFString)(dict.get("TU") || "");
607
- data.defaultAppearance = (0, _core_utils.getInheritableProperty)({
729
+ const defaultAppearance = (0, _core_utils.getInheritableProperty)({
608
730
  dict,
609
731
  key: "DA"
610
732
  }) || params.acroForm.get("DA") || "";
733
+ data.defaultAppearance = (0, _util.isString)(defaultAppearance) ? defaultAppearance : "";
734
+ data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(data.defaultAppearance);
611
735
  const fieldType = (0, _core_utils.getInheritableProperty)({
612
736
  dict,
613
737
  key: "FT"
614
738
  });
615
739
  data.fieldType = (0, _primitives.isName)(fieldType) ? fieldType.name : null;
616
- this.fieldResources = (0, _core_utils.getInheritableProperty)({
740
+ const localResources = (0, _core_utils.getInheritableProperty)({
617
741
  dict,
618
742
  key: "DR"
619
- }) || params.acroForm.get("DR") || _primitives.Dict.empty;
743
+ });
744
+ const acroFormResources = params.acroForm.get("DR");
745
+ const appearanceResources = this.appearance && this.appearance.dict.get("Resources");
746
+ this._fieldResources = {
747
+ localResources,
748
+ acroFormResources,
749
+ appearanceResources,
750
+ mergedResources: _primitives.Dict.merge({
751
+ xref: params.xref,
752
+ dictArray: [localResources, appearanceResources, acroFormResources],
753
+ mergeSubDicts: true
754
+ })
755
+ };
620
756
  data.fieldFlags = (0, _core_utils.getInheritableProperty)({
621
757
  dict,
622
758
  key: "Ff"
@@ -627,10 +763,12 @@ class WidgetAnnotation extends Annotation {
627
763
  }
628
764
 
629
765
  data.readOnly = this.hasFieldFlag(_util.AnnotationFieldFlag.READONLY);
766
+ data.hidden = this._hasFlag(data.annotationFlags, _util.AnnotationFlag.HIDDEN);
630
767
 
631
768
  if (data.fieldType === "Sig") {
632
769
  data.fieldValue = null;
633
770
  this.setFlags(_util.AnnotationFlag.HIDDEN);
771
+ data.hidden = true;
634
772
  }
635
773
  }
636
774
 
@@ -711,7 +849,7 @@ class WidgetAnnotation extends Annotation {
711
849
  return evaluator.getOperatorList({
712
850
  stream,
713
851
  task,
714
- resources: this.fieldResources,
852
+ resources: this._fieldResources.mergedResources,
715
853
  operatorList
716
854
  }).then(function () {
717
855
  operatorList.addOp(_util.OPS.endAnnotation, []);
@@ -721,7 +859,9 @@ class WidgetAnnotation extends Annotation {
721
859
  }
722
860
 
723
861
  async save(evaluator, task, annotationStorage) {
724
- if (this.data.fieldValue === annotationStorage[this.data.id]) {
862
+ const value = annotationStorage[this.data.id] && annotationStorage[this.data.id].value;
863
+
864
+ if (value === this.data.fieldValue || value === undefined) {
725
865
  return null;
726
866
  }
727
867
 
@@ -731,18 +871,24 @@ class WidgetAnnotation extends Annotation {
731
871
  return null;
732
872
  }
733
873
 
734
- const dict = evaluator.xref.fetchIfRef(this.ref);
874
+ const {
875
+ xref
876
+ } = evaluator;
877
+ const dict = xref.fetchIfRef(this.ref);
735
878
 
736
879
  if (!(0, _primitives.isDict)(dict)) {
737
880
  return null;
738
881
  }
739
882
 
740
883
  const bbox = [0, 0, this.data.rect[2] - this.data.rect[0], this.data.rect[3] - this.data.rect[1]];
741
- const newRef = evaluator.xref.getNewRef();
742
- const AP = new _primitives.Dict(evaluator.xref);
884
+ const xfa = {
885
+ path: (0, _util.stringToPDFString)(dict.get("T") || ""),
886
+ value
887
+ };
888
+ const newRef = xref.getNewRef();
889
+ const AP = new _primitives.Dict(xref);
743
890
  AP.set("N", newRef);
744
- const value = annotationStorage[this.data.id];
745
- const encrypt = evaluator.xref.encrypt;
891
+ const encrypt = xref.encrypt;
746
892
  let originalTransform = null;
747
893
  let newTransform = null;
748
894
 
@@ -752,13 +898,13 @@ class WidgetAnnotation extends Annotation {
752
898
  appearance = newTransform.encryptString(appearance);
753
899
  }
754
900
 
755
- dict.set("V", value);
901
+ dict.set("V", (0, _util.isAscii)(value) ? value : (0, _util.stringToUTF16BEString)(value));
756
902
  dict.set("AP", AP);
757
903
  dict.set("M", `D:${(0, _util.getModificationDate)()}`);
758
- const appearanceDict = new _primitives.Dict(evaluator.xref);
904
+ const appearanceDict = new _primitives.Dict(xref);
759
905
  appearanceDict.set("Length", appearance.length);
760
906
  appearanceDict.set("Subtype", _primitives.Name.get("Form"));
761
- appearanceDict.set("Resources", this.fieldResources);
907
+ appearanceDict.set("Resources", this._getSaveFieldResources(xref));
762
908
  appearanceDict.set("BBox", bbox);
763
909
  const bufferOriginal = [`${this.ref.num} ${this.ref.gen} obj\n`];
764
910
  (0, _writer.writeDict)(dict, bufferOriginal, originalTransform);
@@ -770,10 +916,12 @@ class WidgetAnnotation extends Annotation {
770
916
  bufferNew.push("\nendstream\nendobj\n");
771
917
  return [{
772
918
  ref: this.ref,
773
- data: bufferOriginal.join("")
919
+ data: bufferOriginal.join(""),
920
+ xfa
774
921
  }, {
775
922
  ref: newRef,
776
- data: bufferNew.join("")
923
+ data: bufferNew.join(""),
924
+ xfa: null
777
925
  }];
778
926
  }
779
927
 
@@ -784,7 +932,11 @@ class WidgetAnnotation extends Annotation {
784
932
  return null;
785
933
  }
786
934
 
787
- const value = annotationStorage[this.data.id];
935
+ const value = annotationStorage[this.data.id] && annotationStorage[this.data.id].value;
936
+
937
+ if (value === undefined) {
938
+ return null;
939
+ }
788
940
 
789
941
  if (value === "") {
790
942
  return "";
@@ -794,10 +946,16 @@ class WidgetAnnotation extends Annotation {
794
946
  const hPadding = defaultPadding;
795
947
  const totalHeight = this.data.rect[3] - this.data.rect[1];
796
948
  const totalWidth = this.data.rect[2] - this.data.rect[0];
797
- const fontInfo = await this._getFontData(evaluator, task);
798
- const [font, fontName] = fontInfo;
799
- let fontSize = fontInfo[2];
800
- fontSize = this._computeFontSize(font, fontName, fontSize, totalHeight);
949
+
950
+ if (!this.data.defaultAppearance) {
951
+ this.data.defaultAppearance = "/Helvetica 0 Tf 0 g";
952
+ this.data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(this.data.defaultAppearance);
953
+ }
954
+
955
+ const font = await this._getFontData(evaluator, task);
956
+
957
+ const fontSize = this._computeFontSize(font, totalHeight);
958
+
801
959
  let descent = font.descent;
802
960
 
803
961
  if (isNaN(descent)) {
@@ -808,19 +966,21 @@ class WidgetAnnotation extends Annotation {
808
966
  const defaultAppearance = this.data.defaultAppearance;
809
967
  const alignment = this.data.textAlignment;
810
968
 
811
- if (this.data.comb) {
812
- return this._getCombAppearance(defaultAppearance, value, totalWidth, hPadding, vPadding);
813
- }
814
-
815
969
  if (this.data.multiLine) {
816
970
  return this._getMultilineAppearance(defaultAppearance, value, font, fontSize, totalWidth, totalHeight, alignment, hPadding, vPadding);
817
971
  }
818
972
 
973
+ const encodedString = font.encodeString(value).join("");
974
+
975
+ if (this.data.comb) {
976
+ return this._getCombAppearance(defaultAppearance, font, encodedString, totalWidth, hPadding, vPadding);
977
+ }
978
+
819
979
  if (alignment === 0 || alignment > 2) {
820
- return "/Tx BMC q BT " + defaultAppearance + ` 1 0 0 1 ${hPadding} ${vPadding} Tm (${(0, _util.escapeString)(value)}) Tj` + " ET Q EMC";
980
+ return "/Tx BMC q BT " + defaultAppearance + ` 1 0 0 1 ${hPadding} ${vPadding} Tm (${(0, _util.escapeString)(encodedString)}) Tj` + " ET Q EMC";
821
981
  }
822
982
 
823
- const renderedText = this._renderText(value, font, fontSize, totalWidth, alignment, hPadding, vPadding);
983
+ const renderedText = this._renderText(encodedString, font, fontSize, totalWidth, alignment, hPadding, vPadding);
824
984
 
825
985
  return "/Tx BMC q BT " + defaultAppearance + ` 1 0 0 1 0 0 Tm ${renderedText}` + " ET Q EMC";
826
986
  }
@@ -828,37 +988,50 @@ class WidgetAnnotation extends Annotation {
828
988
  async _getFontData(evaluator, task) {
829
989
  const operatorList = new _operator_list.OperatorList();
830
990
  const initialState = {
831
- fontSize: 0,
832
991
  font: null,
833
- fontName: null,
834
992
 
835
993
  clone() {
836
994
  return this;
837
995
  }
838
996
 
839
997
  };
840
- await evaluator.getOperatorList({
841
- stream: new _stream.StringStream(this.data.defaultAppearance),
842
- task,
843
- resources: this.fieldResources,
844
- operatorList,
845
- initialState
846
- });
847
- return [initialState.font, initialState.fontName, initialState.fontSize];
848
- }
849
-
850
- _computeFontSize(font, fontName, fontSize, height) {
851
- if (fontSize === null || fontSize === 0) {
852
- const em = font.charsToGlyphs("M", true)[0].width / 1000;
853
- const capHeight = 0.7 * em;
854
- fontSize = Math.max(1, Math.floor(height / (1.5 * capHeight)));
855
- let fontRegex = new RegExp(`/${fontName}\\s+[0-9\.]+\\s+Tf`);
998
+ const {
999
+ fontName,
1000
+ fontSize
1001
+ } = this.data.defaultAppearanceData;
1002
+ await evaluator.handleSetFont(this._fieldResources.mergedResources, [fontName, fontSize], null, operatorList, task, initialState, null);
1003
+ return initialState.font;
1004
+ }
1005
+
1006
+ _computeFontSize(font, height) {
1007
+ let fontSize = this.data.defaultAppearanceData.fontSize;
1008
+
1009
+ if (!fontSize) {
1010
+ const {
1011
+ fontColor,
1012
+ fontName
1013
+ } = this.data.defaultAppearanceData;
1014
+ let capHeight;
1015
+
1016
+ if (font.capHeight) {
1017
+ capHeight = font.capHeight;
1018
+ } else {
1019
+ const glyphs = font.charsToGlyphs(font.encodeString("M").join(""));
856
1020
 
857
- if (this.data.defaultAppearance.search(fontRegex) === -1) {
858
- fontRegex = new RegExp(`/${fontName}\\s+Tf`);
1021
+ if (glyphs.length === 1 && glyphs[0].width) {
1022
+ const em = glyphs[0].width / 1000;
1023
+ capHeight = 0.7 * em;
1024
+ } else {
1025
+ capHeight = 0.7;
1026
+ }
859
1027
  }
860
1028
 
861
- this.data.defaultAppearance = this.data.defaultAppearance.replace(fontRegex, `/${fontName} ${fontSize} Tf`);
1029
+ fontSize = Math.max(1, Math.floor(height / (1.5 * capHeight)));
1030
+ this.data.defaultAppearance = (0, _default_appearance.createDefaultAppearance)({
1031
+ fontSize,
1032
+ fontName,
1033
+ fontColor
1034
+ });
862
1035
  }
863
1036
 
864
1037
  return fontSize;
@@ -888,6 +1061,59 @@ class WidgetAnnotation extends Annotation {
888
1061
  return `${shift} ${vPadding} Td (${(0, _util.escapeString)(text)}) Tj`;
889
1062
  }
890
1063
 
1064
+ _getSaveFieldResources(xref) {
1065
+ const {
1066
+ localResources,
1067
+ appearanceResources,
1068
+ acroFormResources
1069
+ } = this._fieldResources;
1070
+ const fontNameStr = this.data.defaultAppearanceData && this.data.defaultAppearanceData.fontName.name;
1071
+
1072
+ if (!fontNameStr) {
1073
+ return localResources || _primitives.Dict.empty;
1074
+ }
1075
+
1076
+ for (const resources of [localResources, appearanceResources]) {
1077
+ if (resources instanceof _primitives.Dict) {
1078
+ const localFont = resources.get("Font");
1079
+
1080
+ if (localFont instanceof _primitives.Dict && localFont.has(fontNameStr)) {
1081
+ return resources;
1082
+ }
1083
+ }
1084
+ }
1085
+
1086
+ if (acroFormResources instanceof _primitives.Dict) {
1087
+ const acroFormFont = acroFormResources.get("Font");
1088
+
1089
+ if (acroFormFont instanceof _primitives.Dict && acroFormFont.has(fontNameStr)) {
1090
+ const subFontDict = new _primitives.Dict(xref);
1091
+ subFontDict.set(fontNameStr, acroFormFont.getRaw(fontNameStr));
1092
+ const subResourcesDict = new _primitives.Dict(xref);
1093
+ subResourcesDict.set("Font", subFontDict);
1094
+ return _primitives.Dict.merge({
1095
+ xref,
1096
+ dictArray: [subResourcesDict, localResources],
1097
+ mergeSubDicts: true
1098
+ });
1099
+ }
1100
+ }
1101
+
1102
+ return localResources || _primitives.Dict.empty;
1103
+ }
1104
+
1105
+ getFieldObject() {
1106
+ if (this.data.fieldType === "Sig") {
1107
+ return {
1108
+ id: this.data.id,
1109
+ value: null,
1110
+ type: "signature"
1111
+ };
1112
+ }
1113
+
1114
+ return null;
1115
+ }
1116
+
891
1117
  }
892
1118
 
893
1119
  class TextWidgetAnnotation extends WidgetAnnotation {
@@ -924,12 +1150,13 @@ class TextWidgetAnnotation extends WidgetAnnotation {
924
1150
  this.data.comb = this.hasFieldFlag(_util.AnnotationFieldFlag.COMB) && !this.hasFieldFlag(_util.AnnotationFieldFlag.MULTILINE) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PASSWORD) && !this.hasFieldFlag(_util.AnnotationFieldFlag.FILESELECT) && this.data.maxLen !== null;
925
1151
  }
926
1152
 
927
- _getCombAppearance(defaultAppearance, text, width, hPadding, vPadding) {
1153
+ _getCombAppearance(defaultAppearance, font, text, width, hPadding, vPadding) {
928
1154
  const combWidth = (width / this.data.maxLen).toFixed(2);
929
1155
  const buf = [];
1156
+ const positions = font.getCharPositions(text);
930
1157
 
931
- for (const character of text) {
932
- buf.push(`(${(0, _util.escapeString)(character)}) Tj`);
1158
+ for (const [start, end] of positions) {
1159
+ buf.push(`(${(0, _util.escapeString)(text.substring(start, end))}) Tj`);
933
1160
  }
934
1161
 
935
1162
  const renderedComb = buf.join(` ${combWidth} 0 Td `);
@@ -955,46 +1182,55 @@ class TextWidgetAnnotation extends WidgetAnnotation {
955
1182
  }
956
1183
 
957
1184
  _splitLine(line, font, fontSize, width) {
958
- if (line.length <= 1) {
1185
+ line = font.encodeString(line).join("");
1186
+ const glyphs = font.charsToGlyphs(line);
1187
+
1188
+ if (glyphs.length <= 1) {
959
1189
  return [line];
960
1190
  }
961
1191
 
1192
+ const positions = font.getCharPositions(line);
962
1193
  const scale = fontSize / 1000;
963
- const whitespace = font.charsToGlyphs(" ", true)[0].width * scale;
964
1194
  const chunks = [];
965
- let lastSpacePos = -1,
1195
+ let lastSpacePosInStringStart = -1,
1196
+ lastSpacePosInStringEnd = -1,
1197
+ lastSpacePos = -1,
966
1198
  startChunk = 0,
967
1199
  currentWidth = 0;
968
1200
 
969
- for (let i = 0, ii = line.length; i < ii; i++) {
970
- const character = line.charAt(i);
971
-
972
- if (character === " ") {
973
- if (currentWidth + whitespace > width) {
974
- chunks.push(line.substring(startChunk, i));
975
- startChunk = i;
976
- currentWidth = whitespace;
1201
+ for (let i = 0, ii = glyphs.length; i < ii; i++) {
1202
+ const [start, end] = positions[i];
1203
+ const glyph = glyphs[i];
1204
+ const glyphWidth = glyph.width * scale;
1205
+
1206
+ if (glyph.unicode === " ") {
1207
+ if (currentWidth + glyphWidth > width) {
1208
+ chunks.push(line.substring(startChunk, start));
1209
+ startChunk = start;
1210
+ currentWidth = glyphWidth;
1211
+ lastSpacePosInStringStart = -1;
977
1212
  lastSpacePos = -1;
978
1213
  } else {
979
- currentWidth += whitespace;
1214
+ currentWidth += glyphWidth;
1215
+ lastSpacePosInStringStart = start;
1216
+ lastSpacePosInStringEnd = end;
980
1217
  lastSpacePos = i;
981
1218
  }
982
1219
  } else {
983
- const charWidth = font.charsToGlyphs(character, false)[0].width * scale;
984
-
985
- if (currentWidth + charWidth > width) {
986
- if (lastSpacePos !== -1) {
987
- chunks.push(line.substring(startChunk, lastSpacePos + 1));
988
- startChunk = i = lastSpacePos + 1;
989
- lastSpacePos = -1;
1220
+ if (currentWidth + glyphWidth > width) {
1221
+ if (lastSpacePosInStringStart !== -1) {
1222
+ chunks.push(line.substring(startChunk, lastSpacePosInStringEnd));
1223
+ startChunk = lastSpacePosInStringEnd;
1224
+ i = lastSpacePos + 1;
1225
+ lastSpacePosInStringStart = -1;
990
1226
  currentWidth = 0;
991
1227
  } else {
992
- chunks.push(line.substring(startChunk, i));
993
- startChunk = i;
994
- currentWidth = charWidth;
1228
+ chunks.push(line.substring(startChunk, start));
1229
+ startChunk = start;
1230
+ currentWidth = glyphWidth;
995
1231
  }
996
1232
  } else {
997
- currentWidth += charWidth;
1233
+ currentWidth += glyphWidth;
998
1234
  }
999
1235
  }
1000
1236
  }
@@ -1006,6 +1242,24 @@ class TextWidgetAnnotation extends WidgetAnnotation {
1006
1242
  return chunks;
1007
1243
  }
1008
1244
 
1245
+ getFieldObject() {
1246
+ return {
1247
+ id: this.data.id,
1248
+ value: this.data.fieldValue,
1249
+ defaultValue: this.data.defaultFieldValue,
1250
+ multiline: this.data.multiLine,
1251
+ password: this.hasFieldFlag(_util.AnnotationFieldFlag.PASSWORD),
1252
+ charLimit: this.data.maxLen,
1253
+ comb: this.data.comb,
1254
+ editable: !this.data.readOnly,
1255
+ hidden: this.data.hidden,
1256
+ name: this.data.fieldName,
1257
+ rect: this.data.rect,
1258
+ actions: this.data.actions,
1259
+ type: "text"
1260
+ };
1261
+ }
1262
+
1009
1263
  }
1010
1264
 
1011
1265
  class ButtonWidgetAnnotation extends WidgetAnnotation {
@@ -1016,6 +1270,7 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
1016
1270
  this.data.checkBox = !this.hasFieldFlag(_util.AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PUSHBUTTON);
1017
1271
  this.data.radioButton = this.hasFieldFlag(_util.AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PUSHBUTTON);
1018
1272
  this.data.pushButton = this.hasFieldFlag(_util.AnnotationFieldFlag.PUSHBUTTON);
1273
+ this.data.isTooltipOnly = false;
1019
1274
 
1020
1275
  if (this.data.checkBox) {
1021
1276
  this._processCheckBox(params);
@@ -1034,7 +1289,12 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
1034
1289
  }
1035
1290
 
1036
1291
  if (annotationStorage) {
1037
- const value = annotationStorage[this.data.id] || false;
1292
+ const value = annotationStorage[this.data.id] && annotationStorage[this.data.id].value;
1293
+
1294
+ if (value === undefined) {
1295
+ return super.getOperatorList(evaluator, task, renderForms, annotationStorage);
1296
+ }
1297
+
1038
1298
  let appearance;
1039
1299
 
1040
1300
  if (value) {
@@ -1066,12 +1326,17 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
1066
1326
  return this._saveRadioButton(evaluator, task, annotationStorage);
1067
1327
  }
1068
1328
 
1069
- return super.save(evaluator, task, annotationStorage);
1329
+ return null;
1070
1330
  }
1071
1331
 
1072
1332
  async _saveCheckbox(evaluator, task, annotationStorage) {
1333
+ const value = annotationStorage[this.data.id] && annotationStorage[this.data.id].value;
1334
+
1335
+ if (value === undefined) {
1336
+ return null;
1337
+ }
1338
+
1073
1339
  const defaultValue = this.data.fieldValue && this.data.fieldValue !== "Off";
1074
- const value = annotationStorage[this.data.id];
1075
1340
 
1076
1341
  if (defaultValue === value) {
1077
1342
  return null;
@@ -1083,6 +1348,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
1083
1348
  return null;
1084
1349
  }
1085
1350
 
1351
+ const xfa = {
1352
+ path: (0, _util.stringToPDFString)(dict.get("T") || ""),
1353
+ value: value ? this.data.exportValue : ""
1354
+ };
1355
+
1086
1356
  const name = _primitives.Name.get(value ? this.data.exportValue : "Off");
1087
1357
 
1088
1358
  dict.set("V", name);
@@ -1100,13 +1370,19 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
1100
1370
  buffer.push("\nendobj\n");
1101
1371
  return [{
1102
1372
  ref: this.ref,
1103
- data: buffer.join("")
1373
+ data: buffer.join(""),
1374
+ xfa
1104
1375
  }];
1105
1376
  }
1106
1377
 
1107
1378
  async _saveRadioButton(evaluator, task, annotationStorage) {
1379
+ const value = annotationStorage[this.data.id] && annotationStorage[this.data.id].value;
1380
+
1381
+ if (value === undefined) {
1382
+ return null;
1383
+ }
1384
+
1108
1385
  const defaultValue = this.data.fieldValue === this.data.buttonValue;
1109
- const value = annotationStorage[this.data.id];
1110
1386
 
1111
1387
  if (defaultValue === value) {
1112
1388
  return null;
@@ -1118,6 +1394,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
1118
1394
  return null;
1119
1395
  }
1120
1396
 
1397
+ const xfa = {
1398
+ path: (0, _util.stringToPDFString)(dict.get("T") || ""),
1399
+ value: value ? this.data.buttonValue : ""
1400
+ };
1401
+
1121
1402
  const name = _primitives.Name.get(value ? this.data.buttonValue : "Off");
1122
1403
 
1123
1404
  let parentBuffer = null;
@@ -1154,13 +1435,15 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
1154
1435
  buffer.push("\nendobj\n");
1155
1436
  const newRefs = [{
1156
1437
  ref: this.ref,
1157
- data: buffer.join("")
1438
+ data: buffer.join(""),
1439
+ xfa
1158
1440
  }];
1159
1441
 
1160
1442
  if (parentBuffer !== null) {
1161
1443
  newRefs.push({
1162
1444
  ref: this.parent,
1163
- data: parentBuffer.join("")
1445
+ data: parentBuffer.join(""),
1446
+ xfa: null
1164
1447
  });
1165
1448
  }
1166
1449
 
@@ -1193,17 +1476,25 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
1193
1476
  this.data.exportValue = exportValues[0] === "Off" ? exportValues[1] : exportValues[0];
1194
1477
  this.checkedAppearance = normalAppearance.get(this.data.exportValue);
1195
1478
  this.uncheckedAppearance = normalAppearance.get("Off") || null;
1479
+
1480
+ this._streams.push(this.checkedAppearance);
1481
+
1482
+ if (this.uncheckedAppearance) {
1483
+ this._streams.push(this.uncheckedAppearance);
1484
+ }
1485
+
1486
+ this._fallbackFontDict = this.fallbackFontDict;
1196
1487
  }
1197
1488
 
1198
1489
  _processRadioButton(params) {
1199
1490
  this.data.fieldValue = this.data.buttonValue = null;
1200
1491
  const fieldParent = params.dict.get("Parent");
1201
1492
 
1202
- if ((0, _primitives.isDict)(fieldParent) && fieldParent.has("V")) {
1493
+ if ((0, _primitives.isDict)(fieldParent)) {
1494
+ this.parent = params.dict.getRaw("Parent");
1203
1495
  const fieldParentValue = fieldParent.get("V");
1204
1496
 
1205
1497
  if ((0, _primitives.isName)(fieldParentValue)) {
1206
- this.parent = params.dict.getRaw("Parent");
1207
1498
  this.data.fieldValue = this._decodeFormValue(fieldParentValue);
1208
1499
  }
1209
1500
  }
@@ -1222,21 +1513,31 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
1222
1513
 
1223
1514
  for (const key of normalAppearance.getKeys()) {
1224
1515
  if (key !== "Off") {
1225
- this.data.buttonValue = key;
1516
+ this.data.buttonValue = this._decodeFormValue(key);
1226
1517
  break;
1227
1518
  }
1228
1519
  }
1229
1520
 
1230
1521
  this.checkedAppearance = normalAppearance.get(this.data.buttonValue);
1231
1522
  this.uncheckedAppearance = normalAppearance.get("Off") || null;
1523
+
1524
+ this._streams.push(this.checkedAppearance);
1525
+
1526
+ if (this.uncheckedAppearance) {
1527
+ this._streams.push(this.uncheckedAppearance);
1528
+ }
1529
+
1530
+ this._fallbackFontDict = this.fallbackFontDict;
1232
1531
  }
1233
1532
 
1234
1533
  _processPushButton(params) {
1235
- if (!params.dict.has("A")) {
1534
+ if (!params.dict.has("A") && !params.dict.has("AA") && !this.data.alternativeText) {
1236
1535
  (0, _util.warn)("Push buttons without action dictionaries are not supported");
1237
1536
  return;
1238
1537
  }
1239
1538
 
1539
+ this.data.isTooltipOnly = !params.dict.has("A") && !params.dict.has("AA");
1540
+
1240
1541
  _obj.Catalog.parseDestDictionary({
1241
1542
  destDict: params.dict,
1242
1543
  resultObj: this.data,
@@ -1244,6 +1545,41 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
1244
1545
  });
1245
1546
  }
1246
1547
 
1548
+ getFieldObject() {
1549
+ let type = "button";
1550
+ let exportValues;
1551
+
1552
+ if (this.data.checkBox) {
1553
+ type = "checkbox";
1554
+ exportValues = this.data.exportValue;
1555
+ } else if (this.data.radioButton) {
1556
+ type = "radiobutton";
1557
+ exportValues = this.data.buttonValue;
1558
+ }
1559
+
1560
+ return {
1561
+ id: this.data.id,
1562
+ value: this.data.fieldValue || "Off",
1563
+ defaultValue: this.data.defaultFieldValue,
1564
+ exportValues,
1565
+ editable: !this.data.readOnly,
1566
+ name: this.data.fieldName,
1567
+ rect: this.data.rect,
1568
+ hidden: this.data.hidden,
1569
+ actions: this.data.actions,
1570
+ type
1571
+ };
1572
+ }
1573
+
1574
+ get fallbackFontDict() {
1575
+ const dict = new _primitives.Dict();
1576
+ dict.set("BaseFont", _primitives.Name.get("ZapfDingbats"));
1577
+ dict.set("Type", _primitives.Name.get("FallbackType"));
1578
+ dict.set("Subtype", _primitives.Name.get("FallbackType"));
1579
+ dict.set("Encoding", _primitives.Name.get("ZapfDingbatsEncoding"));
1580
+ return (0, _util.shadow)(this, "fallbackFontDict", dict);
1581
+ }
1582
+
1247
1583
  }
1248
1584
 
1249
1585
  class ChoiceWidgetAnnotation extends WidgetAnnotation {
@@ -1279,6 +1615,24 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation {
1279
1615
  this._hasText = true;
1280
1616
  }
1281
1617
 
1618
+ getFieldObject() {
1619
+ const type = this.data.combo ? "combobox" : "listbox";
1620
+ const value = this.data.fieldValue.length > 0 ? this.data.fieldValue[0] : null;
1621
+ return {
1622
+ id: this.data.id,
1623
+ value,
1624
+ defaultValue: this.data.defaultFieldValue,
1625
+ editable: !this.data.readOnly,
1626
+ name: this.data.fieldName,
1627
+ rect: this.data.rect,
1628
+ numItems: this.data.fieldValue.length,
1629
+ multipleSelection: this.data.multiSelect,
1630
+ hidden: this.data.hidden,
1631
+ actions: this.data.actions,
1632
+ type
1633
+ };
1634
+ }
1635
+
1282
1636
  }
1283
1637
 
1284
1638
  class TextAnnotation extends MarkupAnnotation {
@@ -1341,6 +1695,14 @@ class PopupAnnotation extends Annotation {
1341
1695
  this.data.parentType = (0, _primitives.isName)(parentSubtype) ? parentSubtype.name : null;
1342
1696
  const rawParent = parameters.dict.getRaw("Parent");
1343
1697
  this.data.parentId = (0, _primitives.isRef)(rawParent) ? rawParent.toString() : null;
1698
+ const parentRect = parentItem.getArray("Rect");
1699
+
1700
+ if (Array.isArray(parentRect) && parentRect.length === 4) {
1701
+ this.data.parentRect = _util.Util.normalizeRect(parentRect);
1702
+ } else {
1703
+ this.data.parentRect = [0, 0, 0, 0];
1704
+ }
1705
+
1344
1706
  const rt = parentItem.get("RT");
1345
1707
 
1346
1708
  if ((0, _primitives.isName)(rt, _util.AnnotationReplyType.GROUP)) {
@@ -1412,8 +1774,12 @@ class PolylineAnnotation extends MarkupAnnotation {
1412
1774
  constructor(parameters) {
1413
1775
  super(parameters);
1414
1776
  this.data.annotationType = _util.AnnotationType.POLYLINE;
1415
- const rawVertices = parameters.dict.getArray("Vertices");
1416
1777
  this.data.vertices = [];
1778
+ const rawVertices = parameters.dict.getArray("Vertices");
1779
+
1780
+ if (!Array.isArray(rawVertices)) {
1781
+ return;
1782
+ }
1417
1783
 
1418
1784
  for (let i = 0, ii = rawVertices.length; i < ii; i += 2) {
1419
1785
  this.data.vertices.push({
@@ -1445,17 +1811,22 @@ class InkAnnotation extends MarkupAnnotation {
1445
1811
  constructor(parameters) {
1446
1812
  super(parameters);
1447
1813
  this.data.annotationType = _util.AnnotationType.INK;
1448
- const xref = parameters.xref;
1449
- const originalInkLists = parameters.dict.getArray("InkList");
1450
1814
  this.data.inkLists = [];
1815
+ const rawInkLists = parameters.dict.getArray("InkList");
1816
+
1817
+ if (!Array.isArray(rawInkLists)) {
1818
+ return;
1819
+ }
1451
1820
 
1452
- for (let i = 0, ii = originalInkLists.length; i < ii; ++i) {
1821
+ const xref = parameters.xref;
1822
+
1823
+ for (let i = 0, ii = rawInkLists.length; i < ii; ++i) {
1453
1824
  this.data.inkLists.push([]);
1454
1825
 
1455
- for (let j = 0, jj = originalInkLists[i].length; j < jj; j += 2) {
1826
+ for (let j = 0, jj = rawInkLists[i].length; j < jj; j += 2) {
1456
1827
  this.data.inkLists[i].push({
1457
- x: xref.fetchIfRef(originalInkLists[i][j]),
1458
- y: xref.fetchIfRef(originalInkLists[i][j + 1])
1828
+ x: xref.fetchIfRef(rawInkLists[i][j]),
1829
+ y: xref.fetchIfRef(rawInkLists[i][j + 1])
1459
1830
  });
1460
1831
  }
1461
1832
  }
@@ -1467,10 +1838,28 @@ class HighlightAnnotation extends MarkupAnnotation {
1467
1838
  constructor(parameters) {
1468
1839
  super(parameters);
1469
1840
  this.data.annotationType = _util.AnnotationType.HIGHLIGHT;
1470
- const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
1841
+ const quadPoints = this.data.quadPoints = getQuadPoints(parameters.dict, null);
1471
1842
 
1472
1843
  if (quadPoints) {
1473
- this.data.quadPoints = quadPoints;
1844
+ if (!this.appearance) {
1845
+ const fillColor = this.color ? Array.from(this.color).map(c => c / 255) : [1, 1, 0];
1846
+
1847
+ this._setDefaultAppearance({
1848
+ xref: parameters.xref,
1849
+ fillColor,
1850
+ blendMode: "Multiply",
1851
+ pointsCallback: (buffer, points) => {
1852
+ buffer.push(`${points[0].x} ${points[0].y} m`);
1853
+ buffer.push(`${points[1].x} ${points[1].y} l`);
1854
+ buffer.push(`${points[3].x} ${points[3].y} l`);
1855
+ buffer.push(`${points[2].x} ${points[2].y} l`);
1856
+ buffer.push("f");
1857
+ return [points[0].x, points[1].x, points[3].y, points[1].y];
1858
+ }
1859
+ });
1860
+ }
1861
+ } else {
1862
+ this.data.hasPopup = false;
1474
1863
  }
1475
1864
  }
1476
1865
 
@@ -1480,10 +1869,26 @@ class UnderlineAnnotation extends MarkupAnnotation {
1480
1869
  constructor(parameters) {
1481
1870
  super(parameters);
1482
1871
  this.data.annotationType = _util.AnnotationType.UNDERLINE;
1483
- const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
1872
+ const quadPoints = this.data.quadPoints = getQuadPoints(parameters.dict, null);
1484
1873
 
1485
1874
  if (quadPoints) {
1486
- this.data.quadPoints = quadPoints;
1875
+ if (!this.appearance) {
1876
+ const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0];
1877
+
1878
+ this._setDefaultAppearance({
1879
+ xref: parameters.xref,
1880
+ extra: "[] 0 d 1 w",
1881
+ strokeColor,
1882
+ pointsCallback: (buffer, points) => {
1883
+ buffer.push(`${points[2].x} ${points[2].y} m`);
1884
+ buffer.push(`${points[3].x} ${points[3].y} l`);
1885
+ buffer.push("S");
1886
+ return [points[0].x, points[1].x, points[3].y, points[1].y];
1887
+ }
1888
+ });
1889
+ }
1890
+ } else {
1891
+ this.data.hasPopup = false;
1487
1892
  }
1488
1893
  }
1489
1894
 
@@ -1493,10 +1898,37 @@ class SquigglyAnnotation extends MarkupAnnotation {
1493
1898
  constructor(parameters) {
1494
1899
  super(parameters);
1495
1900
  this.data.annotationType = _util.AnnotationType.SQUIGGLY;
1496
- const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
1901
+ const quadPoints = this.data.quadPoints = getQuadPoints(parameters.dict, null);
1497
1902
 
1498
1903
  if (quadPoints) {
1499
- this.data.quadPoints = quadPoints;
1904
+ if (!this.appearance) {
1905
+ const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0];
1906
+
1907
+ this._setDefaultAppearance({
1908
+ xref: parameters.xref,
1909
+ extra: "[] 0 d 1 w",
1910
+ strokeColor,
1911
+ pointsCallback: (buffer, points) => {
1912
+ const dy = (points[0].y - points[2].y) / 6;
1913
+ let shift = dy;
1914
+ let x = points[2].x;
1915
+ const y = points[2].y;
1916
+ const xEnd = points[3].x;
1917
+ buffer.push(`${x} ${y + shift} m`);
1918
+
1919
+ do {
1920
+ x += 2;
1921
+ shift = shift === 0 ? dy : 0;
1922
+ buffer.push(`${x} ${y + shift} l`);
1923
+ } while (x < xEnd);
1924
+
1925
+ buffer.push("S");
1926
+ return [points[2].x, xEnd, y - 2 * dy, y + 2 * dy];
1927
+ }
1928
+ });
1929
+ }
1930
+ } else {
1931
+ this.data.hasPopup = false;
1500
1932
  }
1501
1933
  }
1502
1934
 
@@ -1506,10 +1938,26 @@ class StrikeOutAnnotation extends MarkupAnnotation {
1506
1938
  constructor(parameters) {
1507
1939
  super(parameters);
1508
1940
  this.data.annotationType = _util.AnnotationType.STRIKEOUT;
1509
- const quadPoints = getQuadPoints(parameters.dict, this.rectangle);
1941
+ const quadPoints = this.data.quadPoints = getQuadPoints(parameters.dict, null);
1510
1942
 
1511
1943
  if (quadPoints) {
1512
- this.data.quadPoints = quadPoints;
1944
+ if (!this.appearance) {
1945
+ const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0];
1946
+
1947
+ this._setDefaultAppearance({
1948
+ xref: parameters.xref,
1949
+ extra: "[] 0 d 1 w",
1950
+ strokeColor,
1951
+ pointsCallback: (buffer, points) => {
1952
+ buffer.push(`${(points[0].x + points[2].x) / 2}` + ` ${(points[0].y + points[2].y) / 2} m`);
1953
+ buffer.push(`${(points[1].x + points[3].x) / 2}` + ` ${(points[1].y + points[3].y) / 2} l`);
1954
+ buffer.push("S");
1955
+ return [points[0].x, points[1].x, points[3].y, points[1].y];
1956
+ }
1957
+ });
1958
+ }
1959
+ } else {
1960
+ this.data.hasPopup = false;
1513
1961
  }
1514
1962
  }
1515
1963