pdf-lite 1.4.0 → 1.5.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/dist/acroform/acroform.d.ts +3 -3
- package/dist/acroform/acroform.js +2 -2
- 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 +54 -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 +23 -0
- package/dist/acroform/fields/pdf-button-form-field.js +102 -0
- package/dist/acroform/fields/pdf-choice-form-field.d.ts +18 -0
- package/dist/acroform/fields/pdf-choice-form-field.js +131 -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} +15 -11
- package/dist/acroform/fields/{PdfFormField.js → pdf-form-field.js} +68 -134
- 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/pdf-text-form-field.js +77 -0
- package/dist/acroform/fields/types.d.ts +5 -0
- package/dist/acroform/index.d.ts +2 -2
- package/dist/acroform/index.js +2 -2
- package/dist/acroform/manager.d.ts +7 -3
- package/dist/acroform/manager.js +14 -8
- package/dist/acroform/{PdfAcroForm.d.ts → pdf-acro-form.d.ts} +12 -6
- package/dist/acroform/{PdfAcroForm.js → pdf-acro-form.js} +43 -29
- package/dist/acroform/{PdfFontEncodingCache.d.ts → pdf-font-encoding-cache.d.ts} +11 -0
- package/dist/acroform/pdf-font-encoding-cache.js +188 -0
- package/dist/acroform/xfa/index.d.ts +3 -3
- package/dist/acroform/xfa/index.js +2 -2
- package/dist/acroform/xfa/{PdfXfaForm.d.ts → pdf-xfa-form.d.ts} +1 -2
- package/dist/acroform/xfa/{PdfXfaForm.js → pdf-xfa-form.js} +2 -10
- package/dist/annotations/index.d.ts +4 -4
- package/dist/annotations/index.js +4 -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} +25 -4
- package/dist/annotations/{PdfAnnotation.js → pdf-annotation.js} +4 -3
- 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/objects/pdf-stream.d.ts +1 -0
- package/dist/core/objects/pdf-stream.js +6 -2
- package/dist/core/parser/incremental-parser.d.ts +0 -13
- package/dist/core/parser/incremental-parser.js +1 -18
- package/dist/core/streams/object-stream.d.ts +1 -1
- package/dist/core/streams/object-stream.js +1 -1
- package/dist/errors.d.ts +22 -0
- package/dist/errors.js +24 -0
- package/dist/fonts/index.d.ts +1 -1
- package/dist/fonts/index.js +1 -1
- package/dist/fonts/pdf-font.d.ts +64 -7
- package/dist/fonts/pdf-font.js +188 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/pdf/index.d.ts +0 -1
- package/dist/pdf/index.js +0 -1
- package/dist/pdf/pdf-document.d.ts +2 -1
- package/dist/pdf/pdf-document.js +15 -11
- package/dist/utils/encodePdfText.d.ts +17 -0
- package/dist/utils/encodePdfText.js +61 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/package.json +1 -1
- package/dist/acroform/PdfFontEncodingCache.js +0 -75
- 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/PdfTextFormField.js +0 -52
- package/dist/pdf/errors.d.ts +0 -6
- package/dist/pdf/errors.js +0 -6
- /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/acroform/xfa/{PdfXfaData.d.ts → pdf-xfa-data.d.ts} +0 -0
- /package/dist/acroform/xfa/{PdfXfaData.js → pdf-xfa-data.js} +0 -0
- /package/dist/annotations/{PdfAnnotationWriter.d.ts → pdf-annotation-writer.d.ts} +0 -0
- /package/dist/annotations/{PdfAnnotationWriter.js → pdf-annotation-writer.js} +0 -0
- /package/dist/fonts/{font-manager.d.ts → manager.d.ts} +0 -0
- /package/dist/fonts/{font-manager.js → manager.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
|
@@ -5,19 +5,20 @@ import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
|
5
5
|
import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
|
|
6
6
|
import { PdfBoolean } from '../core/objects/pdf-boolean.js';
|
|
7
7
|
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
8
|
-
import { PdfFontEncodingCache } from './
|
|
9
|
-
import { PdfAnnotationWriter } from '../annotations/
|
|
10
|
-
import { PdfXfaForm } from './xfa/
|
|
11
|
-
import { PdfFormField } from './fields/
|
|
8
|
+
import { PdfFontEncodingCache } from './pdf-font-encoding-cache.js';
|
|
9
|
+
import { PdfAnnotationWriter } from '../annotations/pdf-annotation-writer.js';
|
|
10
|
+
import { PdfXfaForm } from './xfa/pdf-xfa-form.js';
|
|
11
|
+
import { PdfFormField } from './fields/pdf-form-field.js';
|
|
12
12
|
// Import subclasses to trigger static registration blocks
|
|
13
|
-
import './fields/
|
|
14
|
-
import './fields/
|
|
15
|
-
import './fields/
|
|
16
|
-
import './fields/
|
|
13
|
+
import './fields/pdf-text-form-field.js';
|
|
14
|
+
import './fields/pdf-button-form-field.js';
|
|
15
|
+
import './fields/pdf-choice-form-field.js';
|
|
16
|
+
import './fields/pdf-signature-form-field.js';
|
|
17
17
|
export class PdfAcroForm extends PdfIndirectObject {
|
|
18
18
|
fields;
|
|
19
19
|
_fontEncodingCache;
|
|
20
20
|
document;
|
|
21
|
+
_xfa; // undefined = not set; null = explicitly no XFA
|
|
21
22
|
constructor(options) {
|
|
22
23
|
super(options?.other ??
|
|
23
24
|
new PdfIndirectObject({
|
|
@@ -35,6 +36,12 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
35
36
|
get fontEncodingMaps() {
|
|
36
37
|
return this.fontEncodingCache.fontEncodingMaps;
|
|
37
38
|
}
|
|
39
|
+
get fontRefs() {
|
|
40
|
+
return this.fontEncodingCache.fontRefs;
|
|
41
|
+
}
|
|
42
|
+
setXfa(xfa) {
|
|
43
|
+
this._xfa = xfa;
|
|
44
|
+
}
|
|
38
45
|
isModified() {
|
|
39
46
|
return this.content.isModified();
|
|
40
47
|
}
|
|
@@ -102,6 +109,9 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
102
109
|
async getFontEncodingMap(fontName) {
|
|
103
110
|
return this.fontEncodingCache.getFontEncodingMap(fontName);
|
|
104
111
|
}
|
|
112
|
+
isFontUnicode(fontName) {
|
|
113
|
+
return this.fontEncodingCache.isFontUnicode(fontName);
|
|
114
|
+
}
|
|
105
115
|
static async fromDocument(document) {
|
|
106
116
|
const catalog = document.root;
|
|
107
117
|
if (!catalog)
|
|
@@ -112,10 +122,7 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
112
122
|
let acroFormDict;
|
|
113
123
|
let acroFormContainer;
|
|
114
124
|
if (acroFormRef instanceof PdfObjectReference) {
|
|
115
|
-
const acroFormObject = await document.readObject(
|
|
116
|
-
objectNumber: acroFormRef.objectNumber,
|
|
117
|
-
generationNumber: acroFormRef.generationNumber,
|
|
118
|
-
});
|
|
125
|
+
const acroFormObject = await document.readObject(acroFormRef);
|
|
119
126
|
if (!acroFormObject)
|
|
120
127
|
return null;
|
|
121
128
|
if (!(acroFormObject.content instanceof PdfDictionary))
|
|
@@ -131,8 +138,6 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
131
138
|
return null;
|
|
132
139
|
}
|
|
133
140
|
const acroForm = new PdfAcroForm({ other: acroFormContainer, document });
|
|
134
|
-
// Pre-cache font encoding maps for all fonts used in fields
|
|
135
|
-
await acroForm.cacheAllFontEncodings();
|
|
136
141
|
const fields = new Map();
|
|
137
142
|
const getFields = async (fieldRefs, parent) => {
|
|
138
143
|
for (const fieldRef of fieldRefs) {
|
|
@@ -141,10 +146,7 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
141
146
|
fields.get(refKey).parent = parent;
|
|
142
147
|
continue;
|
|
143
148
|
}
|
|
144
|
-
const fieldObject = await document.readObject(
|
|
145
|
-
objectNumber: fieldRef.objectNumber,
|
|
146
|
-
generationNumber: fieldRef.generationNumber,
|
|
147
|
-
});
|
|
149
|
+
const fieldObject = await document.readObject(fieldRef);
|
|
148
150
|
if (!fieldObject)
|
|
149
151
|
continue;
|
|
150
152
|
if (!(fieldObject.content instanceof PdfDictionary))
|
|
@@ -169,19 +171,14 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
169
171
|
.as((PdfArray)).items);
|
|
170
172
|
}
|
|
171
173
|
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
|
-
});
|
|
174
|
+
const fieldsObj = await document.readObject(acroForm.content.get('Fields').as(PdfObjectReference));
|
|
180
175
|
if (fieldsObj && fieldsObj.content instanceof PdfArray) {
|
|
181
176
|
fieldsArray.items.push(...fieldsObj.content.as((PdfArray)).items);
|
|
182
177
|
}
|
|
183
178
|
}
|
|
184
179
|
await getFields(fieldsArray.items);
|
|
180
|
+
// Pre-cache font encoding maps now that this.fields is populated
|
|
181
|
+
await acroForm.cacheAllFontEncodings();
|
|
185
182
|
// Reset field-level modified flag so only explicitly changed fields are detected
|
|
186
183
|
for (const field of acroForm.fields) {
|
|
187
184
|
field.setModified(false);
|
|
@@ -194,11 +191,28 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
194
191
|
async updatePageAnnotations(document, fieldsByPage) {
|
|
195
192
|
await PdfAnnotationWriter.updatePageAnnotations(document, fieldsByPage);
|
|
196
193
|
}
|
|
194
|
+
async getXfa(document) {
|
|
195
|
+
if (this._xfa) {
|
|
196
|
+
return this._xfa;
|
|
197
|
+
}
|
|
198
|
+
const doc = document || this.document;
|
|
199
|
+
if (!doc) {
|
|
200
|
+
throw new Error('No document available to load XFA form. Provide a document or ensure this AcroForm is associated with a document.');
|
|
201
|
+
}
|
|
202
|
+
this._xfa = await PdfXfaForm.fromDocument(doc);
|
|
203
|
+
return this._xfa;
|
|
204
|
+
}
|
|
197
205
|
async write(document) {
|
|
206
|
+
document ||= this.document;
|
|
207
|
+
if (!document) {
|
|
208
|
+
throw new Error('No document associated with this AcroForm');
|
|
209
|
+
}
|
|
198
210
|
const catalog = document.root;
|
|
199
211
|
const isIncremental = document.isIncremental();
|
|
200
212
|
document.setIncremental(true);
|
|
201
|
-
const xfaForm =
|
|
213
|
+
const xfaForm = this._xfa !== undefined
|
|
214
|
+
? this._xfa
|
|
215
|
+
: await PdfXfaForm.fromDocument(document);
|
|
202
216
|
if (xfaForm) {
|
|
203
217
|
// Only send fields whose value was explicitly changed (field.isModified())
|
|
204
218
|
const xfaFields = this.fields
|
|
@@ -270,8 +284,8 @@ export class PdfAcroForm extends PdfIndirectObject {
|
|
|
270
284
|
}
|
|
271
285
|
}
|
|
272
286
|
// XFA datasets stream — PdfXfaData extends PdfIndirectObject<PdfStream>, must stay standalone
|
|
273
|
-
if (xfaForm) {
|
|
274
|
-
xfaForm.
|
|
287
|
+
if (xfaForm?.datasets?.isModified()) {
|
|
288
|
+
document.add(xfaForm.datasets);
|
|
275
289
|
}
|
|
276
290
|
await document.commit();
|
|
277
291
|
document.setIncremental(isIncremental);
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { PdfDocument } from '../pdf/pdf-document.js';
|
|
2
2
|
import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
|
|
3
|
+
import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
3
4
|
import type { PdfDefaultResourcesDictionary } from './acroform.js';
|
|
4
5
|
/**
|
|
5
6
|
* Resolves and caches font encoding maps from the form's default resources.
|
|
6
7
|
*/
|
|
7
8
|
export declare class PdfFontEncodingCache {
|
|
8
9
|
readonly fontEncodingMaps: Map<string, Map<number, string>>;
|
|
10
|
+
readonly fontTypes: Map<string, string>;
|
|
11
|
+
/** Object references for all resolved fonts, keyed by resource name. */
|
|
12
|
+
readonly fontRefs: Map<string, PdfObjectReference>;
|
|
9
13
|
private document?;
|
|
10
14
|
private defaultResources;
|
|
11
15
|
constructor(document: PdfDocument | undefined, defaultResources: PdfDefaultResourcesDictionary | null);
|
|
@@ -13,4 +17,11 @@ export declare class PdfFontEncodingCache {
|
|
|
13
17
|
cacheAllFontEncodings(fields: Array<{
|
|
14
18
|
content: PdfDictionary;
|
|
15
19
|
}>): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Walks the page-tree (page → parent → … → Pages root), looking for the
|
|
22
|
+
* font in each node's /Resources/Font dict. Stops as soon as it finds the
|
|
23
|
+
* font. PDF resource inheritance means any ancestor can supply the font.
|
|
24
|
+
*/
|
|
25
|
+
private resolveFontFromPage;
|
|
26
|
+
isFontUnicode(fontName: string): boolean;
|
|
16
27
|
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
|
|
2
|
+
import { PdfArray } from '../core/objects/pdf-array.js';
|
|
3
|
+
import { PdfName } from '../core/objects/pdf-name.js';
|
|
4
|
+
import { PdfString } from '../core/objects/pdf-string.js';
|
|
5
|
+
import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
6
|
+
import { buildEncodingMap } from '../utils/decodeWithFontEncoding.js';
|
|
7
|
+
/**
|
|
8
|
+
* Resolves and caches font encoding maps from the form's default resources.
|
|
9
|
+
*/
|
|
10
|
+
export class PdfFontEncodingCache {
|
|
11
|
+
fontEncodingMaps = new Map();
|
|
12
|
+
fontTypes = new Map();
|
|
13
|
+
/** Object references for all resolved fonts, keyed by resource name. */
|
|
14
|
+
fontRefs = new Map();
|
|
15
|
+
document;
|
|
16
|
+
defaultResources;
|
|
17
|
+
constructor(document, defaultResources) {
|
|
18
|
+
this.document = document;
|
|
19
|
+
this.defaultResources = defaultResources;
|
|
20
|
+
}
|
|
21
|
+
async getFontEncodingMap(fontName) {
|
|
22
|
+
if (this.fontEncodingMaps.has(fontName)) {
|
|
23
|
+
return this.fontEncodingMaps.get(fontName);
|
|
24
|
+
}
|
|
25
|
+
const dr = this.defaultResources;
|
|
26
|
+
if (!dr)
|
|
27
|
+
return null;
|
|
28
|
+
const fontDictEntry = dr.get('Font');
|
|
29
|
+
const fonts = fontDictEntry instanceof PdfDictionary ? fontDictEntry : null;
|
|
30
|
+
if (!fonts)
|
|
31
|
+
return null;
|
|
32
|
+
const fontEntry = fonts.get(fontName);
|
|
33
|
+
const fontRef = fontEntry instanceof PdfObjectReference ? fontEntry : null;
|
|
34
|
+
if (!fontRef)
|
|
35
|
+
return null;
|
|
36
|
+
this.fontRefs.set(fontName, fontRef);
|
|
37
|
+
const fontObj = await this.document?.readObject(fontRef);
|
|
38
|
+
if (!fontObj)
|
|
39
|
+
return null;
|
|
40
|
+
const fontDict = fontObj.content instanceof PdfDictionary ? fontObj.content : null;
|
|
41
|
+
if (!fontDict)
|
|
42
|
+
return null;
|
|
43
|
+
// Cache font subtype (Type0, TrueType, Type1, etc.)
|
|
44
|
+
const subtypeEntry = fontDict.get('Subtype');
|
|
45
|
+
const subtype = subtypeEntry instanceof PdfName ? subtypeEntry.value : undefined;
|
|
46
|
+
if (subtype) {
|
|
47
|
+
this.fontTypes.set(fontName, subtype);
|
|
48
|
+
}
|
|
49
|
+
const encoding = fontDict.get('Encoding');
|
|
50
|
+
let encodingDict = null;
|
|
51
|
+
if (encoding instanceof PdfObjectReference) {
|
|
52
|
+
const encodingObj = await this.document?.readObject(encoding);
|
|
53
|
+
encodingDict =
|
|
54
|
+
encodingObj?.content instanceof PdfDictionary
|
|
55
|
+
? encodingObj.content
|
|
56
|
+
: null;
|
|
57
|
+
}
|
|
58
|
+
else if (encoding instanceof PdfDictionary) {
|
|
59
|
+
encodingDict = encoding;
|
|
60
|
+
}
|
|
61
|
+
if (!encodingDict)
|
|
62
|
+
return null;
|
|
63
|
+
const differences = encodingDict.get('Differences')?.as(PdfArray);
|
|
64
|
+
if (!differences)
|
|
65
|
+
return null;
|
|
66
|
+
const encodingMap = buildEncodingMap(differences);
|
|
67
|
+
if (!encodingMap)
|
|
68
|
+
return null;
|
|
69
|
+
this.fontEncodingMaps.set(fontName, encodingMap);
|
|
70
|
+
return encodingMap;
|
|
71
|
+
}
|
|
72
|
+
async cacheAllFontEncodings(fields) {
|
|
73
|
+
// Collect font names with an associated page ref for the first field
|
|
74
|
+
// that uses them (needed to fall back to page resources).
|
|
75
|
+
const fontPageRefs = new Map();
|
|
76
|
+
for (const field of fields) {
|
|
77
|
+
const daEntry = field.content.get('DA');
|
|
78
|
+
const da = daEntry instanceof PdfString ? daEntry.value : undefined;
|
|
79
|
+
if (da) {
|
|
80
|
+
const fontMatch = da.match(/\/(\w+)\s+[\d.]+\s+Tf/);
|
|
81
|
+
if (fontMatch) {
|
|
82
|
+
const fontName = fontMatch[1];
|
|
83
|
+
if (!fontPageRefs.has(fontName)) {
|
|
84
|
+
const pageEntry = field.content.get('P');
|
|
85
|
+
const pageRef = pageEntry instanceof PdfObjectReference
|
|
86
|
+
? pageEntry
|
|
87
|
+
: null;
|
|
88
|
+
fontPageRefs.set(fontName, pageRef);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
for (const [fontName, pageRef] of fontPageRefs) {
|
|
94
|
+
await this.getFontEncodingMap(fontName);
|
|
95
|
+
// If the font was not in the AcroForm DR, try the field's page resources
|
|
96
|
+
if (!this.fontRefs.has(fontName) && pageRef) {
|
|
97
|
+
await this.resolveFontFromPage(fontName, pageRef);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Walks the page-tree (page → parent → … → Pages root), looking for the
|
|
103
|
+
* font in each node's /Resources/Font dict. Stops as soon as it finds the
|
|
104
|
+
* font. PDF resource inheritance means any ancestor can supply the font.
|
|
105
|
+
*/
|
|
106
|
+
async resolveFontFromPage(fontName, pageRef) {
|
|
107
|
+
if (!this.document)
|
|
108
|
+
return;
|
|
109
|
+
// Walk up the parent chain (max 16 levels to avoid infinite loops)
|
|
110
|
+
let currentRef = pageRef;
|
|
111
|
+
for (let depth = 0; depth < 16 && currentRef; depth++) {
|
|
112
|
+
const nodeObj = await this.document.readObject({
|
|
113
|
+
objectNumber: currentRef.objectNumber,
|
|
114
|
+
generationNumber: currentRef.generationNumber,
|
|
115
|
+
});
|
|
116
|
+
const nodeDict = nodeObj?.content instanceof PdfDictionary
|
|
117
|
+
? nodeObj.content
|
|
118
|
+
: null;
|
|
119
|
+
if (!nodeDict)
|
|
120
|
+
break;
|
|
121
|
+
// Try Resources.Font in this node
|
|
122
|
+
const resourcesEntry = nodeDict.get('Resources');
|
|
123
|
+
const resources = resourcesEntry instanceof PdfDictionary ? resourcesEntry : null;
|
|
124
|
+
if (resources) {
|
|
125
|
+
const fontsEntry = resources.get('Font');
|
|
126
|
+
const fonts = fontsEntry instanceof PdfDictionary ? fontsEntry : null;
|
|
127
|
+
if (fonts) {
|
|
128
|
+
const fontEntry = fonts.get(fontName);
|
|
129
|
+
const fontRef = fontEntry instanceof PdfObjectReference
|
|
130
|
+
? fontEntry
|
|
131
|
+
: null;
|
|
132
|
+
if (fontRef) {
|
|
133
|
+
// Found — cache and finish
|
|
134
|
+
currentRef = fontRef;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Walk to parent
|
|
140
|
+
const parentEntry = nodeDict.get('Parent');
|
|
141
|
+
currentRef =
|
|
142
|
+
parentEntry instanceof PdfObjectReference ? parentEntry : null;
|
|
143
|
+
}
|
|
144
|
+
const fontRef = currentRef;
|
|
145
|
+
if (!fontRef)
|
|
146
|
+
return;
|
|
147
|
+
this.fontRefs.set(fontName, fontRef);
|
|
148
|
+
const fontObj = await this.document.readObject({
|
|
149
|
+
objectNumber: fontRef.objectNumber,
|
|
150
|
+
generationNumber: fontRef.generationNumber,
|
|
151
|
+
});
|
|
152
|
+
const fontDict = fontObj?.content instanceof PdfDictionary ? fontObj.content : null;
|
|
153
|
+
if (!fontDict)
|
|
154
|
+
return;
|
|
155
|
+
const subtypeEntry = fontDict.get('Subtype');
|
|
156
|
+
const subtype = subtypeEntry instanceof PdfName ? subtypeEntry.value : undefined;
|
|
157
|
+
if (subtype)
|
|
158
|
+
this.fontTypes.set(fontName, subtype);
|
|
159
|
+
// Also resolve encoding map if present
|
|
160
|
+
const encoding = fontDict.get('Encoding');
|
|
161
|
+
let encodingDict = null;
|
|
162
|
+
if (encoding instanceof PdfObjectReference) {
|
|
163
|
+
const encodingObj = await this.document.readObject({
|
|
164
|
+
objectNumber: encoding.objectNumber,
|
|
165
|
+
generationNumber: encoding.generationNumber,
|
|
166
|
+
});
|
|
167
|
+
encodingDict =
|
|
168
|
+
encodingObj?.content instanceof PdfDictionary
|
|
169
|
+
? encodingObj.content
|
|
170
|
+
: null;
|
|
171
|
+
}
|
|
172
|
+
else if (encoding instanceof PdfDictionary) {
|
|
173
|
+
encodingDict = encoding;
|
|
174
|
+
}
|
|
175
|
+
if (!encodingDict)
|
|
176
|
+
return;
|
|
177
|
+
const differencesEntry = encodingDict.get('Differences');
|
|
178
|
+
if (!(differencesEntry instanceof PdfArray))
|
|
179
|
+
return;
|
|
180
|
+
const encodingMap = buildEncodingMap(differencesEntry);
|
|
181
|
+
if (encodingMap) {
|
|
182
|
+
this.fontEncodingMaps.set(fontName, encodingMap);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
isFontUnicode(fontName) {
|
|
186
|
+
return this.fontTypes.get(fontName) === 'Type0';
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { PdfXfaForm } from './
|
|
2
|
-
export { PdfXfaData } from './
|
|
3
|
-
export type { XfaFieldData } from './
|
|
1
|
+
export { PdfXfaForm } from './pdf-xfa-form.js';
|
|
2
|
+
export { PdfXfaData } from './pdf-xfa-data.js';
|
|
3
|
+
export type { XfaFieldData } from './pdf-xfa-data.js';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { PdfXfaForm } from './
|
|
2
|
-
export { PdfXfaData } from './
|
|
1
|
+
export { PdfXfaForm } from './pdf-xfa-form.js';
|
|
2
|
+
export { PdfXfaData } from './pdf-xfa-data.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PdfDocument } from '../../pdf/pdf-document.js';
|
|
2
2
|
import { PdfArray } from '../../core/objects/pdf-array.js';
|
|
3
|
-
import { PdfXfaData } from './
|
|
3
|
+
import { PdfXfaData } from './pdf-xfa-data.js';
|
|
4
4
|
/**
|
|
5
5
|
* Typed wrapper around the XFA name/stream-ref array.
|
|
6
6
|
* Holds eagerly-loaded references to component streams like datasets.
|
|
@@ -8,5 +8,4 @@ import { PdfXfaData } from './PdfXfaData.js';
|
|
|
8
8
|
export declare class PdfXfaForm extends PdfArray {
|
|
9
9
|
datasets: PdfXfaData | null;
|
|
10
10
|
static fromDocument(document: PdfDocument): Promise<PdfXfaForm | null>;
|
|
11
|
-
write(document: PdfDocument): void;
|
|
12
11
|
}
|
|
@@ -3,7 +3,7 @@ import { PdfDictionary } from '../../core/objects/pdf-dictionary.js';
|
|
|
3
3
|
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
|
-
import { PdfXfaData } from './
|
|
6
|
+
import { PdfXfaData } from './pdf-xfa-data.js';
|
|
7
7
|
/**
|
|
8
8
|
* Typed wrapper around the XFA name/stream-ref array.
|
|
9
9
|
* Holds eagerly-loaded references to component streams like datasets.
|
|
@@ -17,10 +17,7 @@ export class PdfXfaForm extends PdfArray {
|
|
|
17
17
|
return null;
|
|
18
18
|
let acroFormDict;
|
|
19
19
|
if (acroFormRef instanceof PdfObjectReference) {
|
|
20
|
-
const acroFormObject = await document.readObject(
|
|
21
|
-
objectNumber: acroFormRef.objectNumber,
|
|
22
|
-
generationNumber: acroFormRef.generationNumber,
|
|
23
|
-
});
|
|
20
|
+
const acroFormObject = await document.readObject(acroFormRef);
|
|
24
21
|
if (!acroFormObject)
|
|
25
22
|
return null;
|
|
26
23
|
acroFormDict = acroFormObject.content.as(PdfDictionary);
|
|
@@ -56,9 +53,4 @@ export class PdfXfaForm extends PdfArray {
|
|
|
56
53
|
}
|
|
57
54
|
return form;
|
|
58
55
|
}
|
|
59
|
-
write(document) {
|
|
60
|
-
if (this.datasets?.isModified()) {
|
|
61
|
-
document.add(this.datasets);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
56
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { PdfAnnotation, type PdfAppearanceStreamDictionary, } from './
|
|
2
|
-
export { PdfAnnotationFlags } from './
|
|
3
|
-
export { PdfWidgetAnnotation } from './
|
|
4
|
-
export { PdfAnnotationWriter } from './
|
|
1
|
+
export { PdfAnnotation, type PdfAppearanceStreamDictionary, } from './pdf-annotation.js';
|
|
2
|
+
export { PdfAnnotationFlags } from './pdf-annotation-flags.js';
|
|
3
|
+
export { PdfWidgetAnnotation } from './pdf-widget-annotation.js';
|
|
4
|
+
export { PdfAnnotationWriter } from './pdf-annotation-writer.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { PdfAnnotation, } from './
|
|
2
|
-
export { PdfAnnotationFlags } from './
|
|
3
|
-
export { PdfWidgetAnnotation } from './
|
|
4
|
-
export { PdfAnnotationWriter } from './
|
|
1
|
+
export { PdfAnnotation, } from './pdf-annotation.js';
|
|
2
|
+
export { PdfAnnotationFlags } from './pdf-annotation-flags.js';
|
|
3
|
+
export { PdfWidgetAnnotation } from './pdf-widget-annotation.js';
|
|
4
|
+
export { PdfAnnotationWriter } from './pdf-annotation-writer.js';
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
2
2
|
/**
|
|
3
3
|
* Provides annotation flag (F field) accessors for PDF annotations.
|
|
4
4
|
* These are generic to all annotation types per the PDF spec.
|
|
5
5
|
*/
|
|
6
|
-
export declare class PdfAnnotationFlags {
|
|
7
|
-
|
|
8
|
-
constructor(dict: PdfDictionary);
|
|
6
|
+
export declare class PdfAnnotationFlags extends PdfNumber {
|
|
7
|
+
constructor(value?: number);
|
|
9
8
|
get annotationFlags(): number;
|
|
10
9
|
set annotationFlags(flags: number);
|
|
11
10
|
get invisible(): boolean;
|
|
@@ -3,16 +3,15 @@ import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
|
3
3
|
* Provides annotation flag (F field) accessors for PDF annotations.
|
|
4
4
|
* These are generic to all annotation types per the PDF spec.
|
|
5
5
|
*/
|
|
6
|
-
export class PdfAnnotationFlags {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.dict = dict;
|
|
6
|
+
export class PdfAnnotationFlags extends PdfNumber {
|
|
7
|
+
constructor(value = 0) {
|
|
8
|
+
super(value);
|
|
10
9
|
}
|
|
11
10
|
get annotationFlags() {
|
|
12
|
-
return this.
|
|
11
|
+
return this.value;
|
|
13
12
|
}
|
|
14
13
|
set annotationFlags(flags) {
|
|
15
|
-
this.
|
|
14
|
+
this.value = flags;
|
|
16
15
|
}
|
|
17
16
|
get invisible() {
|
|
18
17
|
return (this.annotationFlags & 1) !== 0;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
|
|
2
2
|
import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
|
|
3
3
|
import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
4
|
+
import { PdfArray } from '../core/objects/pdf-array.js';
|
|
5
|
+
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
6
|
+
import { PdfName } from '../core/objects/pdf-name.js';
|
|
7
|
+
import { PdfString } from '../core/objects/pdf-string.js';
|
|
4
8
|
export type PdfAppearanceStreamDictionary = PdfDictionary<{
|
|
5
9
|
N: PdfObjectReference | PdfDictionary;
|
|
6
10
|
R?: PdfObjectReference | PdfDictionary;
|
|
@@ -8,15 +12,32 @@ export type PdfAppearanceStreamDictionary = PdfDictionary<{
|
|
|
8
12
|
}>;
|
|
9
13
|
/**
|
|
10
14
|
* Base class for all PDF annotations.
|
|
11
|
-
* Owns: Rect, annotation flags (F), AP (appearance streams), P (page reference).
|
|
12
15
|
*/
|
|
13
|
-
export declare class PdfAnnotation extends PdfIndirectObject<PdfDictionary
|
|
16
|
+
export declare class PdfAnnotation extends PdfIndirectObject<PdfDictionary<{
|
|
17
|
+
Type: PdfName;
|
|
18
|
+
Subtype: PdfName;
|
|
19
|
+
AS: PdfName;
|
|
20
|
+
Ff: PdfNumber;
|
|
21
|
+
FT: PdfName;
|
|
22
|
+
T: PdfString;
|
|
23
|
+
DV: PdfString | PdfName;
|
|
24
|
+
V: PdfString | PdfName;
|
|
25
|
+
DA: PdfString;
|
|
26
|
+
Opt: PdfArray<PdfString | PdfArray<PdfString>>;
|
|
27
|
+
MaxLen: PdfNumber;
|
|
28
|
+
Q: PdfNumber;
|
|
29
|
+
Kids: PdfArray<PdfObjectReference>;
|
|
30
|
+
Rect: PdfArray<PdfNumber>;
|
|
31
|
+
F: PdfNumber;
|
|
32
|
+
AP?: PdfAppearanceStreamDictionary;
|
|
33
|
+
P?: PdfObjectReference;
|
|
34
|
+
}>> {
|
|
14
35
|
private _annotationFlags;
|
|
15
36
|
constructor(options?: {
|
|
16
37
|
other?: PdfIndirectObject;
|
|
17
38
|
});
|
|
18
|
-
get rect(): number
|
|
19
|
-
set rect(rect: number
|
|
39
|
+
get rect(): [number, number, number, number] | null;
|
|
40
|
+
set rect(rect: [number, number, number, number] | null);
|
|
20
41
|
get annotationFlags(): number;
|
|
21
42
|
set annotationFlags(flags: number);
|
|
22
43
|
get invisible(): boolean;
|
|
@@ -3,17 +3,18 @@ import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
|
|
|
3
3
|
import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
4
4
|
import { PdfArray } from '../core/objects/pdf-array.js';
|
|
5
5
|
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
6
|
-
import { PdfAnnotationFlags } from './
|
|
6
|
+
import { PdfAnnotationFlags } from './pdf-annotation-flags.js';
|
|
7
7
|
/**
|
|
8
8
|
* Base class for all PDF annotations.
|
|
9
|
-
* Owns: Rect, annotation flags (F), AP (appearance streams), P (page reference).
|
|
10
9
|
*/
|
|
11
10
|
export class PdfAnnotation extends PdfIndirectObject {
|
|
12
11
|
_annotationFlags;
|
|
13
12
|
constructor(options) {
|
|
14
13
|
super(options?.other ??
|
|
15
14
|
new PdfIndirectObject({ content: new PdfDictionary() }));
|
|
16
|
-
|
|
15
|
+
const flagValue = this.content.get('F')?.as(PdfNumber)?.value ?? 0;
|
|
16
|
+
this._annotationFlags = new PdfAnnotationFlags(flagValue);
|
|
17
|
+
this.content.set('F', this._annotationFlags);
|
|
17
18
|
}
|
|
18
19
|
get rect() {
|
|
19
20
|
const rectArray = this.content.get('Rect')?.as((PdfArray));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
|
|
2
|
-
import { PdfAnnotation } from './
|
|
2
|
+
import { PdfAnnotation } from './pdf-annotation.js';
|
|
3
3
|
/**
|
|
4
4
|
* Widget annotation subtype. Extends PdfAnnotation with widget-specific
|
|
5
5
|
* properties: isWidget (Type/Subtype) and AS (appearance state).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PdfName } from '../core/objects/pdf-name.js';
|
|
2
|
-
import { PdfAnnotation } from './
|
|
2
|
+
import { PdfAnnotation } from './pdf-annotation.js';
|
|
3
3
|
/**
|
|
4
4
|
* Widget annotation subtype. Extends PdfAnnotation with widget-specific
|
|
5
5
|
* properties: isWidget (Type/Subtype) and AS (appearance state).
|
|
@@ -20,6 +20,7 @@ export declare class PdfStream<T extends PdfDictionary = PdfDictionary> extends
|
|
|
20
20
|
set raw(data: ByteArray);
|
|
21
21
|
get originalAsString(): string;
|
|
22
22
|
get rawAsString(): string;
|
|
23
|
+
set rawAsString(str: string);
|
|
23
24
|
getFilters(): PdfStreamFilterType[];
|
|
24
25
|
addFilter(filterName: PdfStreamFilterType): this;
|
|
25
26
|
setPredictor(predictorParams: {
|
|
@@ -17,6 +17,7 @@ import { bytesToPdfObjects } from '../generators.js';
|
|
|
17
17
|
import { PdfIndirectObject } from './pdf-indirect-object.js';
|
|
18
18
|
import { PdfXRefTableEntry } from './pdf-xref-table.js';
|
|
19
19
|
import { stringToBytes } from '../../utils/stringToBytes.js';
|
|
20
|
+
import { bytesToString } from '../../utils/bytesToString.js';
|
|
20
21
|
export class PdfStream extends PdfObject {
|
|
21
22
|
header;
|
|
22
23
|
original;
|
|
@@ -52,10 +53,13 @@ export class PdfStream extends PdfObject {
|
|
|
52
53
|
this.header.set('Length', new PdfNumber(data.length));
|
|
53
54
|
}
|
|
54
55
|
get originalAsString() {
|
|
55
|
-
return
|
|
56
|
+
return bytesToString(this.original);
|
|
56
57
|
}
|
|
57
58
|
get rawAsString() {
|
|
58
|
-
return
|
|
59
|
+
return bytesToString(this.raw);
|
|
60
|
+
}
|
|
61
|
+
set rawAsString(str) {
|
|
62
|
+
this.raw = stringToBytes(str);
|
|
59
63
|
}
|
|
60
64
|
getFilters() {
|
|
61
65
|
const filters = this.header.get('Filter');
|
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
import { Parser } from './parser.js';
|
|
2
|
-
/**
|
|
3
|
-
* Error thrown when the parser needs more input to continue parsing.
|
|
4
|
-
*/
|
|
5
|
-
export declare class NoMoreTokensError extends Error {
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Error thrown when the end of file has been reached and no more input is available.
|
|
9
|
-
*/
|
|
10
|
-
export declare class EofReachedError extends Error {
|
|
11
|
-
}
|
|
12
|
-
export declare class UnexpectedTokenError extends Error {
|
|
13
|
-
constructor(expected: string, actual: string | null);
|
|
14
|
-
}
|
|
15
2
|
/**
|
|
16
3
|
* Abstract base class for incremental parsers that can process input as it becomes available.
|
|
17
4
|
* Supports buffering, lookahead, and backtracking for complex parsing scenarios.
|
|
@@ -1,22 +1,5 @@
|
|
|
1
1
|
import { Parser } from './parser.js';
|
|
2
|
-
|
|
3
|
-
* Error thrown when the parser needs more input to continue parsing.
|
|
4
|
-
*/
|
|
5
|
-
export class NoMoreTokensError extends Error {
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Error thrown when the end of file has been reached and no more input is available.
|
|
9
|
-
*/
|
|
10
|
-
export class EofReachedError extends Error {
|
|
11
|
-
}
|
|
12
|
-
/*
|
|
13
|
-
* Error thrown when an unexpected token is encountered during parsing.
|
|
14
|
-
*/
|
|
15
|
-
export class UnexpectedTokenError extends Error {
|
|
16
|
-
constructor(expected, actual) {
|
|
17
|
-
super(`Unexpected token: expected ${expected}, but got ${actual === null ? 'EOF' : actual}`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
2
|
+
import { NoMoreTokensError, EofReachedError } from '../../errors.js';
|
|
20
3
|
/**
|
|
21
4
|
* Abstract base class for incremental parsers that can process input as it becomes available.
|
|
22
5
|
* Supports buffering, lookahead, and backtracking for complex parsing scenarios.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PdfObject } from '../objects/pdf-object.js';
|
|
2
2
|
import { ByteArray } from '../../types.js';
|
|
3
|
-
import { IterableReadableStream } from '../../utils/
|
|
3
|
+
import { IterableReadableStream } from '../../utils/iterable-readable-stream.js';
|
|
4
4
|
export declare class PdfObjectStream extends IterableReadableStream<PdfObject> {
|
|
5
5
|
constructor(input: AsyncIterable<ByteArray> | Iterable<ByteArray>);
|
|
6
6
|
}
|