pdf-lite 1.3.1 → 1.3.2
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/README.md +1 -1
- package/dist/acroform/acroform.js +72 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,10 +13,10 @@ PRs and issues are welcome!
|
|
|
13
13
|
|
|
14
14
|
## Features
|
|
15
15
|
|
|
16
|
-
- **Zero dependencies**: No external libraries are required, making it lightweight and easy to integrate.
|
|
17
16
|
- **Type-safe**: Built with TypeScript, ensuring type safety and reducing runtime errors.
|
|
18
17
|
- **Browser and Node.js support**: Works seamlessly in both environments, allowing for versatile usage.
|
|
19
18
|
- **Low-level API**: Provides a low-level API for advanced users who want to manipulate PDF files directly, as well as a higher-level API for easier usage.
|
|
19
|
+
- **Minimal dependencies**: A small number external libraries are required, making it lightweight and easy to integrate.
|
|
20
20
|
|
|
21
21
|
## Installation
|
|
22
22
|
|
|
@@ -44,7 +44,8 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
44
44
|
* Gets the field type
|
|
45
45
|
*/
|
|
46
46
|
get fieldType() {
|
|
47
|
-
const ft = this.content.get('FT')?.value
|
|
47
|
+
const ft = this.content.get('FT')?.value ??
|
|
48
|
+
this.parent?.content.get('FT')?.value;
|
|
48
49
|
switch (ft) {
|
|
49
50
|
case 'Tx':
|
|
50
51
|
return 'Text';
|
|
@@ -128,7 +129,7 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
128
129
|
* Gets the default value
|
|
129
130
|
*/
|
|
130
131
|
get defaultValue() {
|
|
131
|
-
const dv = this.content.get('DV');
|
|
132
|
+
const dv = this.content.get('DV') ?? this.parent?.content.get('DV');
|
|
132
133
|
if (dv instanceof PdfString) {
|
|
133
134
|
return dv.value;
|
|
134
135
|
}
|
|
@@ -150,7 +151,8 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
get value() {
|
|
153
|
-
|
|
154
|
+
// V may be on this field or inherited from parent (parent/kids split)
|
|
155
|
+
const v = this.content.get('V') ?? this.parent?.content.get('V');
|
|
154
156
|
if (v instanceof PdfString) {
|
|
155
157
|
// UTF-16BE strings should always use UTF-16BE decoding regardless of font encoding
|
|
156
158
|
if (v.isUTF16BE) {
|
|
@@ -170,19 +172,21 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
170
172
|
if (this.value === val) {
|
|
171
173
|
return;
|
|
172
174
|
}
|
|
175
|
+
// In a parent/kids split, V should be set on the parent field
|
|
176
|
+
const target = this.parent ?? this;
|
|
173
177
|
const fieldType = this.fieldType;
|
|
174
178
|
if (fieldType === 'Button') {
|
|
175
179
|
val = val instanceof PdfString ? val.value : val;
|
|
176
180
|
if (val.trim() === '') {
|
|
177
|
-
|
|
181
|
+
target.content.delete('V');
|
|
178
182
|
this.content.delete('AS');
|
|
179
183
|
return;
|
|
180
184
|
}
|
|
181
|
-
|
|
185
|
+
target.content.set('V', new PdfName(val));
|
|
182
186
|
this.content.set('AS', new PdfName(val));
|
|
183
187
|
}
|
|
184
188
|
else {
|
|
185
|
-
|
|
189
|
+
target.content.set('V', val instanceof PdfString ? val : new PdfString(val));
|
|
186
190
|
}
|
|
187
191
|
if (this.defaultGenerateAppearance) {
|
|
188
192
|
this.generateAppearance();
|
|
@@ -190,25 +194,26 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
190
194
|
}
|
|
191
195
|
get checked() {
|
|
192
196
|
if (this.fieldType === 'Button') {
|
|
193
|
-
const v = this.content.get('V');
|
|
197
|
+
const v = this.content.get('V') ?? this.parent?.content.get('V');
|
|
194
198
|
return v instanceof PdfName && v.value === 'Yes';
|
|
195
199
|
}
|
|
196
200
|
return false;
|
|
197
201
|
}
|
|
198
202
|
set checked(isChecked) {
|
|
199
203
|
if (this.fieldType === 'Button') {
|
|
204
|
+
const target = this.parent ?? this;
|
|
200
205
|
if (isChecked) {
|
|
201
|
-
|
|
206
|
+
target.content.set('V', new PdfName('Yes'));
|
|
202
207
|
this.content.set('AS', new PdfName('Yes'));
|
|
203
208
|
}
|
|
204
209
|
else {
|
|
205
|
-
|
|
210
|
+
target.content.set('V', new PdfName('Off'));
|
|
206
211
|
this.content.set('AS', new PdfName('Off'));
|
|
207
212
|
}
|
|
208
213
|
}
|
|
209
214
|
}
|
|
210
215
|
get fontSize() {
|
|
211
|
-
const da = this.
|
|
216
|
+
const da = this.defaultAppearance || '';
|
|
212
217
|
const match = da.match(/\/[A-Za-z0-9_-]+\s+([\d.]+)\s+Tf/);
|
|
213
218
|
if (match) {
|
|
214
219
|
return parseFloat(match[1]);
|
|
@@ -216,7 +221,7 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
216
221
|
return null;
|
|
217
222
|
}
|
|
218
223
|
set fontSize(size) {
|
|
219
|
-
const da = this.
|
|
224
|
+
const da = this.defaultAppearance || '';
|
|
220
225
|
if (!da) {
|
|
221
226
|
this.content.set('DA', new PdfString(`/F1 ${size} Tf 0 g`));
|
|
222
227
|
return;
|
|
@@ -225,7 +230,7 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
225
230
|
this.content.set('DA', new PdfString(updatedDa));
|
|
226
231
|
}
|
|
227
232
|
get fontName() {
|
|
228
|
-
const da = this.
|
|
233
|
+
const da = this.defaultAppearance || '';
|
|
229
234
|
const match = da.match(/\/([A-Za-z0-9_-]+)\s+[\d.]+\s+Tf/);
|
|
230
235
|
if (match) {
|
|
231
236
|
return match[1];
|
|
@@ -233,7 +238,7 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
233
238
|
return null;
|
|
234
239
|
}
|
|
235
240
|
set fontName(fontName) {
|
|
236
|
-
const da = this.
|
|
241
|
+
const da = this.defaultAppearance || '';
|
|
237
242
|
if (!da) {
|
|
238
243
|
this.content.set('DA', new PdfString(`/${fontName} 12 Tf 0 g`));
|
|
239
244
|
return;
|
|
@@ -253,7 +258,7 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
253
258
|
}
|
|
254
259
|
const resourceName = font.resourceName;
|
|
255
260
|
const currentSize = this.fontSize ?? 12;
|
|
256
|
-
const da = this.
|
|
261
|
+
const da = this.defaultAppearance || '';
|
|
257
262
|
if (!da) {
|
|
258
263
|
this.content.set('DA', new PdfString(`/${resourceName} ${currentSize} Tf 0 g`));
|
|
259
264
|
return;
|
|
@@ -265,7 +270,9 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
265
270
|
* Gets field flags (bitwise combination of field attributes)
|
|
266
271
|
*/
|
|
267
272
|
get flags() {
|
|
268
|
-
return this.content.get('Ff')?.as(PdfNumber)?.value ??
|
|
273
|
+
return (this.content.get('Ff')?.as(PdfNumber)?.value ??
|
|
274
|
+
this.parent?.content.get('Ff')?.as(PdfNumber)?.value ??
|
|
275
|
+
0);
|
|
269
276
|
}
|
|
270
277
|
/**
|
|
271
278
|
* Sets field flags
|
|
@@ -364,7 +371,9 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
364
371
|
* 0 = left-justified, 1 = centered, 2 = right-justified
|
|
365
372
|
*/
|
|
366
373
|
get quadding() {
|
|
367
|
-
return this.content.get('Q')?.as(PdfNumber)?.value ??
|
|
374
|
+
return (this.content.get('Q')?.as(PdfNumber)?.value ??
|
|
375
|
+
this.parent?.content.get('Q')?.as(PdfNumber)?.value ??
|
|
376
|
+
0);
|
|
368
377
|
}
|
|
369
378
|
/**
|
|
370
379
|
* Sets the quadding (text alignment) for this field.
|
|
@@ -378,7 +387,8 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
378
387
|
* Returns an array of option strings.
|
|
379
388
|
*/
|
|
380
389
|
get options() {
|
|
381
|
-
const opt = this.content.get('Opt')?.as((PdfArray))
|
|
390
|
+
const opt = this.content.get('Opt')?.as((PdfArray)) ??
|
|
391
|
+
this.parent?.content.get('Opt')?.as((PdfArray));
|
|
382
392
|
if (!opt)
|
|
383
393
|
return [];
|
|
384
394
|
return opt.items.map((item) => item.value);
|
|
@@ -396,7 +406,9 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
396
406
|
this.content.set('Opt', optArray);
|
|
397
407
|
}
|
|
398
408
|
get defaultAppearance() {
|
|
399
|
-
return this.content.get('DA')?.as(PdfString)?.value ??
|
|
409
|
+
return (this.content.get('DA')?.as(PdfString)?.value ??
|
|
410
|
+
this.parent?.content.get('DA')?.as(PdfString)?.value ??
|
|
411
|
+
null);
|
|
400
412
|
}
|
|
401
413
|
set defaultAppearance(da) {
|
|
402
414
|
this.content.set('DA', new PdfString(da));
|
|
@@ -747,8 +759,9 @@ export class PdfAcroFormField extends PdfIndirectObject {
|
|
|
747
759
|
const [x1, y1, x2, y2] = rect;
|
|
748
760
|
const width = x2 - x1;
|
|
749
761
|
const height = y2 - y1;
|
|
750
|
-
// Get the default appearance string
|
|
751
|
-
const da = this.content.get('DA')?.as(PdfString)?.value
|
|
762
|
+
// Get the default appearance string (may be inherited from parent)
|
|
763
|
+
const da = this.content.get('DA')?.as(PdfString)?.value ??
|
|
764
|
+
this.parent?.content.get('DA')?.as(PdfString)?.value;
|
|
752
765
|
if (!da)
|
|
753
766
|
return false;
|
|
754
767
|
// Get the field value
|
|
@@ -858,6 +871,25 @@ EMC
|
|
|
858
871
|
new PdfNumber(width),
|
|
859
872
|
new PdfNumber(height),
|
|
860
873
|
]));
|
|
874
|
+
// Add font resources so Acrobat can resolve the font name.
|
|
875
|
+
// Prefer the field's own DR (which has correctly resolved refs in incremental updates),
|
|
876
|
+
// then fall back to the AcroForm-level DR.
|
|
877
|
+
const fieldDR = this.content
|
|
878
|
+
.get('DR')
|
|
879
|
+
?.as(PdfDictionary);
|
|
880
|
+
const acroformDR = this.form?.defaultResources;
|
|
881
|
+
const fontSource = fieldDR?.get('Font')?.as(PdfDictionary) ??
|
|
882
|
+
acroformDR?.get('Font')?.as(PdfDictionary);
|
|
883
|
+
if (fontSource && fontName) {
|
|
884
|
+
const fontRef = fontSource.get(fontName);
|
|
885
|
+
if (fontRef) {
|
|
886
|
+
const resourceFontDict = new PdfDictionary();
|
|
887
|
+
resourceFontDict.set(fontName, fontRef);
|
|
888
|
+
const resourcesDict = new PdfDictionary();
|
|
889
|
+
resourcesDict.set('Font', resourceFontDict);
|
|
890
|
+
appearanceDict.set('Resources', resourcesDict);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
861
893
|
const stream = new PdfStream({
|
|
862
894
|
header: appearanceDict,
|
|
863
895
|
original: contentStream,
|
|
@@ -978,8 +1010,9 @@ Q
|
|
|
978
1010
|
const [x1, y1, x2, y2] = rect;
|
|
979
1011
|
const width = x2 - x1;
|
|
980
1012
|
const height = y2 - y1;
|
|
981
|
-
// Get the default appearance string
|
|
982
|
-
const da = this.content.get('DA')?.as(PdfString)?.value
|
|
1013
|
+
// Get the default appearance string (may be inherited from parent)
|
|
1014
|
+
const da = this.content.get('DA')?.as(PdfString)?.value ??
|
|
1015
|
+
this.parent?.content.get('DA')?.as(PdfString)?.value;
|
|
983
1016
|
if (!da)
|
|
984
1017
|
return false;
|
|
985
1018
|
const value = this.value;
|
|
@@ -1045,6 +1078,23 @@ EMC
|
|
|
1045
1078
|
new PdfNumber(width),
|
|
1046
1079
|
new PdfNumber(height),
|
|
1047
1080
|
]));
|
|
1081
|
+
// Add font resources so Acrobat can resolve the font name.
|
|
1082
|
+
const fieldDR = this.content
|
|
1083
|
+
.get('DR')
|
|
1084
|
+
?.as(PdfDictionary);
|
|
1085
|
+
const acroformDR = this.form?.defaultResources;
|
|
1086
|
+
const fontSource = fieldDR?.get('Font')?.as(PdfDictionary) ??
|
|
1087
|
+
acroformDR?.get('Font')?.as(PdfDictionary);
|
|
1088
|
+
if (fontSource && fontName) {
|
|
1089
|
+
const fontRef = fontSource.get(fontName);
|
|
1090
|
+
if (fontRef) {
|
|
1091
|
+
const resourceFontDict = new PdfDictionary();
|
|
1092
|
+
resourceFontDict.set(fontName, fontRef);
|
|
1093
|
+
const resourcesDict = new PdfDictionary();
|
|
1094
|
+
resourcesDict.set('Font', resourceFontDict);
|
|
1095
|
+
appearanceDict.set('Resources', resourcesDict);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1048
1098
|
const stream = new PdfStream({
|
|
1049
1099
|
header: appearanceDict,
|
|
1050
1100
|
original: contentStream,
|