pdf-lite 1.6.4 → 1.7.1
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/dist/acroform/appearance/pdf-button-appearance-stream.js +1 -1
- package/dist/acroform/appearance/pdf-graphics.d.ts +48 -0
- package/dist/acroform/appearance/pdf-graphics.js +177 -4
- package/dist/acroform/appearance/pdf-text-appearance-stream.d.ts +3 -0
- package/dist/acroform/appearance/pdf-text-appearance-stream.js +58 -29
- package/dist/acroform/fields/pdf-button-form-field.d.ts +11 -2
- package/dist/acroform/fields/pdf-button-form-field.js +76 -37
- package/dist/acroform/fields/pdf-choice-form-field.js +2 -2
- package/dist/acroform/fields/pdf-form-field.d.ts +39 -9
- package/dist/acroform/fields/pdf-form-field.js +234 -46
- package/dist/acroform/fields/pdf-text-form-field.js +23 -3
- package/dist/acroform/pdf-acro-form.d.ts +1 -0
- package/dist/acroform/pdf-acro-form.js +15 -4
- package/dist/acroform/xfa/pdf-xfa-data.d.ts +2 -1
- package/dist/acroform/xfa/pdf-xfa-data.js +36 -28
- package/dist/annotations/pdf-annotation.d.ts +1 -1
- package/dist/annotations/pdf-annotation.js +16 -2
- package/dist/core/objects/pdf-array.d.ts +6 -1
- package/dist/core/objects/pdf-array.js +3 -0
- package/dist/core/objects/pdf-boolean.d.ts +6 -2
- package/dist/core/objects/pdf-boolean.js +3 -0
- package/dist/core/objects/pdf-comment.d.ts +6 -2
- package/dist/core/objects/pdf-comment.js +3 -0
- package/dist/core/objects/pdf-date.d.ts +4 -0
- package/dist/core/objects/pdf-date.js +3 -0
- package/dist/core/objects/pdf-dictionary.d.ts +5 -0
- package/dist/core/objects/pdf-dictionary.js +16 -0
- package/dist/core/objects/pdf-hexadecimal.d.ts +6 -2
- package/dist/core/objects/pdf-hexadecimal.js +3 -0
- package/dist/core/objects/pdf-indirect-object.d.ts +8 -1
- package/dist/core/objects/pdf-indirect-object.js +14 -0
- package/dist/core/objects/pdf-name.d.ts +6 -2
- package/dist/core/objects/pdf-name.js +3 -0
- package/dist/core/objects/pdf-null.d.ts +5 -2
- package/dist/core/objects/pdf-null.js +3 -0
- package/dist/core/objects/pdf-number.d.ts +6 -1
- package/dist/core/objects/pdf-number.js +3 -0
- package/dist/core/objects/pdf-object-reference.d.ts +5 -0
- package/dist/core/objects/pdf-object-reference.js +7 -0
- package/dist/core/objects/pdf-object.d.ts +1 -0
- package/dist/core/objects/pdf-start-xref.d.ts +6 -1
- package/dist/core/objects/pdf-start-xref.js +3 -0
- package/dist/core/objects/pdf-stream.d.ts +8 -0
- package/dist/core/objects/pdf-stream.js +7 -0
- package/dist/core/objects/pdf-string.d.ts +8 -2
- package/dist/core/objects/pdf-string.js +9 -0
- package/dist/core/objects/pdf-trailer.d.ts +7 -0
- package/dist/core/objects/pdf-trailer.js +3 -0
- package/dist/core/objects/pdf-xref-table.d.ts +31 -5
- package/dist/core/objects/pdf-xref-table.js +23 -0
- package/dist/fonts/font-family.d.ts +12 -0
- package/dist/fonts/font-family.js +1 -0
- package/dist/fonts/index.d.ts +1 -0
- package/dist/fonts/index.js +1 -0
- package/dist/fonts/parsers/otf-parser.d.ts +2 -2
- package/dist/fonts/parsers/ttf-parser.d.ts +2 -2
- package/dist/fonts/parsers/woff-parser.d.ts +2 -0
- package/dist/fonts/parsers/woff-parser.js +6 -0
- package/dist/fonts/pdf-font.js +94 -8
- package/dist/fonts/types.d.ts +10 -0
- package/dist/pdf/pdf-document.d.ts +7 -0
- package/dist/pdf/pdf-document.js +6 -0
- package/dist/pdf/pdf-revision.d.ts +4 -0
- package/dist/pdf/pdf-revision.js +6 -0
- package/dist/utils/iterable-readable-stream.d.ts +2 -0
- package/dist/utils/iterable-readable-stream.js +8 -1
- package/dist/utils/parse-markdown-segments.d.ts +12 -0
- package/dist/utils/parse-markdown-segments.js +27 -0
- package/dist/utils/xml.d.ts +9 -0
- package/dist/utils/xml.js +59 -0
- package/package.json +2 -2
|
@@ -91,7 +91,7 @@ export class PdfChoiceFormField extends PdfFormField {
|
|
|
91
91
|
const fontResources = this.buildFontResources(parsed.fontName);
|
|
92
92
|
const isUnicode = font?.isUnicode ?? false;
|
|
93
93
|
const reverseEncodingMap = font?.reverseEncodingMap;
|
|
94
|
-
this.
|
|
94
|
+
this.appearanceStream = new PdfChoiceAppearanceStream({
|
|
95
95
|
rect: rect,
|
|
96
96
|
value,
|
|
97
97
|
da: parsed,
|
|
@@ -101,7 +101,7 @@ export class PdfChoiceFormField extends PdfFormField {
|
|
|
101
101
|
reverseEncodingMap,
|
|
102
102
|
displayOptions: this.options.map((opt) => opt.label),
|
|
103
103
|
selectedIndex: this.selectedIndex,
|
|
104
|
-
})
|
|
104
|
+
});
|
|
105
105
|
if (options?.makeReadOnly) {
|
|
106
106
|
this.readOnly = true;
|
|
107
107
|
this.print = true;
|
|
@@ -4,6 +4,7 @@ import { PdfString } from '../../core/objects/pdf-string.js';
|
|
|
4
4
|
import { PdfObjectReference } from '../../core/objects/pdf-object-reference.js';
|
|
5
5
|
import { PdfIndirectObject } from '../../core/objects/pdf-indirect-object.js';
|
|
6
6
|
import { PdfFont } from '../../fonts/pdf-font.js';
|
|
7
|
+
import type { FontFamily } from '../../fonts/font-family.js';
|
|
7
8
|
import { PdfStream } from '../../core/objects/pdf-stream.js';
|
|
8
9
|
import { PdfWidgetAnnotation } from '../../annotations/pdf-widget-annotation.js';
|
|
9
10
|
import type { PdfFieldType } from './types.js';
|
|
@@ -19,12 +20,16 @@ import { PdfJavaScriptAction } from '../js/pdf-javascript-action.js';
|
|
|
19
20
|
*/
|
|
20
21
|
export declare abstract class PdfFormField extends PdfWidgetAnnotation {
|
|
21
22
|
defaultGenerateAppearance: boolean;
|
|
23
|
+
/** Raw markdown string set by markdownValue; cleared by setRawValue. */
|
|
24
|
+
protected _markdownValue?: string;
|
|
25
|
+
private _fontFamily?;
|
|
22
26
|
/** @internal */
|
|
23
27
|
_form?: PdfAcroForm;
|
|
24
28
|
constructor(other?: PdfIndirectObject | {
|
|
25
29
|
form?: PdfAcroForm;
|
|
26
30
|
});
|
|
27
31
|
set form(f: PdfAcroForm);
|
|
32
|
+
static getFieldType(other: PdfIndirectObject): 'Btn' | 'Sig' | 'Tx' | 'Ch' | null;
|
|
28
33
|
static create(other?: PdfIndirectObject): PdfFormField;
|
|
29
34
|
get parent(): PdfFormField | undefined;
|
|
30
35
|
set parent(field: PdfFormField | PdfIndirectObject | undefined);
|
|
@@ -40,25 +45,43 @@ export declare abstract class PdfFormField extends PdfWidgetAnnotation {
|
|
|
40
45
|
* Returns undefined if neither source provides the font.
|
|
41
46
|
*/
|
|
42
47
|
buildFontResources(fontName: string): PdfDictionary | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Like buildFontResources but includes multiple font names (regular +
|
|
50
|
+
* variant fonts) in a single Resources/Font dictionary. Falls through to
|
|
51
|
+
* buildFontResources when only one name is provided.
|
|
52
|
+
*/
|
|
53
|
+
buildAllFontResources(fontNames: string[]): PdfDictionary | undefined;
|
|
43
54
|
get fieldType(): PdfFieldType | null;
|
|
44
55
|
set fieldType(type: PdfFieldType | null);
|
|
45
56
|
get name(): string;
|
|
46
57
|
set name(name: string);
|
|
47
58
|
get defaultValue(): string;
|
|
48
59
|
set defaultValue(val: string);
|
|
60
|
+
get onStates(): string[];
|
|
61
|
+
get onState(): string | null;
|
|
62
|
+
set onState(state: string);
|
|
49
63
|
get value(): string;
|
|
64
|
+
protected setRawValue(val: string | PdfString): void;
|
|
50
65
|
set value(val: string | PdfString);
|
|
51
|
-
|
|
52
|
-
* Writes the value to the dictionary. Returns true if appearance generation
|
|
53
|
-
* should proceed, false to skip it (e.g. when value was cleared).
|
|
54
|
-
* Override in subclasses to change the stored representation.
|
|
55
|
-
*/
|
|
56
|
-
protected _storeValue(val: string | PdfString, fieldParent: PdfFormField | undefined): boolean;
|
|
66
|
+
set markdownValue(val: string);
|
|
57
67
|
get fontSize(): number | null;
|
|
58
68
|
set fontSize(size: number);
|
|
59
69
|
get fontName(): string | null;
|
|
60
70
|
set fontName(fontName: string);
|
|
61
71
|
set font(font: PdfFont | null);
|
|
72
|
+
private _embedFontInDR;
|
|
73
|
+
get fontFamily(): FontFamily | null;
|
|
74
|
+
set fontFamily(family: FontFamily | null);
|
|
75
|
+
get fontVariantNames(): {
|
|
76
|
+
bold?: string;
|
|
77
|
+
italic?: string;
|
|
78
|
+
boldItalic?: string;
|
|
79
|
+
};
|
|
80
|
+
protected get resolvedVariantFonts(): {
|
|
81
|
+
bold?: PdfFont;
|
|
82
|
+
italic?: PdfFont;
|
|
83
|
+
boldItalic?: PdfFont;
|
|
84
|
+
};
|
|
62
85
|
get flags(): PdfFormFieldFlags;
|
|
63
86
|
set flags(v: PdfFormFieldFlags);
|
|
64
87
|
get readOnly(): boolean;
|
|
@@ -108,16 +131,23 @@ export declare abstract class PdfFormField extends PdfWidgetAnnotation {
|
|
|
108
131
|
abstract generateAppearance(options?: {
|
|
109
132
|
makeReadOnly?: boolean;
|
|
110
133
|
textYOffset?: number;
|
|
134
|
+
onStateName?: string;
|
|
111
135
|
}): boolean;
|
|
112
|
-
|
|
136
|
+
set appearanceStream(stream: PdfIndirectObject | {
|
|
113
137
|
[key: string]: PdfIndirectObject;
|
|
114
|
-
})
|
|
138
|
+
});
|
|
139
|
+
set downAppearanceStream(stream: PdfIndirectObject | {
|
|
140
|
+
[key: string]: PdfIndirectObject;
|
|
141
|
+
});
|
|
142
|
+
get appearanceState(): string | null;
|
|
143
|
+
set appearanceState(state: string | null);
|
|
115
144
|
/**
|
|
116
145
|
* Returns the list of appearance state names from the normal appearance
|
|
117
146
|
* dictionary (e.g. ["Yes", "Off"] for a checkbox).
|
|
118
147
|
*/
|
|
119
|
-
get appearanceStates(): string
|
|
148
|
+
get appearanceStates(): ReadonlyArray<string>;
|
|
120
149
|
getAppearanceStream(setting?: string): PdfIndirectObject<PdfStream> | null;
|
|
150
|
+
hasAppearanceStream(setting: string): boolean;
|
|
121
151
|
private static _fallbackCtor?;
|
|
122
152
|
private static _registry;
|
|
123
153
|
static registerFieldType(ft: 'Sig' | 'Btn' | 'Tx' | 'Ch', ctor: new (other?: PdfIndirectObject) => PdfFormField, options?: {
|
|
@@ -14,6 +14,7 @@ import { PdfFieldType as PdfFieldTypeConst } from './types.js';
|
|
|
14
14
|
import { PdfFormFieldFlags } from './pdf-form-field-flags.js';
|
|
15
15
|
import { PdfFieldActions } from '../js/pdf-field-actions.js';
|
|
16
16
|
import { PdfJavaScriptAction } from '../js/pdf-javascript-action.js';
|
|
17
|
+
import { parseMarkdownSegments } from '../../utils/parse-markdown-segments.js';
|
|
17
18
|
/**
|
|
18
19
|
* Abstract base form field class. Extends PdfWidgetAnnotation with form-specific properties:
|
|
19
20
|
* FT, V, DA, Ff, T (name), field hierarchy (parent/children/siblings).
|
|
@@ -21,6 +22,9 @@ import { PdfJavaScriptAction } from '../js/pdf-javascript-action.js';
|
|
|
21
22
|
*/
|
|
22
23
|
export class PdfFormField extends PdfWidgetAnnotation {
|
|
23
24
|
defaultGenerateAppearance = true;
|
|
25
|
+
/** Raw markdown string set by markdownValue; cleared by setRawValue. */
|
|
26
|
+
_markdownValue;
|
|
27
|
+
_fontFamily;
|
|
24
28
|
/** @internal */
|
|
25
29
|
_form;
|
|
26
30
|
constructor(other) {
|
|
@@ -32,10 +36,25 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
32
36
|
set form(f) {
|
|
33
37
|
this._form = f;
|
|
34
38
|
}
|
|
39
|
+
static getFieldType(other) {
|
|
40
|
+
if (!(other.content instanceof PdfDictionary))
|
|
41
|
+
return null;
|
|
42
|
+
const ft = other.content.get('FT')?.as(PdfName)?.value;
|
|
43
|
+
if (ft)
|
|
44
|
+
return ft;
|
|
45
|
+
const parentRef = other.content.get('Parent');
|
|
46
|
+
if (parentRef instanceof PdfObjectReference) {
|
|
47
|
+
const parentResolved = parentRef.resolve();
|
|
48
|
+
if (parentResolved?.content instanceof PdfDictionary) {
|
|
49
|
+
return (parentResolved.content.get('FT')?.as(PdfName)?.value ?? null);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
35
54
|
static create(other) {
|
|
36
55
|
if (!(other?.content instanceof PdfDictionary))
|
|
37
56
|
throw new Error('Invalid form field object');
|
|
38
|
-
const ft =
|
|
57
|
+
const ft = PdfFormField.getFieldType(other);
|
|
39
58
|
const cls = ft ? PdfFormField._registry.get(ft) : undefined;
|
|
40
59
|
if (!cls) {
|
|
41
60
|
if (PdfFormField._fallbackCtor) {
|
|
@@ -60,14 +79,23 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
60
79
|
if (field instanceof PdfFormField) {
|
|
61
80
|
field.children = [...field.children, this];
|
|
62
81
|
}
|
|
82
|
+
// Auto-add widget to page's Annots array
|
|
83
|
+
const page = this.page;
|
|
84
|
+
if (page) {
|
|
85
|
+
const annots = page.annotations;
|
|
86
|
+
const ref = this.reference;
|
|
87
|
+
const key = ref.key;
|
|
88
|
+
const alreadyPresent = annots.items.some((r) => r instanceof PdfObjectReference && r.key === key);
|
|
89
|
+
if (!alreadyPresent) {
|
|
90
|
+
annots.items.push(ref);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
63
93
|
}
|
|
64
94
|
get children() {
|
|
65
95
|
const kids = this.content.get('Kids')?.items ?? [];
|
|
66
96
|
const result = [];
|
|
67
97
|
for (const ref of kids) {
|
|
68
98
|
const resolved = ref.resolve();
|
|
69
|
-
if (!resolved || !(resolved.content instanceof PdfDictionary))
|
|
70
|
-
continue;
|
|
71
99
|
result.push(PdfFormField.create(resolved));
|
|
72
100
|
}
|
|
73
101
|
return result;
|
|
@@ -156,9 +184,41 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
156
184
|
}
|
|
157
185
|
return undefined;
|
|
158
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Like buildFontResources but includes multiple font names (regular +
|
|
189
|
+
* variant fonts) in a single Resources/Font dictionary. Falls through to
|
|
190
|
+
* buildFontResources when only one name is provided.
|
|
191
|
+
*/
|
|
192
|
+
buildAllFontResources(fontNames) {
|
|
193
|
+
if (fontNames.length <= 1)
|
|
194
|
+
return this.buildFontResources(fontNames[0]);
|
|
195
|
+
const dr = this.defaultResources;
|
|
196
|
+
const fontRaw = dr?.get('Font');
|
|
197
|
+
let drFontDict;
|
|
198
|
+
if (fontRaw instanceof PdfObjectReference) {
|
|
199
|
+
const resolved = fontRaw.resolve()?.content;
|
|
200
|
+
if (resolved instanceof PdfDictionary)
|
|
201
|
+
drFontDict = resolved;
|
|
202
|
+
}
|
|
203
|
+
else if (fontRaw instanceof PdfDictionary) {
|
|
204
|
+
drFontDict = fontRaw;
|
|
205
|
+
}
|
|
206
|
+
const resFontDict = new PdfDictionary();
|
|
207
|
+
for (const name of fontNames) {
|
|
208
|
+
if (drFontDict?.get(name)) {
|
|
209
|
+
resFontDict.set(name, drFontDict.get(name));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (resFontDict.keys().length > 0) {
|
|
213
|
+
const resources = new PdfDictionary();
|
|
214
|
+
resources.set('Font', resFontDict);
|
|
215
|
+
return resources;
|
|
216
|
+
}
|
|
217
|
+
// Fallback to single-font path for the primary font name
|
|
218
|
+
return this.buildFontResources(fontNames[0]);
|
|
219
|
+
}
|
|
159
220
|
get fieldType() {
|
|
160
|
-
const ft =
|
|
161
|
-
this.parent?.content.get('FT')?.as(PdfName)?.value;
|
|
221
|
+
const ft = PdfFormField.getFieldType(this);
|
|
162
222
|
switch (ft) {
|
|
163
223
|
case 'Tx':
|
|
164
224
|
return 'Text';
|
|
@@ -202,6 +262,27 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
202
262
|
set defaultValue(val) {
|
|
203
263
|
this.content.set('DV', new PdfString(val));
|
|
204
264
|
}
|
|
265
|
+
get onStates() {
|
|
266
|
+
return this.appearanceStates.filter((s) => s !== 'Off');
|
|
267
|
+
}
|
|
268
|
+
get onState() {
|
|
269
|
+
return this.appearanceStates.find((s) => s !== 'Off') || null;
|
|
270
|
+
}
|
|
271
|
+
set onState(state) {
|
|
272
|
+
if (!this.appearanceStates.includes(state)) {
|
|
273
|
+
const currentOnState = this.onState;
|
|
274
|
+
if (currentOnState) {
|
|
275
|
+
this.appearanceStreamDict
|
|
276
|
+
?.get('N')
|
|
277
|
+
?.as(PdfDictionary)
|
|
278
|
+
?.move(currentOnState, state);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
// No existing on-state; generate a new appearance stream for the new state
|
|
282
|
+
this.generateAppearance({ onStateName: state });
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
205
286
|
get value() {
|
|
206
287
|
const v = this.content.get('V') ?? this.parent?.content.get('V');
|
|
207
288
|
if (v instanceof PdfString) {
|
|
@@ -221,48 +302,67 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
221
302
|
}
|
|
222
303
|
return '';
|
|
223
304
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
sibling.generateAppearance();
|
|
238
|
-
}
|
|
305
|
+
setRawValue(val) {
|
|
306
|
+
this._markdownValue = undefined;
|
|
307
|
+
const targets = [this];
|
|
308
|
+
const parent = this.parent;
|
|
309
|
+
if (parent?.fieldType) {
|
|
310
|
+
targets.push(parent);
|
|
311
|
+
}
|
|
312
|
+
const pdfVal = val instanceof PdfString ? val : new PdfString(val);
|
|
313
|
+
const isEmpty = pdfVal.length === 0;
|
|
314
|
+
for (const target of targets) {
|
|
315
|
+
if (isEmpty) {
|
|
316
|
+
target.content.delete('V');
|
|
317
|
+
target.appearanceState = null;
|
|
239
318
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if (!this.rect) {
|
|
243
|
-
for (const child of this.children) {
|
|
244
|
-
if (child.rect && child.defaultGenerateAppearance) {
|
|
245
|
-
if (this._form)
|
|
246
|
-
child.form = this._form;
|
|
247
|
-
child.generateAppearance();
|
|
248
|
-
}
|
|
249
|
-
}
|
|
319
|
+
else {
|
|
320
|
+
target.content.set('V', pdfVal);
|
|
250
321
|
}
|
|
251
322
|
}
|
|
252
|
-
if (
|
|
253
|
-
this._form
|
|
323
|
+
if (isEmpty) {
|
|
324
|
+
this._form?.xfa?.datasets?.updateField(this.name, '');
|
|
254
325
|
}
|
|
326
|
+
if (this.defaultGenerateAppearance) {
|
|
327
|
+
this.generateAppearance();
|
|
328
|
+
}
|
|
329
|
+
for (const sibling of this.siblings) {
|
|
330
|
+
if (sibling !== this && sibling.defaultGenerateAppearance) {
|
|
331
|
+
sibling.generateAppearance();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// Separated field/widget structure: field has no Rect but its Kids
|
|
335
|
+
// are widget annotations that do. Clear stale V entries on children
|
|
336
|
+
// so they inherit the parent's value, then generate appearances.
|
|
337
|
+
for (const child of this.children) {
|
|
338
|
+
if (child.content.has('V')) {
|
|
339
|
+
child.content.delete('V');
|
|
340
|
+
}
|
|
341
|
+
if (child.defaultGenerateAppearance) {
|
|
342
|
+
if (this._form)
|
|
343
|
+
child.form = this._form;
|
|
344
|
+
child.generateAppearance();
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
this._form?.xfa?.datasets?.updateField(this.name, this.value);
|
|
255
348
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
349
|
+
set value(val) {
|
|
350
|
+
this.setRawValue(val);
|
|
351
|
+
}
|
|
352
|
+
set markdownValue(val) {
|
|
353
|
+
const plainText = parseMarkdownSegments(val)
|
|
354
|
+
.map((s) => s.text)
|
|
355
|
+
.join('');
|
|
356
|
+
// Store plain text as V without triggering appearance generation yet
|
|
357
|
+
const saved = this.defaultGenerateAppearance;
|
|
358
|
+
this.defaultGenerateAppearance = false;
|
|
359
|
+
this.setRawValue(plainText);
|
|
360
|
+
this.defaultGenerateAppearance = saved;
|
|
361
|
+
// setRawValue cleared _markdownValue; store the markdown string now
|
|
362
|
+
this._markdownValue = val;
|
|
363
|
+
if (this.defaultGenerateAppearance) {
|
|
364
|
+
this.generateAppearance();
|
|
365
|
+
}
|
|
266
366
|
}
|
|
267
367
|
get fontSize() {
|
|
268
368
|
const da = this.defaultAppearance || '';
|
|
@@ -305,6 +405,8 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
305
405
|
}
|
|
306
406
|
const resourceName = font.resourceName;
|
|
307
407
|
const currentSize = this.fontSize ?? 12;
|
|
408
|
+
this._embedFontInDR(font);
|
|
409
|
+
// Update the DA string to use the font
|
|
308
410
|
const da = this.defaultAppearance || '';
|
|
309
411
|
if (!da) {
|
|
310
412
|
this.content.set('DA', new PdfDefaultAppearance(resourceName, currentSize, '0 g'));
|
|
@@ -316,6 +418,62 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
316
418
|
this.content.set('DA', parsed);
|
|
317
419
|
}
|
|
318
420
|
}
|
|
421
|
+
_embedFontInDR(font) {
|
|
422
|
+
const resourceName = font.resourceName;
|
|
423
|
+
// Add font to field's default resources
|
|
424
|
+
const dr = this.content.get('DR') || new PdfDictionary();
|
|
425
|
+
let fontDict = dr.get('Font');
|
|
426
|
+
if (!fontDict) {
|
|
427
|
+
fontDict = new PdfDictionary();
|
|
428
|
+
dr.set('Font', fontDict);
|
|
429
|
+
}
|
|
430
|
+
fontDict.set(resourceName, font.reference);
|
|
431
|
+
this.content.set('DR', dr);
|
|
432
|
+
// Also add to form's default resources if available
|
|
433
|
+
if (this._form) {
|
|
434
|
+
const formDr = this._form.defaultResources ||
|
|
435
|
+
new PdfDictionary();
|
|
436
|
+
let formFontDict = formDr.get('Font');
|
|
437
|
+
if (!formFontDict) {
|
|
438
|
+
formFontDict = new PdfDictionary();
|
|
439
|
+
formDr.set('Font', formFontDict);
|
|
440
|
+
}
|
|
441
|
+
formFontDict.set(resourceName, font.reference);
|
|
442
|
+
this._form.defaultResources = formDr;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
get fontFamily() {
|
|
446
|
+
return this._fontFamily ?? null;
|
|
447
|
+
}
|
|
448
|
+
set fontFamily(family) {
|
|
449
|
+
if (family === null) {
|
|
450
|
+
this._fontFamily = undefined;
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
this._fontFamily = family;
|
|
454
|
+
// Setting regular via the existing setter keeps DA string in sync
|
|
455
|
+
this.font = family.regular;
|
|
456
|
+
if (family.bold)
|
|
457
|
+
this._embedFontInDR(family.bold);
|
|
458
|
+
if (family.italic)
|
|
459
|
+
this._embedFontInDR(family.italic);
|
|
460
|
+
if (family.boldItalic)
|
|
461
|
+
this._embedFontInDR(family.boldItalic);
|
|
462
|
+
}
|
|
463
|
+
get fontVariantNames() {
|
|
464
|
+
return {
|
|
465
|
+
bold: this._fontFamily?.bold?.resourceName,
|
|
466
|
+
italic: this._fontFamily?.italic?.resourceName,
|
|
467
|
+
boldItalic: this._fontFamily?.boldItalic?.resourceName,
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
get resolvedVariantFonts() {
|
|
471
|
+
return {
|
|
472
|
+
bold: this._fontFamily?.bold,
|
|
473
|
+
italic: this._fontFamily?.italic,
|
|
474
|
+
boldItalic: this._fontFamily?.boldItalic,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
319
477
|
get flags() {
|
|
320
478
|
const flags = new PdfFormFieldFlags(this.content.get('Ff') ?? this.parent?.content.get('Ff') ?? 0);
|
|
321
479
|
flags.onChange(() => {
|
|
@@ -499,7 +657,7 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
499
657
|
engine: this._form?.jsEngine,
|
|
500
658
|
});
|
|
501
659
|
}
|
|
502
|
-
|
|
660
|
+
set appearanceStream(stream) {
|
|
503
661
|
this.appearanceStreamDict ||= new PdfDictionary();
|
|
504
662
|
if (stream instanceof PdfIndirectObject) {
|
|
505
663
|
this.appearanceStreamDict.set('N', stream.reference);
|
|
@@ -512,6 +670,35 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
512
670
|
this.appearanceStreamDict.set('N', dict);
|
|
513
671
|
}
|
|
514
672
|
}
|
|
673
|
+
set downAppearanceStream(stream) {
|
|
674
|
+
this.appearanceStreamDict ||= new PdfDictionary();
|
|
675
|
+
if (stream instanceof PdfIndirectObject) {
|
|
676
|
+
this.appearanceStreamDict.set('D', stream.reference);
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
const dict = new PdfDictionary();
|
|
680
|
+
for (const key in stream) {
|
|
681
|
+
dict.set(key, stream[key].reference);
|
|
682
|
+
}
|
|
683
|
+
this.appearanceStreamDict.set('D', dict);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
get appearanceState() {
|
|
687
|
+
return this.content.get('AS')?.as(PdfName)?.value ?? null;
|
|
688
|
+
}
|
|
689
|
+
set appearanceState(state) {
|
|
690
|
+
if (state === null) {
|
|
691
|
+
this.content.delete('AS');
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
this.content.set('AS', new PdfName(state));
|
|
696
|
+
}
|
|
697
|
+
if (this.defaultGenerateAppearance &&
|
|
698
|
+
!this.hasAppearanceStream(state)) {
|
|
699
|
+
this.generateAppearance();
|
|
700
|
+
}
|
|
701
|
+
}
|
|
515
702
|
/**
|
|
516
703
|
* Returns the list of appearance state names from the normal appearance
|
|
517
704
|
* dictionary (e.g. ["Yes", "Off"] for a checkbox).
|
|
@@ -534,9 +721,7 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
534
721
|
}
|
|
535
722
|
}
|
|
536
723
|
else if (n instanceof PdfDictionary) {
|
|
537
|
-
const key = setting ??
|
|
538
|
-
this.content.get('AS')?.as(PdfName)?.value ??
|
|
539
|
-
undefined;
|
|
724
|
+
const key = setting ?? this.appearanceState ?? undefined;
|
|
540
725
|
if (key) {
|
|
541
726
|
const entry = n.get(key);
|
|
542
727
|
if (entry instanceof PdfObjectReference) {
|
|
@@ -549,6 +734,9 @@ export class PdfFormField extends PdfWidgetAnnotation {
|
|
|
549
734
|
}
|
|
550
735
|
return null;
|
|
551
736
|
}
|
|
737
|
+
hasAppearanceStream(setting) {
|
|
738
|
+
return this.appearanceStates.includes(setting);
|
|
739
|
+
}
|
|
552
740
|
static _fallbackCtor;
|
|
553
741
|
static _registry = new Map();
|
|
554
742
|
static registerFieldType(ft, ctor, options) {
|
|
@@ -21,10 +21,27 @@ export class PdfTextFormField extends PdfFormField {
|
|
|
21
21
|
if (!parsed)
|
|
22
22
|
return false;
|
|
23
23
|
const font = this.font;
|
|
24
|
-
const
|
|
24
|
+
const variantNames = this.fontVariantNames;
|
|
25
|
+
const variantFonts = this.resolvedVariantFonts;
|
|
26
|
+
const allFontNames = [
|
|
27
|
+
parsed.fontName,
|
|
28
|
+
variantNames.bold,
|
|
29
|
+
variantNames.italic,
|
|
30
|
+
variantNames.boldItalic,
|
|
31
|
+
].filter((n) => !!n);
|
|
32
|
+
const fontResources = this.buildAllFontResources(allFontNames);
|
|
33
|
+
const resolvedFonts = new Map();
|
|
34
|
+
if (font)
|
|
35
|
+
resolvedFonts.set(parsed.fontName, font);
|
|
36
|
+
if (variantFonts.bold)
|
|
37
|
+
resolvedFonts.set(variantNames.bold, variantFonts.bold);
|
|
38
|
+
if (variantFonts.italic)
|
|
39
|
+
resolvedFonts.set(variantNames.italic, variantFonts.italic);
|
|
40
|
+
if (variantFonts.boldItalic)
|
|
41
|
+
resolvedFonts.set(variantNames.boldItalic, variantFonts.boldItalic);
|
|
25
42
|
const isUnicode = font?.isUnicode ?? false;
|
|
26
43
|
const reverseEncodingMap = font?.reverseEncodingMap;
|
|
27
|
-
this.
|
|
44
|
+
this.appearanceStream = new PdfTextAppearanceStream({
|
|
28
45
|
rect: rect,
|
|
29
46
|
value: this.value,
|
|
30
47
|
da: parsed,
|
|
@@ -32,9 +49,12 @@ export class PdfTextFormField extends PdfFormField {
|
|
|
32
49
|
comb: this.comb,
|
|
33
50
|
maxLen: this.maxLen,
|
|
34
51
|
fontResources,
|
|
52
|
+
resolvedFonts,
|
|
35
53
|
isUnicode,
|
|
36
54
|
reverseEncodingMap,
|
|
37
|
-
|
|
55
|
+
markdown: this._markdownValue,
|
|
56
|
+
fontVariantNames: variantNames,
|
|
57
|
+
});
|
|
38
58
|
if (options?.makeReadOnly) {
|
|
39
59
|
this.readOnly = true;
|
|
40
60
|
if (!this.print)
|
|
@@ -36,6 +36,7 @@ export declare class PdfAcroForm<T extends Record<string, string> = Record<strin
|
|
|
36
36
|
set defaultResources(resources: PdfDefaultResourcesDictionary | null);
|
|
37
37
|
get fields(): ReadonlyArray<PdfFormField>;
|
|
38
38
|
addField(...fields: PdfFormField[]): void;
|
|
39
|
+
private _addWidgetToPage;
|
|
39
40
|
set fields(newFields: PdfFormField[]);
|
|
40
41
|
setValues(values: Partial<T>): void;
|
|
41
42
|
importData(fields: T): void;
|
|
@@ -108,13 +108,24 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
108
108
|
}
|
|
109
109
|
for (const field of fields) {
|
|
110
110
|
fieldsArray.items.push(field.reference);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
this._addWidgetToPage(field);
|
|
112
|
+
// Also register any child widgets (e.g. radio button group kids)
|
|
113
|
+
for (const child of field.children) {
|
|
114
|
+
this._addWidgetToPage(child);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
+
_addWidgetToPage(field) {
|
|
119
|
+
const page = field.page;
|
|
120
|
+
if (!page)
|
|
121
|
+
return;
|
|
122
|
+
const ref = field.reference;
|
|
123
|
+
const key = ref.key;
|
|
124
|
+
const alreadyPresent = page.annotations.items.some((r) => r instanceof PdfObjectReference && r.key === key);
|
|
125
|
+
if (!alreadyPresent) {
|
|
126
|
+
page.annotations.items.push(ref);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
118
129
|
set fields(newFields) {
|
|
119
130
|
this.content.set('Fields', PdfArray.refs(newFields));
|
|
120
131
|
}
|
|
@@ -17,5 +17,6 @@ export declare class PdfXfaData extends PdfIndirectObject<PdfStream> {
|
|
|
17
17
|
getFieldValue(name: string): string | null;
|
|
18
18
|
importData(fields: Record<string, string | undefined>): void;
|
|
19
19
|
private static updateFieldValue;
|
|
20
|
-
private static
|
|
20
|
+
private static leafName;
|
|
21
|
+
private static cleanSegments;
|
|
21
22
|
}
|