pdf-lite 1.2.1 → 1.3.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/EXAMPLES.md +1 -1
- package/dist/acroform/acroform.d.ts +272 -16
- package/dist/acroform/acroform.js +1084 -144
- package/dist/acroform/manager.d.ts +2 -2
- package/dist/acroform/manager.js +3 -3
- package/dist/core/decoder.d.ts +1 -1
- package/dist/core/decoder.js +3 -3
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/core/objects/pdf-array.d.ts +1 -0
- package/dist/core/objects/pdf-array.js +4 -0
- package/dist/core/objects/pdf-dictionary.d.ts +1 -0
- package/dist/core/objects/pdf-dictionary.js +12 -0
- package/dist/core/objects/pdf-hexadecimal.d.ts +9 -2
- package/dist/core/objects/pdf-hexadecimal.js +25 -5
- package/dist/core/objects/pdf-indirect-object.d.ts +5 -3
- package/dist/core/objects/pdf-indirect-object.js +23 -5
- package/dist/core/objects/pdf-number.js +3 -0
- package/dist/core/objects/pdf-object.d.ts +6 -0
- package/dist/core/objects/pdf-object.js +10 -0
- package/dist/core/objects/pdf-stream.js +3 -0
- package/dist/core/objects/pdf-string.d.ts +11 -1
- package/dist/core/objects/pdf-string.js +24 -6
- package/dist/core/ref.d.ts +5 -0
- package/dist/core/ref.js +14 -0
- package/dist/core/serializer.d.ts +1 -1
- package/dist/core/serializer.js +1 -1
- package/dist/core/tokeniser.d.ts +2 -2
- package/dist/core/tokeniser.js +37 -75
- package/dist/core/tokens/hexadecimal-token.d.ts +8 -1
- package/dist/core/tokens/hexadecimal-token.js +20 -2
- package/dist/core/tokens/name-token.js +0 -3
- package/dist/core/tokens/string-token.d.ts +8 -1
- package/dist/core/tokens/string-token.js +20 -2
- package/dist/fonts/font-manager.js +6 -8
- package/dist/pdf/pdf-document.d.ts +12 -11
- package/dist/pdf/pdf-document.js +50 -42
- package/dist/pdf/pdf-revision.d.ts +33 -4
- package/dist/pdf/pdf-revision.js +100 -26
- package/dist/pdf/pdf-xref-lookup.js +3 -2
- package/dist/utils/decodeWithFontEncoding.d.ts +20 -0
- package/dist/utils/decodeWithFontEncoding.js +67 -0
- package/dist/utils/escapeString.d.ts +1 -1
- package/dist/utils/escapeString.js +12 -3
- package/dist/utils/glyphNameToUnicode.d.ts +10 -0
- package/dist/utils/glyphNameToUnicode.js +4292 -0
- package/dist/xfa/manager.js +2 -4
- package/package.json +1 -1
- /package/dist/core/{incremental-parser.d.ts → parser/incremental-parser.d.ts} +0 -0
- /package/dist/core/{incremental-parser.js → parser/incremental-parser.js} +0 -0
- /package/dist/core/{parser.d.ts → parser/parser.d.ts} +0 -0
- /package/dist/core/{parser.js → parser/parser.js} +0 -0
package/dist/pdf/pdf-revision.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
|
|
2
2
|
import { PdfObject } from '../core/objects/pdf-object.js';
|
|
3
3
|
import { PdfWhitespaceToken } from '../core/tokens/whitespace-token.js';
|
|
4
|
+
import { PdfComment } from '../index.js';
|
|
4
5
|
import { PdfXrefLookup } from './pdf-xref-lookup.js';
|
|
5
6
|
/**
|
|
6
7
|
* Represents a single revision of a PDF document.
|
|
@@ -8,12 +9,13 @@ import { PdfXrefLookup } from './pdf-xref-lookup.js';
|
|
|
8
9
|
* where each revision contains its own set of objects and cross-reference table.
|
|
9
10
|
*/
|
|
10
11
|
export class PdfRevision extends PdfObject {
|
|
11
|
-
/** Objects contained in this revision */
|
|
12
|
-
|
|
12
|
+
/** Objects contained in this revision (private backing field) */
|
|
13
|
+
_objects = [];
|
|
14
|
+
/** Whether this revision is locked (private backing field) */
|
|
15
|
+
_locked = false;
|
|
13
16
|
/** Cross-reference lookup table for this revision */
|
|
14
17
|
xref;
|
|
15
|
-
|
|
16
|
-
locked = false;
|
|
18
|
+
cachedBytes;
|
|
17
19
|
/**
|
|
18
20
|
* Creates a new PDF revision.
|
|
19
21
|
*
|
|
@@ -25,13 +27,67 @@ export class PdfRevision extends PdfObject {
|
|
|
25
27
|
constructor(options) {
|
|
26
28
|
super();
|
|
27
29
|
this.modified = false;
|
|
28
|
-
this.
|
|
29
|
-
this.xref = PdfXrefLookup.fromObjects(this.
|
|
30
|
+
this._objects = options?.objects ?? [];
|
|
31
|
+
this.xref = PdfXrefLookup.fromObjects(this._objects);
|
|
30
32
|
if (options?.prev)
|
|
31
33
|
this.setPrev(options.prev);
|
|
32
34
|
if (!this.contains(this.xref.object))
|
|
33
35
|
this.addObject(...this.xref.toTrailerSection());
|
|
34
|
-
this.
|
|
36
|
+
this._locked = options?.locked ?? false;
|
|
37
|
+
}
|
|
38
|
+
get header() {
|
|
39
|
+
const firstObj = this._objects[0];
|
|
40
|
+
if (firstObj instanceof PdfComment && firstObj.isVersionComment()) {
|
|
41
|
+
return firstObj;
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
set header(comment) {
|
|
46
|
+
if (this._locked) {
|
|
47
|
+
throw new Error('Cannot modify header in locked PDF revision');
|
|
48
|
+
}
|
|
49
|
+
const currentHeader = this.header;
|
|
50
|
+
if (currentHeader) {
|
|
51
|
+
this._objects[0] = comment;
|
|
52
|
+
}
|
|
53
|
+
else
|
|
54
|
+
this._objects.unshift(comment);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Gets whether this revision is locked (cannot be modified).
|
|
58
|
+
*/
|
|
59
|
+
get locked() {
|
|
60
|
+
return this._locked;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Sets whether this revision is locked.
|
|
64
|
+
* When locking, creates a cached clone of all objects to freeze their state.
|
|
65
|
+
* When unlocking, clears the cache.
|
|
66
|
+
*/
|
|
67
|
+
set locked(value) {
|
|
68
|
+
this._locked = value;
|
|
69
|
+
this.cachedBytes = value ? this.toBytes() : undefined;
|
|
70
|
+
for (const obj of this._objects) {
|
|
71
|
+
obj.setImmutable(value);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Gets the objects in this revision.
|
|
76
|
+
* Returns fresh clones of cached objects if the revision is locked, otherwise returns live objects.
|
|
77
|
+
* Each access to a locked revision's objects returns new clones to prevent mutations.
|
|
78
|
+
*/
|
|
79
|
+
get objects() {
|
|
80
|
+
return this._objects;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Sets the objects array.
|
|
84
|
+
* @throws Error if the revision is locked
|
|
85
|
+
*/
|
|
86
|
+
set objects(value) {
|
|
87
|
+
if (this._locked) {
|
|
88
|
+
throw new Error('Cannot modify objects array in locked revision');
|
|
89
|
+
}
|
|
90
|
+
this._objects = value;
|
|
35
91
|
}
|
|
36
92
|
/**
|
|
37
93
|
* Links this revision to a previous revision's cross-reference table.
|
|
@@ -49,7 +105,7 @@ export class PdfRevision extends PdfObject {
|
|
|
49
105
|
* @returns True if the exact object instance exists in this revision
|
|
50
106
|
*/
|
|
51
107
|
contains(object) {
|
|
52
|
-
return this.
|
|
108
|
+
return this._objects.includes(object);
|
|
53
109
|
}
|
|
54
110
|
/**
|
|
55
111
|
* Checks if an equivalent object exists in this revision (by value equality).
|
|
@@ -58,7 +114,7 @@ export class PdfRevision extends PdfObject {
|
|
|
58
114
|
* @returns True if an equal object exists in this revision
|
|
59
115
|
*/
|
|
60
116
|
exists(object) {
|
|
61
|
-
for (const obj of this.
|
|
117
|
+
for (const obj of this._objects) {
|
|
62
118
|
if (obj.equals(object)) {
|
|
63
119
|
return true;
|
|
64
120
|
}
|
|
@@ -69,10 +125,14 @@ export class PdfRevision extends PdfObject {
|
|
|
69
125
|
* Adds objects to the beginning of the revision's object list.
|
|
70
126
|
*
|
|
71
127
|
* @param objects - Objects to add at the beginning
|
|
128
|
+
* @throws Error if the revision is locked
|
|
72
129
|
*/
|
|
73
130
|
unshift(...objects) {
|
|
131
|
+
if (this._locked) {
|
|
132
|
+
throw new Error('Cannot add object to locked PDF revision');
|
|
133
|
+
}
|
|
74
134
|
for (const obj of objects.reverse()) {
|
|
75
|
-
this.
|
|
135
|
+
this._objects.unshift(obj);
|
|
76
136
|
if (obj instanceof PdfIndirectObject)
|
|
77
137
|
this.xref.addObject(obj);
|
|
78
138
|
}
|
|
@@ -81,8 +141,12 @@ export class PdfRevision extends PdfObject {
|
|
|
81
141
|
* Adds objects to the revision.
|
|
82
142
|
*
|
|
83
143
|
* @param objects - Objects to add to the revision
|
|
144
|
+
* @throws Error if the revision is locked
|
|
84
145
|
*/
|
|
85
146
|
addObject(...objects) {
|
|
147
|
+
if (this._locked) {
|
|
148
|
+
throw new Error('Cannot add object to locked PDF revision');
|
|
149
|
+
}
|
|
86
150
|
for (const obj of objects) {
|
|
87
151
|
this.addObjectAt(obj);
|
|
88
152
|
}
|
|
@@ -95,25 +159,25 @@ export class PdfRevision extends PdfObject {
|
|
|
95
159
|
* @throws Error if the revision is locked or index is out of bounds
|
|
96
160
|
*/
|
|
97
161
|
addObjectAt(object, index) {
|
|
98
|
-
if (this.
|
|
162
|
+
if (this._locked) {
|
|
99
163
|
throw new Error('Cannot add object to locked PDF revision');
|
|
100
164
|
}
|
|
101
165
|
if (index === undefined) {
|
|
102
166
|
index =
|
|
103
167
|
object instanceof PdfIndirectObject
|
|
104
168
|
? this.xref.object
|
|
105
|
-
: this.
|
|
169
|
+
: this._objects.length;
|
|
106
170
|
}
|
|
107
171
|
if (typeof index !== 'number') {
|
|
108
|
-
index = this.
|
|
172
|
+
index = this._objects.indexOf(index);
|
|
109
173
|
if (index === -1) {
|
|
110
|
-
index = this.
|
|
174
|
+
index = this._objects.length;
|
|
111
175
|
}
|
|
112
176
|
}
|
|
113
|
-
if (index < 0 || index > this.
|
|
177
|
+
if (index < 0 || index > this._objects.length) {
|
|
114
178
|
throw new Error('Index out of bounds');
|
|
115
179
|
}
|
|
116
|
-
this.
|
|
180
|
+
this._objects.splice(index, 0, object);
|
|
117
181
|
this.sortObjects();
|
|
118
182
|
if (object instanceof PdfIndirectObject) {
|
|
119
183
|
this.xref.addObject(object);
|
|
@@ -127,16 +191,16 @@ export class PdfRevision extends PdfObject {
|
|
|
127
191
|
* @throws Error if the revision is locked
|
|
128
192
|
*/
|
|
129
193
|
deleteObject(...objects) {
|
|
130
|
-
if (this.
|
|
194
|
+
if (this._locked) {
|
|
131
195
|
throw new Error('Cannot delete object from locked PDF revision');
|
|
132
196
|
}
|
|
133
197
|
for (const object of objects) {
|
|
134
|
-
const index = this.
|
|
198
|
+
const index = this._objects.indexOf(object);
|
|
135
199
|
if (index === -1) {
|
|
136
200
|
return;
|
|
137
201
|
}
|
|
138
202
|
this.modified = true;
|
|
139
|
-
this.
|
|
203
|
+
this._objects.splice(index, 1);
|
|
140
204
|
if (object instanceof PdfIndirectObject) {
|
|
141
205
|
this.xref.removeObject(object);
|
|
142
206
|
}
|
|
@@ -145,13 +209,13 @@ export class PdfRevision extends PdfObject {
|
|
|
145
209
|
isModified() {
|
|
146
210
|
return (super.isModified() ||
|
|
147
211
|
this.xref.trailerDict.isModified() ||
|
|
148
|
-
this.
|
|
212
|
+
this._objects.some((obj) => obj.isModified()));
|
|
149
213
|
}
|
|
150
214
|
/**
|
|
151
215
|
* Updates the revision by sorting objects and updating the xref table.
|
|
152
216
|
*/
|
|
153
217
|
update() {
|
|
154
|
-
if (this.
|
|
218
|
+
if (this._locked) {
|
|
155
219
|
return;
|
|
156
220
|
}
|
|
157
221
|
this.sortObjects();
|
|
@@ -163,7 +227,7 @@ export class PdfRevision extends PdfObject {
|
|
|
163
227
|
* Indirect objects are placed before other objects.
|
|
164
228
|
*/
|
|
165
229
|
sortObjects() {
|
|
166
|
-
this.
|
|
230
|
+
this._objects.sort((a, b) => {
|
|
167
231
|
if (a instanceof PdfIndirectObject &&
|
|
168
232
|
b instanceof PdfIndirectObject) {
|
|
169
233
|
return a.order() - b.order();
|
|
@@ -191,9 +255,19 @@ export class PdfRevision extends PdfObject {
|
|
|
191
255
|
return new PdfRevision({ objects: clonedObjects });
|
|
192
256
|
}
|
|
193
257
|
tokenize() {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
PdfWhitespaceToken
|
|
197
|
-
|
|
258
|
+
const output = this.objects.flatMap((obj) => {
|
|
259
|
+
const objTokens = obj.toTokens();
|
|
260
|
+
if (!(objTokens[objTokens.length - 1] instanceof PdfWhitespaceToken)) {
|
|
261
|
+
objTokens.push(new PdfWhitespaceToken('\n'));
|
|
262
|
+
}
|
|
263
|
+
return objTokens;
|
|
264
|
+
});
|
|
265
|
+
return output;
|
|
266
|
+
}
|
|
267
|
+
toBytes() {
|
|
268
|
+
if (this.cachedBytes) {
|
|
269
|
+
return this.cachedBytes;
|
|
270
|
+
}
|
|
271
|
+
return super.toBytes();
|
|
198
272
|
}
|
|
199
273
|
}
|
|
@@ -375,10 +375,11 @@ export class PdfXrefLookup {
|
|
|
375
375
|
* @returns The xref entry or undefined if not found
|
|
376
376
|
*/
|
|
377
377
|
getObject(objectNumber) {
|
|
378
|
-
|
|
378
|
+
const entry = this.entries.get(objectNumber);
|
|
379
|
+
if (this.prev && !entry) {
|
|
379
380
|
return this.prev.getObject(objectNumber);
|
|
380
381
|
}
|
|
381
|
-
return
|
|
382
|
+
return entry;
|
|
382
383
|
}
|
|
383
384
|
/**
|
|
384
385
|
* Generates the trailer section objects for this xref.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ByteArray } from '../types.js';
|
|
2
|
+
import { PdfArray } from '../core/objects/pdf-array.js';
|
|
3
|
+
/**
|
|
4
|
+
* Builds a character encoding map from a PDF Encoding Differences array.
|
|
5
|
+
* The Differences array format is: [code name1 name2 ... code name1 name2 ...]
|
|
6
|
+
* where code is a number and names are glyph names.
|
|
7
|
+
*
|
|
8
|
+
* @param differences - PdfArray containing the Differences array
|
|
9
|
+
* @returns Map from byte code to Unicode character
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildEncodingMap(differences: PdfArray): Map<number, string> | null;
|
|
12
|
+
/**
|
|
13
|
+
* Decodes a byte array using a custom font encoding map.
|
|
14
|
+
* Falls back to PDFDocEncoding for unmapped bytes.
|
|
15
|
+
*
|
|
16
|
+
* @param bytes - The byte array to decode
|
|
17
|
+
* @param encodingMap - Map from byte code to Unicode character
|
|
18
|
+
* @returns The decoded string
|
|
19
|
+
*/
|
|
20
|
+
export declare function decodeWithFontEncoding(bytes: ByteArray, encodingMap: Map<number, string> | null): string;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { PdfName } from '../core/objects/pdf-name.js';
|
|
2
|
+
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
3
|
+
import { GLYPH_NAME_TO_UNICODE } from './glyphNameToUnicode.js';
|
|
4
|
+
import { decodeFromPDFDocEncoding } from './decodeFromPDFDocEncoding.js';
|
|
5
|
+
/**
|
|
6
|
+
* Builds a character encoding map from a PDF Encoding Differences array.
|
|
7
|
+
* The Differences array format is: [code name1 name2 ... code name1 name2 ...]
|
|
8
|
+
* where code is a number and names are glyph names.
|
|
9
|
+
*
|
|
10
|
+
* @param differences - PdfArray containing the Differences array
|
|
11
|
+
* @returns Map from byte code to Unicode character
|
|
12
|
+
*/
|
|
13
|
+
export function buildEncodingMap(differences) {
|
|
14
|
+
const encodingMap = new Map();
|
|
15
|
+
let currentCode = 0;
|
|
16
|
+
for (const item of differences.items) {
|
|
17
|
+
if (item instanceof PdfNumber) {
|
|
18
|
+
// This is a starting code
|
|
19
|
+
currentCode = item.value;
|
|
20
|
+
}
|
|
21
|
+
else if (item instanceof PdfName) {
|
|
22
|
+
// This is a glyph name
|
|
23
|
+
const glyphName = item.value;
|
|
24
|
+
const unicode = GLYPH_NAME_TO_UNICODE[glyphName];
|
|
25
|
+
if (unicode) {
|
|
26
|
+
encodingMap.set(currentCode, unicode);
|
|
27
|
+
}
|
|
28
|
+
currentCode++;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return encodingMap.size > 0 ? encodingMap : null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Decodes a byte array using a custom font encoding map.
|
|
35
|
+
* Falls back to PDFDocEncoding for unmapped bytes.
|
|
36
|
+
*
|
|
37
|
+
* @param bytes - The byte array to decode
|
|
38
|
+
* @param encodingMap - Map from byte code to Unicode character
|
|
39
|
+
* @returns The decoded string
|
|
40
|
+
*/
|
|
41
|
+
export function decodeWithFontEncoding(bytes, encodingMap) {
|
|
42
|
+
if (!encodingMap) {
|
|
43
|
+
return decodeFromPDFDocEncoding(bytes);
|
|
44
|
+
}
|
|
45
|
+
let result = '';
|
|
46
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
47
|
+
const byte = bytes[i];
|
|
48
|
+
const mapped = encodingMap.get(byte);
|
|
49
|
+
if (mapped !== undefined) {
|
|
50
|
+
result += mapped;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// Fall back to PDFDocEncoding for unmapped bytes
|
|
54
|
+
if (byte < 128) {
|
|
55
|
+
result += String.fromCharCode(byte);
|
|
56
|
+
}
|
|
57
|
+
else if (byte >= 160) {
|
|
58
|
+
result += String.fromCharCode(byte);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// Byte 128-159 range - use PDFDocEncoding
|
|
62
|
+
result += decodeFromPDFDocEncoding(new Uint8Array([byte]));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ByteArray } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Escapes special characters in a PDF string according to PDF specification.
|
|
4
|
-
* Escapes parentheses, backslashes,
|
|
4
|
+
* Escapes parentheses, backslashes, and control characters (\n, \r, \t, \b, \f).
|
|
5
5
|
*
|
|
6
6
|
* @param bytes - The byte array or string to escape.
|
|
7
7
|
* @returns A new byte array with escaped characters.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { stringToBytes } from './stringToBytes.js';
|
|
2
2
|
/**
|
|
3
3
|
* Escapes special characters in a PDF string according to PDF specification.
|
|
4
|
-
* Escapes parentheses, backslashes,
|
|
4
|
+
* Escapes parentheses, backslashes, and control characters (\n, \r, \t, \b, \f).
|
|
5
5
|
*
|
|
6
6
|
* @param bytes - The byte array or string to escape.
|
|
7
7
|
* @returns A new byte array with escaped characters.
|
|
@@ -30,10 +30,19 @@ export function escapeString(bytes) {
|
|
|
30
30
|
break; // \
|
|
31
31
|
case 0x0a:
|
|
32
32
|
result.push(BACKSLASH, 0x6e);
|
|
33
|
-
break; // LF
|
|
33
|
+
break; // \n (LF)
|
|
34
34
|
case 0x0d:
|
|
35
35
|
result.push(BACKSLASH, 0x72);
|
|
36
|
-
break; // CR
|
|
36
|
+
break; // \r (CR)
|
|
37
|
+
case 0x09:
|
|
38
|
+
result.push(BACKSLASH, 0x74);
|
|
39
|
+
break; // \t (Tab)
|
|
40
|
+
case 0x08:
|
|
41
|
+
result.push(BACKSLASH, 0x62);
|
|
42
|
+
break; // \b (Backspace)
|
|
43
|
+
case 0x0c:
|
|
44
|
+
result.push(BACKSLASH, 0x66);
|
|
45
|
+
break; // \f (Form feed)
|
|
37
46
|
default:
|
|
38
47
|
result.push(b);
|
|
39
48
|
break;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps PostScript glyph names to Unicode characters.
|
|
3
|
+
* Based on Adobe Glyph List Specification.
|
|
4
|
+
*
|
|
5
|
+
* Source: https://github.com/adobe-type-tools/agl-aglfn
|
|
6
|
+
*
|
|
7
|
+
* Copyright 2002-2019 Adobe (http://www.adobe.com/).
|
|
8
|
+
* Licensed under BSD-3-Clause.
|
|
9
|
+
*/
|
|
10
|
+
export declare const GLYPH_NAME_TO_UNICODE: Record<string, string>;
|