pdfjs-dist 2.5.207 → 2.6.347
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.
- package/bower.json +1 -1
- package/build/pdf.js +867 -216
- package/build/pdf.js.map +1 -1
- package/build/pdf.min.js +1 -1
- package/build/pdf.worker.js +10214 -8547
- package/build/pdf.worker.js.map +1 -1
- package/build/pdf.worker.min.js +1 -1
- package/es5/build/pdf.js +2023 -1046
- package/es5/build/pdf.js.map +1 -1
- package/es5/build/pdf.min.js +22 -0
- package/es5/build/pdf.worker.js +11136 -8144
- package/es5/build/pdf.worker.js.map +1 -1
- package/es5/build/pdf.worker.min.js +22 -0
- package/es5/image_decoders/pdf.image_decoders.js +12529 -0
- package/es5/image_decoders/pdf.image_decoders.js.map +1 -0
- package/es5/image_decoders/pdf.image_decoders.min.js +22 -0
- package/es5/web/images/shadow.png +0 -0
- package/es5/web/pdf_viewer.css +8 -5
- package/es5/web/pdf_viewer.js +195 -51
- package/es5/web/pdf_viewer.js.map +1 -1
- package/image_decoders/pdf.image_decoders.js +24 -16
- package/image_decoders/pdf.image_decoders.js.map +1 -1
- package/image_decoders/pdf.image_decoders.min.js +1 -1
- package/lib/core/annotation.js +479 -43
- package/lib/core/cff_parser.js +643 -615
- package/lib/core/chunked_stream.js +64 -50
- package/lib/core/colorspace.js +126 -104
- package/lib/core/crypto.js +37 -0
- package/lib/core/document.js +128 -75
- package/lib/core/evaluator.js +3015 -2754
- package/lib/core/fonts.js +47 -46
- package/lib/core/function.js +79 -6
- package/lib/core/image.js +364 -357
- package/lib/core/image_utils.js +109 -8
- package/lib/core/jpg.js +8 -3
- package/lib/core/obj.js +255 -34
- package/lib/core/operator_list.js +17 -15
- package/lib/core/parser.js +40 -3
- package/lib/core/pattern.js +24 -11
- package/lib/core/primitives.js +112 -53
- package/lib/core/type1_parser.js +2 -0
- package/lib/core/worker.js +102 -37
- package/lib/core/writer.js +242 -0
- package/lib/display/annotation_layer.js +51 -10
- package/lib/display/annotation_storage.js +89 -0
- package/lib/display/api.js +140 -54
- package/lib/display/canvas.js +215 -46
- package/lib/display/display_utils.js +55 -18
- package/lib/display/fetch_stream.js +6 -0
- package/lib/display/font_loader.js +26 -15
- package/lib/display/metadata.js +1 -7
- package/lib/display/network.js +0 -14
- package/lib/display/node_utils.js +87 -0
- package/lib/display/optional_content_config.js +184 -0
- package/lib/display/svg.js +1 -1
- package/lib/display/text_layer.js +4 -1
- package/lib/pdf.js +2 -2
- package/lib/pdf.worker.js +2 -2
- package/lib/shared/is_node.js +1 -1
- package/lib/shared/util.js +13 -10
- package/lib/test/unit/annotation_spec.js +520 -50
- package/lib/test/unit/annotation_storage_spec.js +83 -0
- package/lib/test/unit/api_spec.js +16 -6
- package/lib/test/unit/cmap_spec.js +4 -4
- package/lib/test/unit/colorspace_spec.js +216 -24
- package/lib/test/unit/crypto_spec.js +51 -4
- package/lib/test/unit/custom_spec.js +129 -1
- package/lib/test/unit/document_spec.js +112 -1
- package/lib/test/unit/evaluator_spec.js +29 -10
- package/lib/test/unit/jasmine-boot.js +1 -1
- package/lib/test/unit/metadata_spec.js +3 -3
- package/lib/test/unit/primitives_spec.js +242 -63
- package/lib/test/unit/test_utils.js +42 -89
- package/lib/test/unit/testreporter.js +17 -6
- package/lib/test/unit/util_spec.js +13 -12
- package/lib/test/unit/writer_spec.js +84 -0
- package/lib/web/annotation_layer_builder.js +13 -9
- package/lib/web/app.js +231 -26
- package/lib/web/app_options.js +1 -6
- package/lib/web/base_tree_viewer.js +100 -0
- package/lib/web/base_viewer.js +53 -4
- package/lib/web/download_manager.js +3 -10
- package/lib/web/firefox_print_service.js +32 -12
- package/lib/web/firefoxcom.js +20 -6
- package/lib/web/interfaces.js +1 -1
- package/lib/web/pdf_attachment_viewer.js +80 -38
- package/lib/web/pdf_find_controller.js +2 -1
- package/lib/web/pdf_layer_viewer.js +208 -0
- package/lib/web/pdf_outline_viewer.js +24 -57
- package/lib/web/pdf_page_view.js +29 -6
- package/lib/web/pdf_print_service.js +13 -11
- package/lib/web/pdf_sidebar.js +46 -25
- package/lib/web/pdf_thumbnail_view.js +16 -3
- package/lib/web/pdf_thumbnail_viewer.js +17 -1
- package/lib/web/pdf_viewer.component.js +2 -2
- package/lib/web/preferences.js +1 -1
- package/lib/web/toolbar.js +1 -1
- package/lib/web/ui_utils.js +7 -1
- package/package.json +3 -1
- package/types/display/annotation_layer.d.ts +61 -0
- package/types/display/annotation_storage.d.ts +36 -0
- package/types/display/api.d.ts +1107 -0
- package/types/display/api_compatibility.d.ts +1 -0
- package/types/display/canvas.d.ts +4 -0
- package/types/display/content_disposition.d.ts +7 -0
- package/types/display/display_utils.d.ts +243 -0
- package/types/display/fetch_stream.d.ts +67 -0
- package/types/display/font_loader.d.ts +19 -0
- package/types/display/metadata.d.ts +9 -0
- package/types/display/network.d.ts +80 -0
- package/types/display/network_utils.d.ts +14 -0
- package/types/display/node_stream.d.ts +72 -0
- package/types/display/node_utils.d.ts +6 -0
- package/types/display/optional_content_config.d.ts +12 -0
- package/types/display/pattern_helper.d.ts +5 -0
- package/types/display/svg.d.ts +2 -0
- package/types/display/text_layer.d.ts +83 -0
- package/types/display/transport_stream.d.ts +57 -0
- package/types/display/webgl.d.ts +20 -0
- package/types/display/worker_options.d.ts +27 -0
- package/types/display/xml_parser.d.ts +35 -0
- package/types/pdf.d.ts +33 -0
- package/types/shared/compatibility.d.ts +1 -0
- package/types/shared/is_node.d.ts +1 -0
- package/types/shared/message_handler.d.ts +62 -0
- package/types/shared/util.d.ts +421 -0
- package/web/images/shadow.png +0 -0
- package/web/pdf_viewer.css +8 -5
- package/web/pdf_viewer.js +109 -33
- package/web/pdf_viewer.js.map +1 -1
- package/webpack.js +1 -9
- package/es5/web/images/texture.png +0 -0
- package/web/images/texture.png +0 -0
package/lib/core/annotation.js
CHANGED
@@ -41,12 +41,16 @@ var _operator_list = require("./operator_list.js");
|
|
41
41
|
|
42
42
|
var _stream = require("./stream.js");
|
43
43
|
|
44
|
+
var _writer = require("./writer.js");
|
45
|
+
|
44
46
|
class AnnotationFactory {
|
45
47
|
static create(xref, ref, pdfManager, idFactory) {
|
46
|
-
return pdfManager.
|
48
|
+
return pdfManager.ensureCatalog("acroForm").then(acroForm => {
|
49
|
+
return pdfManager.ensure(this, "_create", [xref, ref, pdfManager, idFactory, acroForm]);
|
50
|
+
});
|
47
51
|
}
|
48
52
|
|
49
|
-
static _create(xref, ref, pdfManager, idFactory) {
|
53
|
+
static _create(xref, ref, pdfManager, idFactory, acroForm) {
|
50
54
|
const dict = xref.fetchIfRef(ref);
|
51
55
|
|
52
56
|
if (!(0, _primitives.isDict)(dict)) {
|
@@ -58,10 +62,12 @@ class AnnotationFactory {
|
|
58
62
|
subtype = (0, _primitives.isName)(subtype) ? subtype.name : null;
|
59
63
|
const parameters = {
|
60
64
|
xref,
|
65
|
+
ref,
|
61
66
|
dict,
|
62
67
|
subtype,
|
63
68
|
id,
|
64
|
-
pdfManager
|
69
|
+
pdfManager,
|
70
|
+
acroForm: acroForm instanceof _primitives.Dict ? acroForm : _primitives.Dict.empty
|
65
71
|
};
|
66
72
|
|
67
73
|
switch (subtype) {
|
@@ -384,13 +390,14 @@ class Annotation {
|
|
384
390
|
});
|
385
391
|
}
|
386
392
|
|
387
|
-
getOperatorList(evaluator, task, renderForms) {
|
393
|
+
getOperatorList(evaluator, task, renderForms, annotationStorage) {
|
388
394
|
if (!this.appearance) {
|
389
395
|
return Promise.resolve(new _operator_list.OperatorList());
|
390
396
|
}
|
391
397
|
|
398
|
+
const appearance = this.appearance;
|
392
399
|
const data = this.data;
|
393
|
-
const appearanceDict =
|
400
|
+
const appearanceDict = appearance.dict;
|
394
401
|
const resourcesPromise = this.loadResources(["ExtGState", "ColorSpace", "Pattern", "Shading", "XObject", "Font"]);
|
395
402
|
const bbox = appearanceDict.getArray("BBox") || [0, 0, 1, 1];
|
396
403
|
const matrix = appearanceDict.getArray("Matrix") || [1, 0, 0, 1, 0, 0];
|
@@ -399,18 +406,22 @@ class Annotation {
|
|
399
406
|
const opList = new _operator_list.OperatorList();
|
400
407
|
opList.addOp(_util.OPS.beginAnnotation, [data.rect, transform, matrix]);
|
401
408
|
return evaluator.getOperatorList({
|
402
|
-
stream:
|
409
|
+
stream: appearance,
|
403
410
|
task,
|
404
411
|
resources,
|
405
412
|
operatorList: opList
|
406
413
|
}).then(() => {
|
407
414
|
opList.addOp(_util.OPS.endAnnotation, []);
|
408
|
-
|
415
|
+
appearance.reset();
|
409
416
|
return opList;
|
410
417
|
});
|
411
418
|
});
|
412
419
|
}
|
413
420
|
|
421
|
+
async save(evaluator, task, annotationStorage) {
|
422
|
+
return null;
|
423
|
+
}
|
424
|
+
|
414
425
|
}
|
415
426
|
|
416
427
|
exports.Annotation = Annotation;
|
@@ -583,18 +594,20 @@ class WidgetAnnotation extends Annotation {
|
|
583
594
|
super(params);
|
584
595
|
const dict = params.dict;
|
585
596
|
const data = this.data;
|
597
|
+
this.ref = params.ref;
|
586
598
|
data.annotationType = _util.AnnotationType.WIDGET;
|
587
599
|
data.fieldName = this._constructFieldName(dict);
|
588
|
-
|
600
|
+
const fieldValue = (0, _core_utils.getInheritableProperty)({
|
589
601
|
dict,
|
590
602
|
key: "V",
|
591
603
|
getArray: true
|
592
604
|
});
|
605
|
+
data.fieldValue = this._decodeFormValue(fieldValue);
|
593
606
|
data.alternativeText = (0, _util.stringToPDFString)(dict.get("TU") || "");
|
594
607
|
data.defaultAppearance = (0, _core_utils.getInheritableProperty)({
|
595
608
|
dict,
|
596
609
|
key: "DA"
|
597
|
-
}) || "";
|
610
|
+
}) || params.acroForm.get("DA") || "";
|
598
611
|
const fieldType = (0, _core_utils.getInheritableProperty)({
|
599
612
|
dict,
|
600
613
|
key: "FT"
|
@@ -603,7 +616,7 @@ class WidgetAnnotation extends Annotation {
|
|
603
616
|
this.fieldResources = (0, _core_utils.getInheritableProperty)({
|
604
617
|
dict,
|
605
618
|
key: "DR"
|
606
|
-
}) || _primitives.Dict.empty;
|
619
|
+
}) || params.acroForm.get("DR") || _primitives.Dict.empty;
|
607
620
|
data.fieldFlags = (0, _core_utils.getInheritableProperty)({
|
608
621
|
dict,
|
609
622
|
key: "Ff"
|
@@ -654,16 +667,225 @@ class WidgetAnnotation extends Annotation {
|
|
654
667
|
return fieldName.join(".");
|
655
668
|
}
|
656
669
|
|
670
|
+
_decodeFormValue(formValue) {
|
671
|
+
if (Array.isArray(formValue)) {
|
672
|
+
return formValue.filter(item => (0, _util.isString)(item)).map(item => (0, _util.stringToPDFString)(item));
|
673
|
+
} else if ((0, _primitives.isName)(formValue)) {
|
674
|
+
return (0, _util.stringToPDFString)(formValue.name);
|
675
|
+
} else if ((0, _util.isString)(formValue)) {
|
676
|
+
return (0, _util.stringToPDFString)(formValue);
|
677
|
+
}
|
678
|
+
|
679
|
+
return null;
|
680
|
+
}
|
681
|
+
|
657
682
|
hasFieldFlag(flag) {
|
658
683
|
return !!(this.data.fieldFlags & flag);
|
659
684
|
}
|
660
685
|
|
661
|
-
getOperatorList(evaluator, task, renderForms) {
|
686
|
+
getOperatorList(evaluator, task, renderForms, annotationStorage) {
|
662
687
|
if (renderForms) {
|
663
688
|
return Promise.resolve(new _operator_list.OperatorList());
|
664
689
|
}
|
665
690
|
|
666
|
-
|
691
|
+
if (!this._hasText) {
|
692
|
+
return super.getOperatorList(evaluator, task, renderForms, annotationStorage);
|
693
|
+
}
|
694
|
+
|
695
|
+
return this._getAppearance(evaluator, task, annotationStorage).then(content => {
|
696
|
+
if (this.appearance && content === null) {
|
697
|
+
return super.getOperatorList(evaluator, task, renderForms, annotationStorage);
|
698
|
+
}
|
699
|
+
|
700
|
+
const operatorList = new _operator_list.OperatorList();
|
701
|
+
|
702
|
+
if (!this.data.defaultAppearance || content === null) {
|
703
|
+
return operatorList;
|
704
|
+
}
|
705
|
+
|
706
|
+
const matrix = [1, 0, 0, 1, 0, 0];
|
707
|
+
const bbox = [0, 0, this.data.rect[2] - this.data.rect[0], this.data.rect[3] - this.data.rect[1]];
|
708
|
+
const transform = getTransformMatrix(this.data.rect, bbox, matrix);
|
709
|
+
operatorList.addOp(_util.OPS.beginAnnotation, [this.data.rect, transform, matrix]);
|
710
|
+
const stream = new _stream.StringStream(content);
|
711
|
+
return evaluator.getOperatorList({
|
712
|
+
stream,
|
713
|
+
task,
|
714
|
+
resources: this.fieldResources,
|
715
|
+
operatorList
|
716
|
+
}).then(function () {
|
717
|
+
operatorList.addOp(_util.OPS.endAnnotation, []);
|
718
|
+
return operatorList;
|
719
|
+
});
|
720
|
+
});
|
721
|
+
}
|
722
|
+
|
723
|
+
async save(evaluator, task, annotationStorage) {
|
724
|
+
if (this.data.fieldValue === annotationStorage[this.data.id]) {
|
725
|
+
return null;
|
726
|
+
}
|
727
|
+
|
728
|
+
let appearance = await this._getAppearance(evaluator, task, annotationStorage);
|
729
|
+
|
730
|
+
if (appearance === null) {
|
731
|
+
return null;
|
732
|
+
}
|
733
|
+
|
734
|
+
const dict = evaluator.xref.fetchIfRef(this.ref);
|
735
|
+
|
736
|
+
if (!(0, _primitives.isDict)(dict)) {
|
737
|
+
return null;
|
738
|
+
}
|
739
|
+
|
740
|
+
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);
|
743
|
+
AP.set("N", newRef);
|
744
|
+
const value = annotationStorage[this.data.id];
|
745
|
+
const encrypt = evaluator.xref.encrypt;
|
746
|
+
let originalTransform = null;
|
747
|
+
let newTransform = null;
|
748
|
+
|
749
|
+
if (encrypt) {
|
750
|
+
originalTransform = encrypt.createCipherTransform(this.ref.num, this.ref.gen);
|
751
|
+
newTransform = encrypt.createCipherTransform(newRef.num, newRef.gen);
|
752
|
+
appearance = newTransform.encryptString(appearance);
|
753
|
+
}
|
754
|
+
|
755
|
+
dict.set("V", value);
|
756
|
+
dict.set("AP", AP);
|
757
|
+
dict.set("M", `D:${(0, _util.getModificationDate)()}`);
|
758
|
+
const appearanceDict = new _primitives.Dict(evaluator.xref);
|
759
|
+
appearanceDict.set("Length", appearance.length);
|
760
|
+
appearanceDict.set("Subtype", _primitives.Name.get("Form"));
|
761
|
+
appearanceDict.set("Resources", this.fieldResources);
|
762
|
+
appearanceDict.set("BBox", bbox);
|
763
|
+
const bufferOriginal = [`${this.ref.num} ${this.ref.gen} obj\n`];
|
764
|
+
(0, _writer.writeDict)(dict, bufferOriginal, originalTransform);
|
765
|
+
bufferOriginal.push("\nendobj\n");
|
766
|
+
const bufferNew = [`${newRef.num} ${newRef.gen} obj\n`];
|
767
|
+
(0, _writer.writeDict)(appearanceDict, bufferNew, newTransform);
|
768
|
+
bufferNew.push(" stream\n");
|
769
|
+
bufferNew.push(appearance);
|
770
|
+
bufferNew.push("\nendstream\nendobj\n");
|
771
|
+
return [{
|
772
|
+
ref: this.ref,
|
773
|
+
data: bufferOriginal.join("")
|
774
|
+
}, {
|
775
|
+
ref: newRef,
|
776
|
+
data: bufferNew.join("")
|
777
|
+
}];
|
778
|
+
}
|
779
|
+
|
780
|
+
async _getAppearance(evaluator, task, annotationStorage) {
|
781
|
+
const isPassword = this.hasFieldFlag(_util.AnnotationFieldFlag.PASSWORD);
|
782
|
+
|
783
|
+
if (!annotationStorage || isPassword) {
|
784
|
+
return null;
|
785
|
+
}
|
786
|
+
|
787
|
+
const value = annotationStorage[this.data.id];
|
788
|
+
|
789
|
+
if (value === "") {
|
790
|
+
return "";
|
791
|
+
}
|
792
|
+
|
793
|
+
const defaultPadding = 2;
|
794
|
+
const hPadding = defaultPadding;
|
795
|
+
const totalHeight = this.data.rect[3] - this.data.rect[1];
|
796
|
+
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);
|
801
|
+
let descent = font.descent;
|
802
|
+
|
803
|
+
if (isNaN(descent)) {
|
804
|
+
descent = 0;
|
805
|
+
}
|
806
|
+
|
807
|
+
const vPadding = defaultPadding + Math.abs(descent) * fontSize;
|
808
|
+
const defaultAppearance = this.data.defaultAppearance;
|
809
|
+
const alignment = this.data.textAlignment;
|
810
|
+
|
811
|
+
if (this.data.comb) {
|
812
|
+
return this._getCombAppearance(defaultAppearance, value, totalWidth, hPadding, vPadding);
|
813
|
+
}
|
814
|
+
|
815
|
+
if (this.data.multiLine) {
|
816
|
+
return this._getMultilineAppearance(defaultAppearance, value, font, fontSize, totalWidth, totalHeight, alignment, hPadding, vPadding);
|
817
|
+
}
|
818
|
+
|
819
|
+
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";
|
821
|
+
}
|
822
|
+
|
823
|
+
const renderedText = this._renderText(value, font, fontSize, totalWidth, alignment, hPadding, vPadding);
|
824
|
+
|
825
|
+
return "/Tx BMC q BT " + defaultAppearance + ` 1 0 0 1 0 0 Tm ${renderedText}` + " ET Q EMC";
|
826
|
+
}
|
827
|
+
|
828
|
+
async _getFontData(evaluator, task) {
|
829
|
+
const operatorList = new _operator_list.OperatorList();
|
830
|
+
const initialState = {
|
831
|
+
fontSize: 0,
|
832
|
+
font: null,
|
833
|
+
fontName: null,
|
834
|
+
|
835
|
+
clone() {
|
836
|
+
return this;
|
837
|
+
}
|
838
|
+
|
839
|
+
};
|
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`);
|
856
|
+
|
857
|
+
if (this.data.defaultAppearance.search(fontRegex) === -1) {
|
858
|
+
fontRegex = new RegExp(`/${fontName}\\s+Tf`);
|
859
|
+
}
|
860
|
+
|
861
|
+
this.data.defaultAppearance = this.data.defaultAppearance.replace(fontRegex, `/${fontName} ${fontSize} Tf`);
|
862
|
+
}
|
863
|
+
|
864
|
+
return fontSize;
|
865
|
+
}
|
866
|
+
|
867
|
+
_renderText(text, font, fontSize, totalWidth, alignment, hPadding, vPadding) {
|
868
|
+
const glyphs = font.charsToGlyphs(text);
|
869
|
+
const scale = fontSize / 1000;
|
870
|
+
let width = 0;
|
871
|
+
|
872
|
+
for (const glyph of glyphs) {
|
873
|
+
width += glyph.width * scale;
|
874
|
+
}
|
875
|
+
|
876
|
+
let shift;
|
877
|
+
|
878
|
+
if (alignment === 1) {
|
879
|
+
shift = (totalWidth - width) / 2;
|
880
|
+
} else if (alignment === 2) {
|
881
|
+
shift = totalWidth - width - hPadding;
|
882
|
+
} else {
|
883
|
+
shift = hPadding;
|
884
|
+
}
|
885
|
+
|
886
|
+
shift = shift.toFixed(2);
|
887
|
+
vPadding = vPadding.toFixed(2);
|
888
|
+
return `${shift} ${vPadding} Td (${(0, _util.escapeString)(text)}) Tj`;
|
667
889
|
}
|
668
890
|
|
669
891
|
}
|
@@ -671,8 +893,13 @@ class WidgetAnnotation extends Annotation {
|
|
671
893
|
class TextWidgetAnnotation extends WidgetAnnotation {
|
672
894
|
constructor(params) {
|
673
895
|
super(params);
|
896
|
+
this._hasText = true;
|
674
897
|
const dict = params.dict;
|
675
|
-
|
898
|
+
|
899
|
+
if (!(0, _util.isString)(this.data.fieldValue)) {
|
900
|
+
this.data.fieldValue = "";
|
901
|
+
}
|
902
|
+
|
676
903
|
let alignment = (0, _core_utils.getInheritableProperty)({
|
677
904
|
dict,
|
678
905
|
key: "Q"
|
@@ -697,26 +924,86 @@ class TextWidgetAnnotation extends WidgetAnnotation {
|
|
697
924
|
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;
|
698
925
|
}
|
699
926
|
|
700
|
-
|
701
|
-
|
702
|
-
|
927
|
+
_getCombAppearance(defaultAppearance, text, width, hPadding, vPadding) {
|
928
|
+
const combWidth = (width / this.data.maxLen).toFixed(2);
|
929
|
+
const buf = [];
|
930
|
+
|
931
|
+
for (const character of text) {
|
932
|
+
buf.push(`(${(0, _util.escapeString)(character)}) Tj`);
|
933
|
+
}
|
934
|
+
|
935
|
+
const renderedComb = buf.join(` ${combWidth} 0 Td `);
|
936
|
+
return "/Tx BMC q BT " + defaultAppearance + ` 1 0 0 1 ${hPadding} ${vPadding} Tm ${renderedComb}` + " ET Q EMC";
|
937
|
+
}
|
938
|
+
|
939
|
+
_getMultilineAppearance(defaultAppearance, text, font, fontSize, width, height, alignment, hPadding, vPadding) {
|
940
|
+
const lines = text.split(/\r\n|\r|\n/);
|
941
|
+
const buf = [];
|
942
|
+
const totalWidth = width - 2 * hPadding;
|
943
|
+
|
944
|
+
for (const line of lines) {
|
945
|
+
const chunks = this._splitLine(line, font, fontSize, totalWidth);
|
946
|
+
|
947
|
+
for (const chunk of chunks) {
|
948
|
+
const padding = buf.length === 0 ? hPadding : 0;
|
949
|
+
buf.push(this._renderText(chunk, font, fontSize, width, alignment, padding, -fontSize));
|
950
|
+
}
|
703
951
|
}
|
704
952
|
|
705
|
-
const
|
953
|
+
const renderedText = buf.join("\n");
|
954
|
+
return "/Tx BMC q BT " + defaultAppearance + ` 1 0 0 1 0 ${height} Tm ${renderedText}` + " ET Q EMC";
|
955
|
+
}
|
706
956
|
|
707
|
-
|
708
|
-
|
957
|
+
_splitLine(line, font, fontSize, width) {
|
958
|
+
if (line.length <= 1) {
|
959
|
+
return [line];
|
709
960
|
}
|
710
961
|
|
711
|
-
const
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
962
|
+
const scale = fontSize / 1000;
|
963
|
+
const whitespace = font.charsToGlyphs(" ", true)[0].width * scale;
|
964
|
+
const chunks = [];
|
965
|
+
let lastSpacePos = -1,
|
966
|
+
startChunk = 0,
|
967
|
+
currentWidth = 0;
|
968
|
+
|
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;
|
977
|
+
lastSpacePos = -1;
|
978
|
+
} else {
|
979
|
+
currentWidth += whitespace;
|
980
|
+
lastSpacePos = i;
|
981
|
+
}
|
982
|
+
} 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;
|
990
|
+
currentWidth = 0;
|
991
|
+
} else {
|
992
|
+
chunks.push(line.substring(startChunk, i));
|
993
|
+
startChunk = i;
|
994
|
+
currentWidth = charWidth;
|
995
|
+
}
|
996
|
+
} else {
|
997
|
+
currentWidth += charWidth;
|
998
|
+
}
|
999
|
+
}
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
if (startChunk < line.length) {
|
1003
|
+
chunks.push(line.substring(startChunk, line.length));
|
1004
|
+
}
|
1005
|
+
|
1006
|
+
return chunks;
|
720
1007
|
}
|
721
1008
|
|
722
1009
|
}
|
@@ -724,6 +1011,8 @@ class TextWidgetAnnotation extends WidgetAnnotation {
|
|
724
1011
|
class ButtonWidgetAnnotation extends WidgetAnnotation {
|
725
1012
|
constructor(params) {
|
726
1013
|
super(params);
|
1014
|
+
this.checkedAppearance = null;
|
1015
|
+
this.uncheckedAppearance = null;
|
727
1016
|
this.data.checkBox = !this.hasFieldFlag(_util.AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PUSHBUTTON);
|
728
1017
|
this.data.radioButton = this.hasFieldFlag(_util.AnnotationFieldFlag.RADIO) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PUSHBUTTON);
|
729
1018
|
this.data.pushButton = this.hasFieldFlag(_util.AnnotationFieldFlag.PUSHBUTTON);
|
@@ -739,31 +1028,171 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
|
|
739
1028
|
}
|
740
1029
|
}
|
741
1030
|
|
742
|
-
|
743
|
-
if (
|
744
|
-
|
1031
|
+
getOperatorList(evaluator, task, renderForms, annotationStorage) {
|
1032
|
+
if (this.data.pushButton) {
|
1033
|
+
return super.getOperatorList(evaluator, task, false, annotationStorage);
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
if (annotationStorage) {
|
1037
|
+
const value = annotationStorage[this.data.id] || false;
|
1038
|
+
let appearance;
|
1039
|
+
|
1040
|
+
if (value) {
|
1041
|
+
appearance = this.checkedAppearance;
|
1042
|
+
} else {
|
1043
|
+
appearance = this.uncheckedAppearance;
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
if (appearance) {
|
1047
|
+
const savedAppearance = this.appearance;
|
1048
|
+
this.appearance = appearance;
|
1049
|
+
const operatorList = super.getOperatorList(evaluator, task, renderForms, annotationStorage);
|
1050
|
+
this.appearance = savedAppearance;
|
1051
|
+
return operatorList;
|
1052
|
+
}
|
1053
|
+
|
1054
|
+
return Promise.resolve(new _operator_list.OperatorList());
|
745
1055
|
}
|
746
1056
|
|
1057
|
+
return super.getOperatorList(evaluator, task, renderForms, annotationStorage);
|
1058
|
+
}
|
1059
|
+
|
1060
|
+
async save(evaluator, task, annotationStorage) {
|
1061
|
+
if (this.data.checkBox) {
|
1062
|
+
return this._saveCheckbox(evaluator, task, annotationStorage);
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
if (this.data.radioButton) {
|
1066
|
+
return this._saveRadioButton(evaluator, task, annotationStorage);
|
1067
|
+
}
|
1068
|
+
|
1069
|
+
return super.save(evaluator, task, annotationStorage);
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
async _saveCheckbox(evaluator, task, annotationStorage) {
|
1073
|
+
const defaultValue = this.data.fieldValue && this.data.fieldValue !== "Off";
|
1074
|
+
const value = annotationStorage[this.data.id];
|
1075
|
+
|
1076
|
+
if (defaultValue === value) {
|
1077
|
+
return null;
|
1078
|
+
}
|
1079
|
+
|
1080
|
+
const dict = evaluator.xref.fetchIfRef(this.ref);
|
1081
|
+
|
1082
|
+
if (!(0, _primitives.isDict)(dict)) {
|
1083
|
+
return null;
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
const name = _primitives.Name.get(value ? this.data.exportValue : "Off");
|
1087
|
+
|
1088
|
+
dict.set("V", name);
|
1089
|
+
dict.set("AS", name);
|
1090
|
+
dict.set("M", `D:${(0, _util.getModificationDate)()}`);
|
1091
|
+
const encrypt = evaluator.xref.encrypt;
|
1092
|
+
let originalTransform = null;
|
1093
|
+
|
1094
|
+
if (encrypt) {
|
1095
|
+
originalTransform = encrypt.createCipherTransform(this.ref.num, this.ref.gen);
|
1096
|
+
}
|
1097
|
+
|
1098
|
+
const buffer = [`${this.ref.num} ${this.ref.gen} obj\n`];
|
1099
|
+
(0, _writer.writeDict)(dict, buffer, originalTransform);
|
1100
|
+
buffer.push("\nendobj\n");
|
1101
|
+
return [{
|
1102
|
+
ref: this.ref,
|
1103
|
+
data: buffer.join("")
|
1104
|
+
}];
|
1105
|
+
}
|
1106
|
+
|
1107
|
+
async _saveRadioButton(evaluator, task, annotationStorage) {
|
1108
|
+
const defaultValue = this.data.fieldValue === this.data.buttonValue;
|
1109
|
+
const value = annotationStorage[this.data.id];
|
1110
|
+
|
1111
|
+
if (defaultValue === value) {
|
1112
|
+
return null;
|
1113
|
+
}
|
1114
|
+
|
1115
|
+
const dict = evaluator.xref.fetchIfRef(this.ref);
|
1116
|
+
|
1117
|
+
if (!(0, _primitives.isDict)(dict)) {
|
1118
|
+
return null;
|
1119
|
+
}
|
1120
|
+
|
1121
|
+
const name = _primitives.Name.get(value ? this.data.buttonValue : "Off");
|
1122
|
+
|
1123
|
+
let parentBuffer = null;
|
1124
|
+
const encrypt = evaluator.xref.encrypt;
|
1125
|
+
|
1126
|
+
if (value) {
|
1127
|
+
if ((0, _primitives.isRef)(this.parent)) {
|
1128
|
+
const parent = evaluator.xref.fetch(this.parent);
|
1129
|
+
let parentTransform = null;
|
1130
|
+
|
1131
|
+
if (encrypt) {
|
1132
|
+
parentTransform = encrypt.createCipherTransform(this.parent.num, this.parent.gen);
|
1133
|
+
}
|
1134
|
+
|
1135
|
+
parent.set("V", name);
|
1136
|
+
parentBuffer = [`${this.parent.num} ${this.parent.gen} obj\n`];
|
1137
|
+
(0, _writer.writeDict)(parent, parentBuffer, parentTransform);
|
1138
|
+
parentBuffer.push("\nendobj\n");
|
1139
|
+
} else if ((0, _primitives.isDict)(this.parent)) {
|
1140
|
+
this.parent.set("V", name);
|
1141
|
+
}
|
1142
|
+
}
|
1143
|
+
|
1144
|
+
dict.set("AS", name);
|
1145
|
+
dict.set("M", `D:${(0, _util.getModificationDate)()}`);
|
1146
|
+
let originalTransform = null;
|
1147
|
+
|
1148
|
+
if (encrypt) {
|
1149
|
+
originalTransform = encrypt.createCipherTransform(this.ref.num, this.ref.gen);
|
1150
|
+
}
|
1151
|
+
|
1152
|
+
const buffer = [`${this.ref.num} ${this.ref.gen} obj\n`];
|
1153
|
+
(0, _writer.writeDict)(dict, buffer, originalTransform);
|
1154
|
+
buffer.push("\nendobj\n");
|
1155
|
+
const newRefs = [{
|
1156
|
+
ref: this.ref,
|
1157
|
+
data: buffer.join("")
|
1158
|
+
}];
|
1159
|
+
|
1160
|
+
if (parentBuffer !== null) {
|
1161
|
+
newRefs.push({
|
1162
|
+
ref: this.parent,
|
1163
|
+
data: parentBuffer.join("")
|
1164
|
+
});
|
1165
|
+
}
|
1166
|
+
|
1167
|
+
return newRefs;
|
1168
|
+
}
|
1169
|
+
|
1170
|
+
_processCheckBox(params) {
|
747
1171
|
const customAppearance = params.dict.get("AP");
|
748
1172
|
|
749
1173
|
if (!(0, _primitives.isDict)(customAppearance)) {
|
750
1174
|
return;
|
751
1175
|
}
|
752
1176
|
|
753
|
-
const
|
1177
|
+
const normalAppearance = customAppearance.get("N");
|
754
1178
|
|
755
|
-
if (!(0, _primitives.isDict)(
|
1179
|
+
if (!(0, _primitives.isDict)(normalAppearance)) {
|
756
1180
|
return;
|
757
1181
|
}
|
758
1182
|
|
759
|
-
const exportValues =
|
760
|
-
const hasCorrectOptionCount = exportValues.length === 2;
|
1183
|
+
const exportValues = normalAppearance.getKeys();
|
761
1184
|
|
762
|
-
if (!
|
1185
|
+
if (!exportValues.includes("Off")) {
|
1186
|
+
exportValues.push("Off");
|
1187
|
+
}
|
1188
|
+
|
1189
|
+
if (exportValues.length !== 2) {
|
763
1190
|
return;
|
764
1191
|
}
|
765
1192
|
|
766
1193
|
this.data.exportValue = exportValues[0] === "Off" ? exportValues[1] : exportValues[0];
|
1194
|
+
this.checkedAppearance = normalAppearance.get(this.data.exportValue);
|
1195
|
+
this.uncheckedAppearance = normalAppearance.get("Off") || null;
|
767
1196
|
}
|
768
1197
|
|
769
1198
|
_processRadioButton(params) {
|
@@ -774,7 +1203,8 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
|
|
774
1203
|
const fieldParentValue = fieldParent.get("V");
|
775
1204
|
|
776
1205
|
if ((0, _primitives.isName)(fieldParentValue)) {
|
777
|
-
this.
|
1206
|
+
this.parent = params.dict.getRaw("Parent");
|
1207
|
+
this.data.fieldValue = this._decodeFormValue(fieldParentValue);
|
778
1208
|
}
|
779
1209
|
}
|
780
1210
|
|
@@ -784,18 +1214,21 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
|
|
784
1214
|
return;
|
785
1215
|
}
|
786
1216
|
|
787
|
-
const
|
1217
|
+
const normalAppearance = appearanceStates.get("N");
|
788
1218
|
|
789
|
-
if (!(0, _primitives.isDict)(
|
1219
|
+
if (!(0, _primitives.isDict)(normalAppearance)) {
|
790
1220
|
return;
|
791
1221
|
}
|
792
1222
|
|
793
|
-
for (const key of
|
1223
|
+
for (const key of normalAppearance.getKeys()) {
|
794
1224
|
if (key !== "Off") {
|
795
1225
|
this.data.buttonValue = key;
|
796
1226
|
break;
|
797
1227
|
}
|
798
1228
|
}
|
1229
|
+
|
1230
|
+
this.checkedAppearance = normalAppearance.get(this.data.buttonValue);
|
1231
|
+
this.uncheckedAppearance = normalAppearance.get("Off") || null;
|
799
1232
|
}
|
800
1233
|
|
801
1234
|
_processPushButton(params) {
|
@@ -829,18 +1262,21 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation {
|
|
829
1262
|
const option = xref.fetchIfRef(options[i]);
|
830
1263
|
const isOptionArray = Array.isArray(option);
|
831
1264
|
this.data.options[i] = {
|
832
|
-
exportValue: isOptionArray ? xref.fetchIfRef(option[0]) : option,
|
833
|
-
displayValue:
|
1265
|
+
exportValue: this._decodeFormValue(isOptionArray ? xref.fetchIfRef(option[0]) : option),
|
1266
|
+
displayValue: this._decodeFormValue(isOptionArray ? xref.fetchIfRef(option[1]) : option)
|
834
1267
|
};
|
835
1268
|
}
|
836
1269
|
}
|
837
1270
|
|
838
|
-
if (
|
1271
|
+
if ((0, _util.isString)(this.data.fieldValue)) {
|
839
1272
|
this.data.fieldValue = [this.data.fieldValue];
|
1273
|
+
} else if (!this.data.fieldValue) {
|
1274
|
+
this.data.fieldValue = [];
|
840
1275
|
}
|
841
1276
|
|
842
1277
|
this.data.combo = this.hasFieldFlag(_util.AnnotationFieldFlag.COMBO);
|
843
1278
|
this.data.multiSelect = this.hasFieldFlag(_util.AnnotationFieldFlag.MULTISELECT);
|
1279
|
+
this._hasText = true;
|
844
1280
|
}
|
845
1281
|
|
846
1282
|
}
|