pdf-lite 1.4.0 → 1.6.0
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.
- package/EXAMPLES.md +51 -70
- package/README.md +1 -1
- package/dist/acroform/appearance/index.d.ts +4 -4
- package/dist/acroform/appearance/index.js +4 -4
- package/dist/acroform/appearance/{PdfAppearanceStream.d.ts → pdf-appearance-stream.d.ts} +9 -3
- package/dist/acroform/appearance/{PdfAppearanceStream.js → pdf-appearance-stream.js} +14 -5
- package/dist/acroform/appearance/{PdfButtonAppearanceStream.d.ts → pdf-button-appearance-stream.d.ts} +3 -2
- package/dist/acroform/appearance/pdf-button-appearance-stream.js +58 -0
- package/dist/acroform/appearance/pdf-choice-appearance-stream.d.ts +22 -0
- package/dist/acroform/appearance/pdf-choice-appearance-stream.js +75 -0
- package/dist/acroform/appearance/pdf-graphics.d.ts +51 -0
- package/dist/acroform/appearance/pdf-graphics.js +239 -0
- package/dist/acroform/appearance/{PdfTextAppearanceStream.d.ts → pdf-text-appearance-stream.d.ts} +7 -2
- package/dist/acroform/appearance/pdf-text-appearance-stream.js +104 -0
- package/dist/acroform/fields/index.d.ts +7 -7
- package/dist/acroform/fields/index.js +7 -7
- package/dist/acroform/fields/pdf-button-form-field.d.ts +14 -0
- package/dist/acroform/fields/pdf-button-form-field.js +70 -0
- package/dist/acroform/fields/pdf-choice-form-field.d.ts +19 -0
- package/dist/acroform/fields/pdf-choice-form-field.js +112 -0
- package/dist/acroform/fields/{PdfFormFieldFlags.d.ts → pdf-form-field-flags.d.ts} +5 -6
- package/dist/acroform/fields/{PdfFormFieldFlags.js → pdf-form-field-flags.js} +12 -18
- package/dist/acroform/fields/{PdfFormField.d.ts → pdf-form-field.d.ts} +37 -38
- package/dist/acroform/fields/pdf-form-field.js +519 -0
- package/dist/acroform/fields/{PdfSignatureFormField.d.ts → pdf-signature-form-field.d.ts} +1 -1
- package/dist/acroform/fields/{PdfSignatureFormField.js → pdf-signature-form-field.js} +1 -1
- package/dist/acroform/fields/{PdfTextFormField.d.ts → pdf-text-form-field.d.ts} +1 -1
- package/dist/acroform/fields/{PdfTextFormField.js → pdf-text-form-field.js} +11 -13
- package/dist/acroform/fields/types.d.ts +6 -1
- package/dist/acroform/index.d.ts +1 -3
- package/dist/acroform/index.js +1 -3
- package/dist/acroform/pdf-acro-form.d.ts +45 -0
- package/dist/acroform/pdf-acro-form.js +203 -0
- package/dist/acroform/xfa/index.d.ts +3 -3
- package/dist/acroform/xfa/index.js +2 -2
- package/dist/acroform/xfa/{PdfXfaData.d.ts → pdf-xfa-data.d.ts} +4 -3
- package/dist/acroform/xfa/{PdfXfaData.js → pdf-xfa-data.js} +16 -12
- package/dist/acroform/xfa/pdf-xfa-form.d.ts +16 -0
- package/dist/acroform/xfa/pdf-xfa-form.js +34 -0
- package/dist/annotations/index.d.ts +3 -4
- package/dist/annotations/index.js +3 -4
- package/dist/annotations/{PdfAnnotationFlags.d.ts → pdf-annotation-flags.d.ts} +3 -4
- package/dist/annotations/{PdfAnnotationFlags.js → pdf-annotation-flags.js} +5 -6
- package/dist/annotations/{PdfAnnotation.d.ts → pdf-annotation.d.ts} +31 -5
- package/dist/annotations/{PdfAnnotation.js → pdf-annotation.js} +31 -19
- package/dist/annotations/pdf-default-resources.d.ts +11 -0
- package/dist/annotations/pdf-default-resources.js +3 -0
- package/dist/annotations/{PdfWidgetAnnotation.d.ts → pdf-widget-annotation.d.ts} +1 -1
- package/dist/annotations/{PdfWidgetAnnotation.js → pdf-widget-annotation.js} +1 -1
- package/dist/core/decoder.js +1 -1
- package/dist/core/objects/pdf-array.d.ts +8 -1
- package/dist/core/objects/pdf-array.js +31 -0
- package/dist/core/objects/pdf-dictionary.d.ts +2 -0
- package/dist/core/objects/pdf-dictionary.js +14 -7
- package/dist/core/objects/pdf-hexadecimal.d.ts +1 -0
- package/dist/core/objects/pdf-hexadecimal.js +3 -3
- package/dist/core/objects/pdf-indirect-object.d.ts +18 -9
- package/dist/core/objects/pdf-indirect-object.js +75 -16
- package/dist/core/objects/pdf-number.d.ts +1 -0
- package/dist/core/objects/pdf-number.js +5 -4
- package/dist/core/objects/pdf-object-reference.d.ts +8 -1
- package/dist/core/objects/pdf-object-reference.js +14 -0
- package/dist/core/objects/pdf-object.d.ts +14 -0
- package/dist/core/objects/pdf-object.js +36 -0
- package/dist/core/objects/pdf-start-xref.d.ts +1 -0
- package/dist/core/objects/pdf-start-xref.js +4 -0
- package/dist/core/objects/pdf-stream.d.ts +44 -7
- package/dist/core/objects/pdf-stream.js +284 -26
- package/dist/core/objects/pdf-string.d.ts +1 -0
- package/dist/core/objects/pdf-string.js +3 -6
- package/dist/core/objects/pdf-trailer.d.ts +1 -0
- package/dist/core/objects/pdf-trailer.js +6 -3
- package/dist/core/objects/pdf-xref-table.js +1 -1
- package/dist/core/parser/incremental-parser.d.ts +0 -13
- package/dist/core/parser/incremental-parser.js +1 -18
- package/dist/core/ref.d.ts +3 -1
- package/dist/core/ref.js +8 -5
- package/dist/core/streams/object-stream.d.ts +1 -1
- package/dist/core/streams/object-stream.js +1 -1
- package/dist/core/tokens/token.d.ts +2 -1
- package/dist/core/tokens/token.js +3 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.js +24 -0
- package/dist/fonts/index.d.ts +0 -1
- package/dist/fonts/index.js +0 -1
- package/dist/fonts/pdf-font.d.ts +94 -32
- package/dist/fonts/pdf-font.js +301 -83
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/pdf/index.d.ts +2 -1
- package/dist/pdf/index.js +2 -1
- package/dist/pdf/pdf-document.d.ts +61 -36
- package/dist/pdf/pdf-document.js +315 -117
- package/dist/pdf/pdf-page.d.ts +50 -0
- package/dist/pdf/pdf-page.js +144 -0
- package/dist/pdf/pdf-pages.d.ts +28 -0
- package/dist/pdf/pdf-pages.js +94 -0
- package/dist/pdf/pdf-reader.d.ts +5 -1
- package/dist/pdf/pdf-reader.js +36 -2
- package/dist/pdf/pdf-revision.d.ts +3 -3
- package/dist/pdf/pdf-revision.js +7 -7
- package/dist/pdf/pdf-xref-lookup.js +34 -14
- package/dist/signing/document-security-store.d.ts +14 -17
- package/dist/signing/document-security-store.js +19 -34
- package/dist/signing/signer.d.ts +23 -8
- package/dist/signing/signer.js +51 -17
- package/dist/utils/encodePdfText.d.ts +17 -0
- package/dist/utils/encodePdfText.js +61 -0
- package/dist/utils/index.d.ts +1 -2
- package/dist/utils/index.js +1 -2
- package/dist/utils/needsCentralWhitespace.d.ts +10 -0
- package/dist/utils/needsCentralWhitespace.js +34 -0
- package/package.json +3 -3
- package/dist/acroform/PdfAcroForm.d.ts +0 -63
- package/dist/acroform/PdfAcroForm.js +0 -279
- package/dist/acroform/PdfFontEncodingCache.d.ts +0 -16
- package/dist/acroform/PdfFontEncodingCache.js +0 -75
- package/dist/acroform/acroform.d.ts +0 -9
- package/dist/acroform/acroform.js +0 -7
- package/dist/acroform/appearance/PdfButtonAppearanceStream.js +0 -54
- package/dist/acroform/appearance/PdfChoiceAppearanceStream.d.ts +0 -15
- package/dist/acroform/appearance/PdfChoiceAppearanceStream.js +0 -48
- package/dist/acroform/appearance/PdfTextAppearanceStream.js +0 -75
- package/dist/acroform/fields/PdfButtonFormField.d.ts +0 -9
- package/dist/acroform/fields/PdfButtonFormField.js +0 -35
- package/dist/acroform/fields/PdfChoiceFormField.d.ts +0 -9
- package/dist/acroform/fields/PdfChoiceFormField.js +0 -46
- package/dist/acroform/fields/PdfFormField.js +0 -499
- package/dist/acroform/manager.d.ts +0 -33
- package/dist/acroform/manager.js +0 -51
- package/dist/acroform/xfa/PdfXfaForm.d.ts +0 -12
- package/dist/acroform/xfa/PdfXfaForm.js +0 -64
- package/dist/annotations/PdfAnnotationWriter.d.ts +0 -20
- package/dist/annotations/PdfAnnotationWriter.js +0 -76
- package/dist/fonts/font-manager.d.ts +0 -127
- package/dist/fonts/font-manager.js +0 -378
- package/dist/pdf/errors.d.ts +0 -6
- package/dist/pdf/errors.js +0 -6
- package/dist/utils/predictors.d.ts +0 -113
- package/dist/utils/predictors.js +0 -279
- /package/dist/acroform/fields/{PdfDefaultAppearance.d.ts → pdf-default-appearance.d.ts} +0 -0
- /package/dist/acroform/fields/{PdfDefaultAppearance.js → pdf-default-appearance.js} +0 -0
- /package/dist/utils/{IterableReadableStream.d.ts → iterable-readable-stream.d.ts} +0 -0
- /package/dist/utils/{IterableReadableStream.js → iterable-readable-stream.js} +0 -0
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
|
|
2
|
-
import { PdfArray } from '../core/objects/pdf-array.js';
|
|
3
|
-
import { PdfString } from '../core/objects/pdf-string.js';
|
|
4
|
-
import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
5
|
-
import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
|
|
6
|
-
import { PdfBoolean } from '../core/objects/pdf-boolean.js';
|
|
7
|
-
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
8
|
-
import { PdfFontEncodingCache } from './PdfFontEncodingCache.js';
|
|
9
|
-
import { PdfAnnotationWriter } from '../annotations/PdfAnnotationWriter.js';
|
|
10
|
-
import { PdfXfaForm } from './xfa/PdfXfaForm.js';
|
|
11
|
-
import { PdfFormField } from './fields/PdfFormField.js';
|
|
12
|
-
// Import subclasses to trigger static registration blocks
|
|
13
|
-
import './fields/PdfTextFormField.js';
|
|
14
|
-
import './fields/PdfButtonFormField.js';
|
|
15
|
-
import './fields/PdfChoiceFormField.js';
|
|
16
|
-
import './fields/PdfSignatureFormField.js';
|
|
17
|
-
export class PdfAcroForm extends PdfIndirectObject {
|
|
18
|
-
fields;
|
|
19
|
-
_fontEncodingCache;
|
|
20
|
-
document;
|
|
21
|
-
constructor(options) {
|
|
22
|
-
super(options?.other ??
|
|
23
|
-
new PdfIndirectObject({
|
|
24
|
-
content: new PdfDictionary(),
|
|
25
|
-
}));
|
|
26
|
-
this.fields = options?.fields ?? [];
|
|
27
|
-
this.document = options?.document;
|
|
28
|
-
}
|
|
29
|
-
get fontEncodingCache() {
|
|
30
|
-
if (!this._fontEncodingCache) {
|
|
31
|
-
this._fontEncodingCache = new PdfFontEncodingCache(this.document, this.defaultResources);
|
|
32
|
-
}
|
|
33
|
-
return this._fontEncodingCache;
|
|
34
|
-
}
|
|
35
|
-
get fontEncodingMaps() {
|
|
36
|
-
return this.fontEncodingCache.fontEncodingMaps;
|
|
37
|
-
}
|
|
38
|
-
isModified() {
|
|
39
|
-
return this.content.isModified();
|
|
40
|
-
}
|
|
41
|
-
get needAppearances() {
|
|
42
|
-
return (this.content.get('NeedAppearances')?.as(PdfBoolean)?.value ?? false);
|
|
43
|
-
}
|
|
44
|
-
set needAppearances(value) {
|
|
45
|
-
this.content.set('NeedAppearances', new PdfBoolean(value));
|
|
46
|
-
}
|
|
47
|
-
get signatureFlags() {
|
|
48
|
-
return this.content.get('SigFlags')?.as(PdfNumber)?.value ?? 0;
|
|
49
|
-
}
|
|
50
|
-
set signatureFlags(flags) {
|
|
51
|
-
this.content.set('SigFlags', new PdfNumber(flags));
|
|
52
|
-
}
|
|
53
|
-
get defaultAppearance() {
|
|
54
|
-
return this.content.get('DA')?.as(PdfString)?.value ?? null;
|
|
55
|
-
}
|
|
56
|
-
set defaultAppearance(da) {
|
|
57
|
-
this.content.set('DA', new PdfString(da));
|
|
58
|
-
}
|
|
59
|
-
get defaultQuadding() {
|
|
60
|
-
return this.content.get('Q')?.as(PdfNumber)?.value ?? 0;
|
|
61
|
-
}
|
|
62
|
-
set defaultQuadding(q) {
|
|
63
|
-
this.content.set('Q', new PdfNumber(q));
|
|
64
|
-
}
|
|
65
|
-
get defaultResources() {
|
|
66
|
-
return this.content.get('DR')?.as(PdfDictionary) ?? null;
|
|
67
|
-
}
|
|
68
|
-
set defaultResources(resources) {
|
|
69
|
-
if (resources === null) {
|
|
70
|
-
this.content.delete('DR');
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
this.content.set('DR', resources);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
setValues(values) {
|
|
77
|
-
for (const field of this.fields) {
|
|
78
|
-
const name = field.name;
|
|
79
|
-
if (name in values && values[name] !== undefined) {
|
|
80
|
-
field.value = values[name];
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
importData(fields) {
|
|
85
|
-
for (const field of this.fields) {
|
|
86
|
-
const name = field.name;
|
|
87
|
-
if (name && name in fields) {
|
|
88
|
-
field.value = fields[name];
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
exportData() {
|
|
93
|
-
const result = {};
|
|
94
|
-
for (const field of this.fields) {
|
|
95
|
-
const name = field.name;
|
|
96
|
-
if (name) {
|
|
97
|
-
result[name] = field.value;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return result;
|
|
101
|
-
}
|
|
102
|
-
async getFontEncodingMap(fontName) {
|
|
103
|
-
return this.fontEncodingCache.getFontEncodingMap(fontName);
|
|
104
|
-
}
|
|
105
|
-
static async fromDocument(document) {
|
|
106
|
-
const catalog = document.root;
|
|
107
|
-
if (!catalog)
|
|
108
|
-
return null;
|
|
109
|
-
const acroFormRef = catalog.content.get('AcroForm');
|
|
110
|
-
if (!acroFormRef)
|
|
111
|
-
return null;
|
|
112
|
-
let acroFormDict;
|
|
113
|
-
let acroFormContainer;
|
|
114
|
-
if (acroFormRef instanceof PdfObjectReference) {
|
|
115
|
-
const acroFormObject = await document.readObject({
|
|
116
|
-
objectNumber: acroFormRef.objectNumber,
|
|
117
|
-
generationNumber: acroFormRef.generationNumber,
|
|
118
|
-
});
|
|
119
|
-
if (!acroFormObject)
|
|
120
|
-
return null;
|
|
121
|
-
if (!(acroFormObject.content instanceof PdfDictionary))
|
|
122
|
-
throw new Error('AcroForm content must be a dictionary');
|
|
123
|
-
acroFormDict = acroFormObject.content;
|
|
124
|
-
acroFormContainer = acroFormObject;
|
|
125
|
-
}
|
|
126
|
-
else if (acroFormRef instanceof PdfDictionary) {
|
|
127
|
-
acroFormDict = acroFormRef;
|
|
128
|
-
acroFormContainer = new PdfIndirectObject({ content: acroFormDict });
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
const acroForm = new PdfAcroForm({ other: acroFormContainer, document });
|
|
134
|
-
// Pre-cache font encoding maps for all fonts used in fields
|
|
135
|
-
await acroForm.cacheAllFontEncodings();
|
|
136
|
-
const fields = new Map();
|
|
137
|
-
const getFields = async (fieldRefs, parent) => {
|
|
138
|
-
for (const fieldRef of fieldRefs) {
|
|
139
|
-
const refKey = fieldRef.toString().trim();
|
|
140
|
-
if (fields.has(refKey)) {
|
|
141
|
-
fields.get(refKey).parent = parent;
|
|
142
|
-
continue;
|
|
143
|
-
}
|
|
144
|
-
const fieldObject = await document.readObject({
|
|
145
|
-
objectNumber: fieldRef.objectNumber,
|
|
146
|
-
generationNumber: fieldRef.generationNumber,
|
|
147
|
-
});
|
|
148
|
-
if (!fieldObject)
|
|
149
|
-
continue;
|
|
150
|
-
if (!(fieldObject.content instanceof PdfDictionary))
|
|
151
|
-
continue;
|
|
152
|
-
const field = PdfFormField.create({
|
|
153
|
-
other: fieldObject,
|
|
154
|
-
form: acroForm,
|
|
155
|
-
parent,
|
|
156
|
-
});
|
|
157
|
-
const kids = field.kids;
|
|
158
|
-
if (kids.length > 0) {
|
|
159
|
-
await getFields(kids, field);
|
|
160
|
-
}
|
|
161
|
-
acroForm.fields.push(field);
|
|
162
|
-
fields.set(refKey, field);
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
const fieldsArray = new PdfArray();
|
|
166
|
-
if (acroForm.content.get('Fields') instanceof PdfArray) {
|
|
167
|
-
fieldsArray.items.push(...acroForm.content
|
|
168
|
-
.get('Fields')
|
|
169
|
-
.as((PdfArray)).items);
|
|
170
|
-
}
|
|
171
|
-
else if (acroForm.content.get('Fields') instanceof PdfObjectReference) {
|
|
172
|
-
const fieldsObj = await document.readObject({
|
|
173
|
-
objectNumber: acroForm.content
|
|
174
|
-
.get('Fields')
|
|
175
|
-
.as(PdfObjectReference).objectNumber,
|
|
176
|
-
generationNumber: acroForm.content
|
|
177
|
-
.get('Fields')
|
|
178
|
-
.as(PdfObjectReference).generationNumber,
|
|
179
|
-
});
|
|
180
|
-
if (fieldsObj && fieldsObj.content instanceof PdfArray) {
|
|
181
|
-
fieldsArray.items.push(...fieldsObj.content.as((PdfArray)).items);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
await getFields(fieldsArray.items);
|
|
185
|
-
// Reset field-level modified flag so only explicitly changed fields are detected
|
|
186
|
-
for (const field of acroForm.fields) {
|
|
187
|
-
field.setModified(false);
|
|
188
|
-
}
|
|
189
|
-
return acroForm;
|
|
190
|
-
}
|
|
191
|
-
async cacheAllFontEncodings() {
|
|
192
|
-
await this.fontEncodingCache.cacheAllFontEncodings(this.fields);
|
|
193
|
-
}
|
|
194
|
-
async updatePageAnnotations(document, fieldsByPage) {
|
|
195
|
-
await PdfAnnotationWriter.updatePageAnnotations(document, fieldsByPage);
|
|
196
|
-
}
|
|
197
|
-
async write(document) {
|
|
198
|
-
const catalog = document.root;
|
|
199
|
-
const isIncremental = document.isIncremental();
|
|
200
|
-
document.setIncremental(true);
|
|
201
|
-
const xfaForm = await PdfXfaForm.fromDocument(document);
|
|
202
|
-
if (xfaForm) {
|
|
203
|
-
// Only send fields whose value was explicitly changed (field.isModified())
|
|
204
|
-
const xfaFields = this.fields
|
|
205
|
-
.filter((f) => f.isModified() && f.fieldType !== 'Signature' && f.name)
|
|
206
|
-
.map((f) => ({ name: f.name, value: f.value }));
|
|
207
|
-
if (xfaFields.length > 0) {
|
|
208
|
-
xfaForm.datasets?.updateFields(xfaFields);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
const fieldsArray = new PdfArray();
|
|
212
|
-
this.content.set('Fields', fieldsArray);
|
|
213
|
-
const fieldsByPage = new Map();
|
|
214
|
-
// Phase 1: add appearance streams standalone (PdfStream — cannot go in ObjStm)
|
|
215
|
-
// and collect field dicts for ObjStm batching.
|
|
216
|
-
const compressibleFields = [];
|
|
217
|
-
for (const field of this.fields) {
|
|
218
|
-
if (field.content.isModified()) {
|
|
219
|
-
const appearances = field.getAppearanceStreamsForWriting();
|
|
220
|
-
if (appearances) {
|
|
221
|
-
document.add(appearances.primary);
|
|
222
|
-
if (appearances.secondary) {
|
|
223
|
-
document.add(appearances.secondary);
|
|
224
|
-
}
|
|
225
|
-
field.setAppearanceReference(appearances.primary.reference, appearances.secondary?.reference);
|
|
226
|
-
if (!field.print) {
|
|
227
|
-
field.print = true;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
compressibleFields.push(field);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
// Phase 2: pack field dicts into ObjStm — pre-assigns their object numbers.
|
|
234
|
-
document.addObjectsAsStream(compressibleFields);
|
|
235
|
-
// Phase 3: build fieldsArray now that field object numbers are stable.
|
|
236
|
-
for (const field of this.fields) {
|
|
237
|
-
let fieldReference;
|
|
238
|
-
if (field.content.isModified()) {
|
|
239
|
-
fieldReference = new PdfObjectReference(field.objectNumber, field.generationNumber);
|
|
240
|
-
const parentRef = field.parentRef;
|
|
241
|
-
const isWidget = field.isWidget;
|
|
242
|
-
if (parentRef && isWidget) {
|
|
243
|
-
const pageKey = `${parentRef.objectNumber}_${parentRef.generationNumber}`;
|
|
244
|
-
if (!fieldsByPage.has(pageKey)) {
|
|
245
|
-
fieldsByPage.set(pageKey, {
|
|
246
|
-
pageRef: parentRef,
|
|
247
|
-
fieldRefs: [],
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
fieldsByPage.get(pageKey).fieldRefs.push(fieldReference);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
fieldReference = field.reference;
|
|
255
|
-
}
|
|
256
|
-
fieldsArray.push(fieldReference);
|
|
257
|
-
}
|
|
258
|
-
await this.updatePageAnnotations(document, fieldsByPage);
|
|
259
|
-
// Phase 4: pack AcroForm dict into ObjStm AFTER fieldsArray is populated,
|
|
260
|
-
// so the dict is serialized with the correct Fields array.
|
|
261
|
-
if (this.isModified()) {
|
|
262
|
-
document.addObjectsAsStream([this]);
|
|
263
|
-
if (!catalog.content.has('AcroForm')) {
|
|
264
|
-
let updatableCatalog = catalog;
|
|
265
|
-
if (catalog.isImmutable()) {
|
|
266
|
-
updatableCatalog = catalog.clone();
|
|
267
|
-
document.add(updatableCatalog);
|
|
268
|
-
}
|
|
269
|
-
updatableCatalog.content.set('AcroForm', this.reference);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
// XFA datasets stream — PdfXfaData extends PdfIndirectObject<PdfStream>, must stay standalone
|
|
273
|
-
if (xfaForm) {
|
|
274
|
-
xfaForm.write(document);
|
|
275
|
-
}
|
|
276
|
-
await document.commit();
|
|
277
|
-
document.setIncremental(isIncremental);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { PdfDocument } from '../pdf/pdf-document.js';
|
|
2
|
-
import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
|
|
3
|
-
import type { PdfDefaultResourcesDictionary } from './acroform.js';
|
|
4
|
-
/**
|
|
5
|
-
* Resolves and caches font encoding maps from the form's default resources.
|
|
6
|
-
*/
|
|
7
|
-
export declare class PdfFontEncodingCache {
|
|
8
|
-
readonly fontEncodingMaps: Map<string, Map<number, string>>;
|
|
9
|
-
private document?;
|
|
10
|
-
private defaultResources;
|
|
11
|
-
constructor(document: PdfDocument | undefined, defaultResources: PdfDefaultResourcesDictionary | null);
|
|
12
|
-
getFontEncodingMap(fontName: string): Promise<Map<number, string> | null>;
|
|
13
|
-
cacheAllFontEncodings(fields: Array<{
|
|
14
|
-
content: PdfDictionary;
|
|
15
|
-
}>): Promise<void>;
|
|
16
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
|
|
2
|
-
import { PdfArray } from '../core/objects/pdf-array.js';
|
|
3
|
-
import { PdfString } from '../core/objects/pdf-string.js';
|
|
4
|
-
import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
5
|
-
import { buildEncodingMap } from '../utils/decodeWithFontEncoding.js';
|
|
6
|
-
/**
|
|
7
|
-
* Resolves and caches font encoding maps from the form's default resources.
|
|
8
|
-
*/
|
|
9
|
-
export class PdfFontEncodingCache {
|
|
10
|
-
fontEncodingMaps = new Map();
|
|
11
|
-
document;
|
|
12
|
-
defaultResources;
|
|
13
|
-
constructor(document, defaultResources) {
|
|
14
|
-
this.document = document;
|
|
15
|
-
this.defaultResources = defaultResources;
|
|
16
|
-
}
|
|
17
|
-
async getFontEncodingMap(fontName) {
|
|
18
|
-
if (this.fontEncodingMaps.has(fontName)) {
|
|
19
|
-
return this.fontEncodingMaps.get(fontName);
|
|
20
|
-
}
|
|
21
|
-
const dr = this.defaultResources;
|
|
22
|
-
if (!dr)
|
|
23
|
-
return null;
|
|
24
|
-
const fonts = dr.get('Font')?.as(PdfDictionary);
|
|
25
|
-
if (!fonts)
|
|
26
|
-
return null;
|
|
27
|
-
const fontRef = fonts.get(fontName)?.as(PdfObjectReference);
|
|
28
|
-
if (!fontRef || !this.document)
|
|
29
|
-
return null;
|
|
30
|
-
const fontObj = await this.document.readObject({
|
|
31
|
-
objectNumber: fontRef.objectNumber,
|
|
32
|
-
generationNumber: fontRef.generationNumber,
|
|
33
|
-
});
|
|
34
|
-
if (!fontObj)
|
|
35
|
-
return null;
|
|
36
|
-
const fontDict = fontObj.content.as(PdfDictionary);
|
|
37
|
-
const encoding = fontDict.get('Encoding');
|
|
38
|
-
let encodingDict = null;
|
|
39
|
-
if (encoding instanceof PdfObjectReference) {
|
|
40
|
-
const encodingObj = await this.document.readObject({
|
|
41
|
-
objectNumber: encoding.objectNumber,
|
|
42
|
-
generationNumber: encoding.generationNumber,
|
|
43
|
-
});
|
|
44
|
-
encodingDict = encodingObj?.content.as(PdfDictionary) ?? null;
|
|
45
|
-
}
|
|
46
|
-
else if (encoding instanceof PdfDictionary) {
|
|
47
|
-
encodingDict = encoding;
|
|
48
|
-
}
|
|
49
|
-
if (!encodingDict)
|
|
50
|
-
return null;
|
|
51
|
-
const differences = encodingDict.get('Differences')?.as(PdfArray);
|
|
52
|
-
if (!differences)
|
|
53
|
-
return null;
|
|
54
|
-
const encodingMap = buildEncodingMap(differences);
|
|
55
|
-
if (!encodingMap)
|
|
56
|
-
return null;
|
|
57
|
-
this.fontEncodingMaps.set(fontName, encodingMap);
|
|
58
|
-
return encodingMap;
|
|
59
|
-
}
|
|
60
|
-
async cacheAllFontEncodings(fields) {
|
|
61
|
-
const fontNames = new Set();
|
|
62
|
-
for (const field of fields) {
|
|
63
|
-
const da = field.content.get('DA')?.as(PdfString)?.value;
|
|
64
|
-
if (da) {
|
|
65
|
-
const fontMatch = da.match(/\/(\w+)\s+[\d.]+\s+Tf/);
|
|
66
|
-
if (fontMatch) {
|
|
67
|
-
fontNames.add(fontMatch[1]);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
for (const fontName of fontNames) {
|
|
72
|
-
await this.getFontEncodingMap(fontName);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Backward-compatible re-export shim.
|
|
3
|
-
* All classes have been moved to dedicated modules.
|
|
4
|
-
*/
|
|
5
|
-
export { PdfFormField as PdfAcroFormField } from './fields/PdfFormField.js';
|
|
6
|
-
export { PdfAcroForm } from './PdfAcroForm.js';
|
|
7
|
-
export type { PdfDefaultResourcesDictionary } from './PdfAcroForm.js';
|
|
8
|
-
export { PdfFieldType } from './fields/types.js';
|
|
9
|
-
export type { PdfAppearanceStreamDictionary } from '../annotations/index.js';
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Backward-compatible re-export shim.
|
|
3
|
-
* All classes have been moved to dedicated modules.
|
|
4
|
-
*/
|
|
5
|
-
export { PdfFormField as PdfAcroFormField } from './fields/PdfFormField.js';
|
|
6
|
-
export { PdfAcroForm } from './PdfAcroForm.js';
|
|
7
|
-
export { PdfFieldType } from './fields/types.js';
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { PdfDictionary } from '../../core/objects/pdf-dictionary.js';
|
|
2
|
-
import { PdfName } from '../../core/objects/pdf-name.js';
|
|
3
|
-
import { PdfAppearanceStream } from './PdfAppearanceStream.js';
|
|
4
|
-
/**
|
|
5
|
-
* Appearance stream for button fields (checkboxes, radio buttons).
|
|
6
|
-
*/
|
|
7
|
-
export class PdfButtonAppearanceStream extends PdfAppearanceStream {
|
|
8
|
-
constructor(ctx) {
|
|
9
|
-
const resources = new PdfDictionary();
|
|
10
|
-
const fonts = new PdfDictionary();
|
|
11
|
-
const zapfFont = new PdfDictionary();
|
|
12
|
-
zapfFont.set('Type', new PdfName('Font'));
|
|
13
|
-
zapfFont.set('Subtype', new PdfName('Type1'));
|
|
14
|
-
zapfFont.set('BaseFont', new PdfName('ZapfDingbats'));
|
|
15
|
-
fonts.set('ZaDb', zapfFont);
|
|
16
|
-
resources.set('Font', fonts);
|
|
17
|
-
super({
|
|
18
|
-
width: ctx.width,
|
|
19
|
-
height: ctx.height,
|
|
20
|
-
contentStream: ctx.contentStream,
|
|
21
|
-
resources,
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
static buildYesContent(width, height, flags) {
|
|
25
|
-
const size = Math.min(width, height);
|
|
26
|
-
const isRadio = (flags & 32768) !== 0;
|
|
27
|
-
if (isRadio) {
|
|
28
|
-
const center = size / 2;
|
|
29
|
-
const radius = size * 0.35;
|
|
30
|
-
const k = 0.5522847498;
|
|
31
|
-
const kRadius = k * radius;
|
|
32
|
-
return `q
|
|
33
|
-
0 0 0 rg
|
|
34
|
-
${center} ${center + radius} m
|
|
35
|
-
${center + kRadius} ${center + radius} ${center + radius} ${center + kRadius} ${center + radius} ${center} c
|
|
36
|
-
${center + radius} ${center - kRadius} ${center + kRadius} ${center - radius} ${center} ${center - radius} c
|
|
37
|
-
${center - kRadius} ${center - radius} ${center - radius} ${center - kRadius} ${center - radius} ${center} c
|
|
38
|
-
${center - radius} ${center + kRadius} ${center - kRadius} ${center + radius} ${center} ${center + radius} c
|
|
39
|
-
f
|
|
40
|
-
Q
|
|
41
|
-
`;
|
|
42
|
-
}
|
|
43
|
-
const checkSize = size * 0.8;
|
|
44
|
-
const offset = (size - checkSize) / 2;
|
|
45
|
-
return `q
|
|
46
|
-
BT
|
|
47
|
-
/ZaDb ${checkSize} Tf
|
|
48
|
-
${offset} ${offset} Td
|
|
49
|
-
(4) Tj
|
|
50
|
-
ET
|
|
51
|
-
Q
|
|
52
|
-
`;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { PdfDefaultAppearance } from '../fields/PdfDefaultAppearance.js';
|
|
2
|
-
import { PdfAppearanceStream } from './PdfAppearanceStream.js';
|
|
3
|
-
import type { PdfDictionary } from '../../core/objects/pdf-dictionary.js';
|
|
4
|
-
/**
|
|
5
|
-
* Appearance stream for choice fields (dropdowns, list boxes).
|
|
6
|
-
*/
|
|
7
|
-
export declare class PdfChoiceAppearanceStream extends PdfAppearanceStream {
|
|
8
|
-
constructor(ctx: {
|
|
9
|
-
rect: [number, number, number, number];
|
|
10
|
-
value: string;
|
|
11
|
-
da: PdfDefaultAppearance;
|
|
12
|
-
flags: number;
|
|
13
|
-
fontResources?: PdfDictionary;
|
|
14
|
-
});
|
|
15
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { PdfAppearanceStream } from './PdfAppearanceStream.js';
|
|
2
|
-
/**
|
|
3
|
-
* Appearance stream for choice fields (dropdowns, list boxes).
|
|
4
|
-
*/
|
|
5
|
-
export class PdfChoiceAppearanceStream extends PdfAppearanceStream {
|
|
6
|
-
constructor(ctx) {
|
|
7
|
-
const [x1, y1, x2, y2] = ctx.rect;
|
|
8
|
-
const width = x2 - x1;
|
|
9
|
-
const height = y2 - y1;
|
|
10
|
-
const colorOp = '0 g';
|
|
11
|
-
const reconstructedDA = `/${ctx.da.fontName} ${ctx.da.fontSize} Tf ${colorOp}`;
|
|
12
|
-
const padding = 2;
|
|
13
|
-
const textY = (height - ctx.da.fontSize) / 2 + ctx.da.fontSize * 0.2;
|
|
14
|
-
const textX = padding;
|
|
15
|
-
const escapedValue = ctx.value
|
|
16
|
-
.replace(/\\/g, '\\\\')
|
|
17
|
-
.replace(/\(/g, '\\(')
|
|
18
|
-
.replace(/\)/g, '\\)');
|
|
19
|
-
const isCombo = (ctx.flags & 131072) !== 0;
|
|
20
|
-
let arrowGraphics = '';
|
|
21
|
-
if (isCombo) {
|
|
22
|
-
const arrowWidth = height * 0.8;
|
|
23
|
-
const arrowX = width - arrowWidth - 2;
|
|
24
|
-
const arrowY = height / 2;
|
|
25
|
-
const arrowSize = height * 0.3;
|
|
26
|
-
arrowGraphics = `
|
|
27
|
-
q
|
|
28
|
-
0.5 0.5 0.5 rg
|
|
29
|
-
${arrowX + arrowWidth / 2} ${arrowY - arrowSize / 3} m
|
|
30
|
-
${arrowX + arrowWidth / 2 - arrowSize / 2} ${arrowY + arrowSize / 3} l
|
|
31
|
-
${arrowX + arrowWidth / 2 + arrowSize / 2} ${arrowY + arrowSize / 3} l
|
|
32
|
-
f
|
|
33
|
-
Q
|
|
34
|
-
`;
|
|
35
|
-
}
|
|
36
|
-
const contentStream = `/Tx BMC
|
|
37
|
-
q
|
|
38
|
-
BT
|
|
39
|
-
${reconstructedDA}
|
|
40
|
-
${textX} ${textY} Td
|
|
41
|
-
(${escapedValue}) Tj
|
|
42
|
-
ET
|
|
43
|
-
${arrowGraphics}Q
|
|
44
|
-
EMC
|
|
45
|
-
`;
|
|
46
|
-
super({ width, height, contentStream, resources: ctx.fontResources });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { PdfAppearanceStream } from './PdfAppearanceStream.js';
|
|
2
|
-
/**
|
|
3
|
-
* Appearance stream for text fields (single-line, multiline, comb).
|
|
4
|
-
*/
|
|
5
|
-
export class PdfTextAppearanceStream extends PdfAppearanceStream {
|
|
6
|
-
constructor(ctx) {
|
|
7
|
-
const [x1, y1, x2, y2] = ctx.rect;
|
|
8
|
-
const width = x2 - x1;
|
|
9
|
-
const height = y2 - y1;
|
|
10
|
-
const value = ctx.value;
|
|
11
|
-
const reconstructedDA = ctx.da.toString();
|
|
12
|
-
const fontSize = ctx.da.fontSize;
|
|
13
|
-
const padding = 2;
|
|
14
|
-
const textY = (height - fontSize) / 2 + fontSize * 0.2;
|
|
15
|
-
const escapedValue = value
|
|
16
|
-
.replace(/\\/g, '\\\\')
|
|
17
|
-
.replace(/\(/g, '\\(')
|
|
18
|
-
.replace(/\)/g, '\\)')
|
|
19
|
-
.replace(/\r/g, '\\r')
|
|
20
|
-
.replace(/\n/g, '\\n');
|
|
21
|
-
let textContent;
|
|
22
|
-
if (ctx.multiline) {
|
|
23
|
-
const lines = value.split('\n');
|
|
24
|
-
const lineHeight = fontSize * 1.2;
|
|
25
|
-
const startY = height - padding - fontSize;
|
|
26
|
-
textContent = 'BT\n';
|
|
27
|
-
textContent += `${reconstructedDA}\n`;
|
|
28
|
-
textContent += `${padding} ${startY} Td\n`;
|
|
29
|
-
for (let i = 0; i < lines.length; i++) {
|
|
30
|
-
const line = lines[i]
|
|
31
|
-
.replace(/\\/g, '\\\\')
|
|
32
|
-
.replace(/\(/g, '\\(')
|
|
33
|
-
.replace(/\)/g, '\\)')
|
|
34
|
-
.replace(/\r/g, '');
|
|
35
|
-
if (i > 0) {
|
|
36
|
-
textContent += `0 ${-lineHeight} Td\n`;
|
|
37
|
-
}
|
|
38
|
-
textContent += `(${line}) Tj\n`;
|
|
39
|
-
}
|
|
40
|
-
textContent += 'ET\n';
|
|
41
|
-
}
|
|
42
|
-
else if (ctx.comb && ctx.maxLen) {
|
|
43
|
-
const cellWidth = width / ctx.maxLen;
|
|
44
|
-
const chars = value.split('');
|
|
45
|
-
textContent = 'BT\n';
|
|
46
|
-
textContent += `${reconstructedDA}\n`;
|
|
47
|
-
for (let i = 0; i < chars.length && i < ctx.maxLen; i++) {
|
|
48
|
-
const cellX = cellWidth * i + cellWidth / 2 - fontSize * 0.3;
|
|
49
|
-
const escapedChar = chars[i]
|
|
50
|
-
.replace(/\\/g, '\\\\')
|
|
51
|
-
.replace(/\(/g, '\\(')
|
|
52
|
-
.replace(/\)/g, '\\)');
|
|
53
|
-
textContent += `${cellX} ${textY} Td\n`;
|
|
54
|
-
textContent += `(${escapedChar}) Tj\n`;
|
|
55
|
-
textContent += `${-cellX} ${-textY} Td\n`;
|
|
56
|
-
}
|
|
57
|
-
textContent += 'ET\n';
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
const textX = padding;
|
|
61
|
-
textContent = `BT
|
|
62
|
-
${reconstructedDA}
|
|
63
|
-
${textX} ${textY} Td
|
|
64
|
-
(${escapedValue}) Tj
|
|
65
|
-
ET
|
|
66
|
-
`;
|
|
67
|
-
}
|
|
68
|
-
const contentStream = `/Tx BMC
|
|
69
|
-
q
|
|
70
|
-
${textContent}Q
|
|
71
|
-
EMC
|
|
72
|
-
`;
|
|
73
|
-
super({ width, height, contentStream, resources: ctx.fontResources });
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { PdfFormField } from './PdfFormField.js';
|
|
2
|
-
/**
|
|
3
|
-
* Button form field subtype (checkboxes, radio buttons, push buttons).
|
|
4
|
-
*/
|
|
5
|
-
export declare class PdfButtonFormField extends PdfFormField {
|
|
6
|
-
generateAppearance(options?: {
|
|
7
|
-
makeReadOnly?: boolean;
|
|
8
|
-
}): boolean;
|
|
9
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { PdfFormField } from './PdfFormField.js';
|
|
2
|
-
import { PdfButtonAppearanceStream } from '../appearance/PdfButtonAppearanceStream.js';
|
|
3
|
-
/**
|
|
4
|
-
* Button form field subtype (checkboxes, radio buttons, push buttons).
|
|
5
|
-
*/
|
|
6
|
-
export class PdfButtonFormField extends PdfFormField {
|
|
7
|
-
static {
|
|
8
|
-
PdfFormField.registerFieldType('Btn', PdfButtonFormField);
|
|
9
|
-
}
|
|
10
|
-
generateAppearance(options) {
|
|
11
|
-
const rect = this.rect;
|
|
12
|
-
if (!rect || rect.length !== 4)
|
|
13
|
-
return false;
|
|
14
|
-
const [x1, y1, x2, y2] = rect;
|
|
15
|
-
const width = x2 - x1;
|
|
16
|
-
const height = y2 - y1;
|
|
17
|
-
this._appearanceStream = new PdfButtonAppearanceStream({
|
|
18
|
-
width,
|
|
19
|
-
height,
|
|
20
|
-
contentStream: '',
|
|
21
|
-
});
|
|
22
|
-
const yesContent = PdfButtonAppearanceStream.buildYesContent(width, height, this.flags);
|
|
23
|
-
this._appearanceStreamYes = new PdfButtonAppearanceStream({
|
|
24
|
-
width,
|
|
25
|
-
height,
|
|
26
|
-
contentStream: yesContent,
|
|
27
|
-
});
|
|
28
|
-
if (options?.makeReadOnly) {
|
|
29
|
-
this.readOnly = true;
|
|
30
|
-
this.print = true;
|
|
31
|
-
this.noZoom = true;
|
|
32
|
-
}
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
}
|