@lexmata/micropdf 0.4.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/LICENSE +191 -0
- package/README.md +985 -0
- package/binding.gyp +73 -0
- package/dist/annot.d.ts +458 -0
- package/dist/annot.d.ts.map +1 -0
- package/dist/annot.js +697 -0
- package/dist/annot.js.map +1 -0
- package/dist/archive.d.ts +128 -0
- package/dist/archive.d.ts.map +1 -0
- package/dist/archive.js +268 -0
- package/dist/archive.js.map +1 -0
- package/dist/buffer.d.ts +572 -0
- package/dist/buffer.d.ts.map +1 -0
- package/dist/buffer.js +971 -0
- package/dist/buffer.js.map +1 -0
- package/dist/colorspace.d.ts +287 -0
- package/dist/colorspace.d.ts.map +1 -0
- package/dist/colorspace.js +542 -0
- package/dist/colorspace.js.map +1 -0
- package/dist/context.d.ts +184 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +320 -0
- package/dist/context.js.map +1 -0
- package/dist/cookie.d.ts +164 -0
- package/dist/cookie.d.ts.map +1 -0
- package/dist/cookie.js +306 -0
- package/dist/cookie.js.map +1 -0
- package/dist/device.d.ts +169 -0
- package/dist/device.d.ts.map +1 -0
- package/dist/device.js +350 -0
- package/dist/device.js.map +1 -0
- package/dist/display-list.d.ts +202 -0
- package/dist/display-list.d.ts.map +1 -0
- package/dist/display-list.js +410 -0
- package/dist/display-list.js.map +1 -0
- package/dist/document.d.ts +637 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +902 -0
- package/dist/document.js.map +1 -0
- package/dist/easy.d.ts +423 -0
- package/dist/easy.d.ts.map +1 -0
- package/dist/easy.js +644 -0
- package/dist/easy.js.map +1 -0
- package/dist/enhanced.d.ts +226 -0
- package/dist/enhanced.d.ts.map +1 -0
- package/dist/enhanced.js +368 -0
- package/dist/enhanced.js.map +1 -0
- package/dist/filter.d.ts +51 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +381 -0
- package/dist/filter.js.map +1 -0
- package/dist/font.d.ts +222 -0
- package/dist/font.d.ts.map +1 -0
- package/dist/font.js +381 -0
- package/dist/font.js.map +1 -0
- package/dist/form.d.ts +214 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/form.js +497 -0
- package/dist/form.js.map +1 -0
- package/dist/geometry.d.ts +469 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +780 -0
- package/dist/geometry.js.map +1 -0
- package/dist/image.d.ts +172 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +348 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +171 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +339 -0
- package/dist/index.js.map +1 -0
- package/dist/link.d.ts +168 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +343 -0
- package/dist/link.js.map +1 -0
- package/dist/micropdf.d.ts +40 -0
- package/dist/micropdf.d.ts.map +1 -0
- package/dist/micropdf.js +45 -0
- package/dist/micropdf.js.map +1 -0
- package/dist/nanopdf.d.ts +40 -0
- package/dist/nanopdf.d.ts.map +1 -0
- package/dist/nanopdf.js +45 -0
- package/dist/nanopdf.js.map +1 -0
- package/dist/native.d.ts +242 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +509 -0
- package/dist/native.js.map +1 -0
- package/dist/output.d.ts +166 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +365 -0
- package/dist/output.js.map +1 -0
- package/dist/path.d.ts +420 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +687 -0
- package/dist/path.js.map +1 -0
- package/dist/pdf/object.d.ts +489 -0
- package/dist/pdf/object.d.ts.map +1 -0
- package/dist/pdf/object.js +1045 -0
- package/dist/pdf/object.js.map +1 -0
- package/dist/pixmap.d.ts +315 -0
- package/dist/pixmap.d.ts.map +1 -0
- package/dist/pixmap.js +590 -0
- package/dist/pixmap.js.map +1 -0
- package/dist/profiler.d.ts +159 -0
- package/dist/profiler.d.ts.map +1 -0
- package/dist/profiler.js +380 -0
- package/dist/profiler.js.map +1 -0
- package/dist/render-options.d.ts +227 -0
- package/dist/render-options.d.ts.map +1 -0
- package/dist/render-options.js +130 -0
- package/dist/render-options.js.map +1 -0
- package/dist/resource-tracking.d.ts +332 -0
- package/dist/resource-tracking.d.ts.map +1 -0
- package/dist/resource-tracking.js +653 -0
- package/dist/resource-tracking.js.map +1 -0
- package/dist/simple.d.ts +276 -0
- package/dist/simple.d.ts.map +1 -0
- package/dist/simple.js +343 -0
- package/dist/simple.js.map +1 -0
- package/dist/stext.d.ts +290 -0
- package/dist/stext.d.ts.map +1 -0
- package/dist/stext.js +312 -0
- package/dist/stext.js.map +1 -0
- package/dist/stream.d.ts +174 -0
- package/dist/stream.d.ts.map +1 -0
- package/dist/stream.js +476 -0
- package/dist/stream.js.map +1 -0
- package/dist/text.d.ts +337 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +454 -0
- package/dist/text.js.map +1 -0
- package/dist/typed-arrays.d.ts +127 -0
- package/dist/typed-arrays.d.ts.map +1 -0
- package/dist/typed-arrays.js +410 -0
- package/dist/typed-arrays.js.map +1 -0
- package/dist/types.d.ts +358 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +216 -0
- package/dist/types.js.map +1 -0
- package/native/annot.cc +557 -0
- package/native/buffer.cc +204 -0
- package/native/colorspace.cc +166 -0
- package/native/context.cc +84 -0
- package/native/cookie.cc +179 -0
- package/native/device.cc +179 -0
- package/native/display_list.cc +179 -0
- package/native/document.cc +268 -0
- package/native/enhanced.cc +70 -0
- package/native/font.cc +282 -0
- package/native/form.cc +523 -0
- package/native/geometry.cc +255 -0
- package/native/image.cc +216 -0
- package/native/include/micropdf/enhanced.h +38 -0
- package/native/include/micropdf/types.h +36 -0
- package/native/include/micropdf.h +106 -0
- package/native/include/mupdf-ffi.h +39 -0
- package/native/include/mupdf.h +11 -0
- package/native/include/mupdf_minimal.h +381 -0
- package/native/lib/linux-x64/libmicropdf.a +0 -0
- package/native/link.cc +234 -0
- package/native/micropdf.cc +71 -0
- package/native/output.cc +229 -0
- package/native/page.cc +572 -0
- package/native/path.cc +259 -0
- package/native/pixmap.cc +240 -0
- package/native/stext.cc +610 -0
- package/native/stream.cc +239 -0
- package/package.json +120 -0
- package/scripts/build-from-rust.js +97 -0
- package/scripts/install.js +184 -0
|
@@ -0,0 +1,1045 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF Object Model
|
|
3
|
+
*
|
|
4
|
+
* This implementation mirrors the Rust `pdf::object` module for 100% API compatibility.
|
|
5
|
+
*/
|
|
6
|
+
import { PdfObjectType } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Base class for all PDF objects
|
|
9
|
+
*/
|
|
10
|
+
export class PdfObject {
|
|
11
|
+
_refCount = 1;
|
|
12
|
+
_marked = false;
|
|
13
|
+
_parentNum = 0;
|
|
14
|
+
get isNull() {
|
|
15
|
+
return this.type === PdfObjectType.Null;
|
|
16
|
+
}
|
|
17
|
+
get isBool() {
|
|
18
|
+
return this.type === PdfObjectType.Bool;
|
|
19
|
+
}
|
|
20
|
+
get isInt() {
|
|
21
|
+
return this.type === PdfObjectType.Int;
|
|
22
|
+
}
|
|
23
|
+
get isReal() {
|
|
24
|
+
return this.type === PdfObjectType.Real;
|
|
25
|
+
}
|
|
26
|
+
get isNumber() {
|
|
27
|
+
return this.isInt || this.isReal;
|
|
28
|
+
}
|
|
29
|
+
get isString() {
|
|
30
|
+
return this.type === PdfObjectType.String;
|
|
31
|
+
}
|
|
32
|
+
get isName() {
|
|
33
|
+
return this.type === PdfObjectType.Name;
|
|
34
|
+
}
|
|
35
|
+
get isArray() {
|
|
36
|
+
return this.type === PdfObjectType.Array;
|
|
37
|
+
}
|
|
38
|
+
get isDict() {
|
|
39
|
+
return this.type === PdfObjectType.Dict;
|
|
40
|
+
}
|
|
41
|
+
get isStream() {
|
|
42
|
+
return this.type === PdfObjectType.Stream;
|
|
43
|
+
}
|
|
44
|
+
get isIndirect() {
|
|
45
|
+
return this.type === PdfObjectType.Indirect;
|
|
46
|
+
}
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// Reference Counting
|
|
49
|
+
// ============================================================================
|
|
50
|
+
/**
|
|
51
|
+
* Increment reference count (keep object alive)
|
|
52
|
+
*/
|
|
53
|
+
keep() {
|
|
54
|
+
this._refCount++;
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Decrement reference count (may allow garbage collection)
|
|
59
|
+
*/
|
|
60
|
+
drop() {
|
|
61
|
+
if (this._refCount > 0) {
|
|
62
|
+
this._refCount--;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get current reference count
|
|
67
|
+
*/
|
|
68
|
+
getRefs() {
|
|
69
|
+
return this._refCount;
|
|
70
|
+
}
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// Object Marking (for traversal algorithms)
|
|
73
|
+
// ============================================================================
|
|
74
|
+
/**
|
|
75
|
+
* Check if object is marked
|
|
76
|
+
*/
|
|
77
|
+
isMarked() {
|
|
78
|
+
return this._marked;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Mark this object
|
|
82
|
+
*/
|
|
83
|
+
mark() {
|
|
84
|
+
this._marked = true;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Unmark this object
|
|
88
|
+
*/
|
|
89
|
+
unmark() {
|
|
90
|
+
this._marked = false;
|
|
91
|
+
}
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// Parent Tracking
|
|
94
|
+
// ============================================================================
|
|
95
|
+
/**
|
|
96
|
+
* Set parent object number (for indirect objects)
|
|
97
|
+
*/
|
|
98
|
+
setParent(objNum) {
|
|
99
|
+
this._parentNum = objNum;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get parent object number
|
|
103
|
+
*/
|
|
104
|
+
getParentNum() {
|
|
105
|
+
return this._parentNum;
|
|
106
|
+
}
|
|
107
|
+
toBool() {
|
|
108
|
+
if (this instanceof PdfBool)
|
|
109
|
+
return this.value;
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
toInt() {
|
|
113
|
+
if (this instanceof PdfInt)
|
|
114
|
+
return this.value;
|
|
115
|
+
if (this instanceof PdfReal)
|
|
116
|
+
return Math.trunc(this.value);
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
toReal() {
|
|
120
|
+
if (this instanceof PdfReal)
|
|
121
|
+
return this.value;
|
|
122
|
+
if (this instanceof PdfInt)
|
|
123
|
+
return this.value;
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
toNumber() {
|
|
127
|
+
return this.toReal();
|
|
128
|
+
}
|
|
129
|
+
toString() {
|
|
130
|
+
if (this instanceof PdfString)
|
|
131
|
+
return this.value;
|
|
132
|
+
return '';
|
|
133
|
+
}
|
|
134
|
+
toName() {
|
|
135
|
+
if (this instanceof PdfName)
|
|
136
|
+
return this.value;
|
|
137
|
+
return '';
|
|
138
|
+
}
|
|
139
|
+
nameEquals(name) {
|
|
140
|
+
if (this instanceof PdfName)
|
|
141
|
+
return this.value === name;
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* PDF Null object
|
|
147
|
+
*/
|
|
148
|
+
class PdfNull extends PdfObject {
|
|
149
|
+
get type() {
|
|
150
|
+
return PdfObjectType.Null;
|
|
151
|
+
}
|
|
152
|
+
equals(other) {
|
|
153
|
+
return other instanceof PdfNull;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* PDF Boolean object
|
|
158
|
+
*/
|
|
159
|
+
class PdfBool extends PdfObject {
|
|
160
|
+
value;
|
|
161
|
+
constructor(value) {
|
|
162
|
+
super();
|
|
163
|
+
this.value = value;
|
|
164
|
+
}
|
|
165
|
+
get type() {
|
|
166
|
+
return PdfObjectType.Bool;
|
|
167
|
+
}
|
|
168
|
+
equals(other) {
|
|
169
|
+
return other instanceof PdfBool && other.value === this.value;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* PDF Integer object
|
|
174
|
+
*/
|
|
175
|
+
class PdfInt extends PdfObject {
|
|
176
|
+
value;
|
|
177
|
+
constructor(value) {
|
|
178
|
+
super();
|
|
179
|
+
this.value = Math.trunc(value);
|
|
180
|
+
}
|
|
181
|
+
get type() {
|
|
182
|
+
return PdfObjectType.Int;
|
|
183
|
+
}
|
|
184
|
+
equals(other) {
|
|
185
|
+
return other instanceof PdfInt && other.value === this.value;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* PDF Real (floating point) object
|
|
190
|
+
*/
|
|
191
|
+
class PdfReal extends PdfObject {
|
|
192
|
+
value;
|
|
193
|
+
constructor(value) {
|
|
194
|
+
super();
|
|
195
|
+
this.value = value;
|
|
196
|
+
}
|
|
197
|
+
get type() {
|
|
198
|
+
return PdfObjectType.Real;
|
|
199
|
+
}
|
|
200
|
+
equals(other) {
|
|
201
|
+
return other instanceof PdfReal && other.value === this.value;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* PDF String object
|
|
206
|
+
*/
|
|
207
|
+
class PdfString extends PdfObject {
|
|
208
|
+
value;
|
|
209
|
+
constructor(value) {
|
|
210
|
+
super();
|
|
211
|
+
this.value = value;
|
|
212
|
+
}
|
|
213
|
+
get type() {
|
|
214
|
+
return PdfObjectType.String;
|
|
215
|
+
}
|
|
216
|
+
equals(other) {
|
|
217
|
+
return other instanceof PdfString && other.value === this.value;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* PDF Name object
|
|
222
|
+
*/
|
|
223
|
+
class PdfName extends PdfObject {
|
|
224
|
+
value;
|
|
225
|
+
constructor(value) {
|
|
226
|
+
super();
|
|
227
|
+
this.value = value;
|
|
228
|
+
}
|
|
229
|
+
get type() {
|
|
230
|
+
return PdfObjectType.Name;
|
|
231
|
+
}
|
|
232
|
+
equals(other) {
|
|
233
|
+
return other instanceof PdfName && other.value === this.value;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* PDF Array object
|
|
238
|
+
*/
|
|
239
|
+
export class PdfArray extends PdfObject {
|
|
240
|
+
items;
|
|
241
|
+
dirty = false;
|
|
242
|
+
constructor(items = []) {
|
|
243
|
+
super();
|
|
244
|
+
this.items = [...items];
|
|
245
|
+
}
|
|
246
|
+
get type() {
|
|
247
|
+
return PdfObjectType.Array;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Get the number of elements in the array
|
|
251
|
+
*/
|
|
252
|
+
get length() {
|
|
253
|
+
return this.items.length;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Get element at the specified index
|
|
257
|
+
*/
|
|
258
|
+
get(index) {
|
|
259
|
+
return this.items[index];
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Set element at the specified index (alias for put)
|
|
263
|
+
*/
|
|
264
|
+
put(index, obj) {
|
|
265
|
+
if (index >= 0 && index < this.items.length) {
|
|
266
|
+
this.items[index] = obj;
|
|
267
|
+
this.dirty = true;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Push a PDF object to the end of the array
|
|
272
|
+
*/
|
|
273
|
+
push(obj) {
|
|
274
|
+
this.items.push(obj);
|
|
275
|
+
this.dirty = true;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Push an integer value to the end of the array
|
|
279
|
+
*/
|
|
280
|
+
pushInt(value) {
|
|
281
|
+
this.items.push(new PdfInt(value));
|
|
282
|
+
this.dirty = true;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Push a real (float) value to the end of the array
|
|
286
|
+
*/
|
|
287
|
+
pushReal(value) {
|
|
288
|
+
this.items.push(new PdfReal(value));
|
|
289
|
+
this.dirty = true;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Push a boolean value to the end of the array
|
|
293
|
+
*/
|
|
294
|
+
pushBool(value) {
|
|
295
|
+
this.items.push(new PdfBool(value));
|
|
296
|
+
this.dirty = true;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Push a name to the end of the array
|
|
300
|
+
*/
|
|
301
|
+
pushName(value) {
|
|
302
|
+
this.items.push(new PdfName(value));
|
|
303
|
+
this.dirty = true;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Push a string to the end of the array
|
|
307
|
+
*/
|
|
308
|
+
pushString(value) {
|
|
309
|
+
this.items.push(new PdfString(value));
|
|
310
|
+
this.dirty = true;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Insert element at the specified index
|
|
314
|
+
*/
|
|
315
|
+
insert(index, obj) {
|
|
316
|
+
if (index >= 0 && index <= this.items.length) {
|
|
317
|
+
this.items.splice(index, 0, obj);
|
|
318
|
+
this.dirty = true;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Delete element at the specified index
|
|
323
|
+
*/
|
|
324
|
+
delete(index) {
|
|
325
|
+
if (index >= 0 && index < this.items.length) {
|
|
326
|
+
this.items.splice(index, 1);
|
|
327
|
+
this.dirty = true;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Convert to a JavaScript array
|
|
332
|
+
*/
|
|
333
|
+
toArray() {
|
|
334
|
+
return [...this.items];
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Check if this array has been modified
|
|
338
|
+
*/
|
|
339
|
+
isDirty() {
|
|
340
|
+
return this.dirty;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Mark this array as dirty (modified)
|
|
344
|
+
*/
|
|
345
|
+
markDirty() {
|
|
346
|
+
this.dirty = true;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Mark this array as clean (not modified)
|
|
350
|
+
*/
|
|
351
|
+
markClean() {
|
|
352
|
+
this.dirty = false;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Create a shallow copy of this array
|
|
356
|
+
*/
|
|
357
|
+
copy() {
|
|
358
|
+
return new PdfArray([...this.items]);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Create a deep copy of this array
|
|
362
|
+
*/
|
|
363
|
+
deepCopy() {
|
|
364
|
+
const copied = this.items.map((item) => {
|
|
365
|
+
if (item instanceof PdfArray)
|
|
366
|
+
return item.deepCopy();
|
|
367
|
+
if (item instanceof PdfDict)
|
|
368
|
+
return item.deepCopy();
|
|
369
|
+
if (item instanceof PdfStream)
|
|
370
|
+
return item.deepCopy();
|
|
371
|
+
return item; // Primitive types are immutable
|
|
372
|
+
});
|
|
373
|
+
return new PdfArray(copied);
|
|
374
|
+
}
|
|
375
|
+
[Symbol.iterator]() {
|
|
376
|
+
return this.items[Symbol.iterator]();
|
|
377
|
+
}
|
|
378
|
+
equals(other) {
|
|
379
|
+
if (!(other instanceof PdfArray))
|
|
380
|
+
return false;
|
|
381
|
+
if (other.length !== this.length)
|
|
382
|
+
return false;
|
|
383
|
+
for (let i = 0; i < this.length; i++) {
|
|
384
|
+
if (!this.items[i].equals(other.items[i]))
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* PDF Dictionary object
|
|
392
|
+
*/
|
|
393
|
+
export class PdfDict extends PdfObject {
|
|
394
|
+
entries;
|
|
395
|
+
dirty = false;
|
|
396
|
+
constructor(entries = {}) {
|
|
397
|
+
super();
|
|
398
|
+
this.entries = new Map(Object.entries(entries));
|
|
399
|
+
}
|
|
400
|
+
get type() {
|
|
401
|
+
return PdfObjectType.Dict;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Get the number of entries in the dictionary
|
|
405
|
+
*/
|
|
406
|
+
get length() {
|
|
407
|
+
return this.entries.size;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Get value for a key
|
|
411
|
+
*/
|
|
412
|
+
get(key) {
|
|
413
|
+
return this.entries.get(key);
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Put a PDF object value for a key
|
|
417
|
+
*/
|
|
418
|
+
put(key, value) {
|
|
419
|
+
this.entries.set(key, value);
|
|
420
|
+
this.dirty = true;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Put an integer value for a key
|
|
424
|
+
*/
|
|
425
|
+
putInt(key, value) {
|
|
426
|
+
this.entries.set(key, new PdfInt(value));
|
|
427
|
+
this.dirty = true;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Put a real (float) value for a key
|
|
431
|
+
*/
|
|
432
|
+
putReal(key, value) {
|
|
433
|
+
this.entries.set(key, new PdfReal(value));
|
|
434
|
+
this.dirty = true;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Put a boolean value for a key
|
|
438
|
+
*/
|
|
439
|
+
putBool(key, value) {
|
|
440
|
+
this.entries.set(key, new PdfBool(value));
|
|
441
|
+
this.dirty = true;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Put a name for a key
|
|
445
|
+
*/
|
|
446
|
+
putName(key, value) {
|
|
447
|
+
this.entries.set(key, new PdfName(value));
|
|
448
|
+
this.dirty = true;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Put a string for a key
|
|
452
|
+
*/
|
|
453
|
+
putString(key, value) {
|
|
454
|
+
this.entries.set(key, new PdfString(value));
|
|
455
|
+
this.dirty = true;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Delete a key from the dictionary
|
|
459
|
+
*/
|
|
460
|
+
del(key) {
|
|
461
|
+
if (this.entries.delete(key)) {
|
|
462
|
+
this.dirty = true;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Check if a key exists in the dictionary
|
|
467
|
+
*/
|
|
468
|
+
has(key) {
|
|
469
|
+
return this.entries.has(key);
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Get all keys in the dictionary
|
|
473
|
+
*/
|
|
474
|
+
keys() {
|
|
475
|
+
return [...this.entries.keys()];
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Get all values in the dictionary
|
|
479
|
+
*/
|
|
480
|
+
values() {
|
|
481
|
+
return [...this.entries.values()];
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Get all entries as [key, value] pairs
|
|
485
|
+
*/
|
|
486
|
+
getEntries() {
|
|
487
|
+
return [...this.entries.entries()];
|
|
488
|
+
}
|
|
489
|
+
*[Symbol.iterator]() {
|
|
490
|
+
for (const [key, value] of this.entries) {
|
|
491
|
+
yield [key, value];
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
// ============================================================================
|
|
495
|
+
// Typed getters with defaults
|
|
496
|
+
// ============================================================================
|
|
497
|
+
/**
|
|
498
|
+
* Get name value for a key
|
|
499
|
+
*/
|
|
500
|
+
getName(key) {
|
|
501
|
+
return this.get(key)?.toName() ?? '';
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Get string value for a key
|
|
505
|
+
*/
|
|
506
|
+
getString(key) {
|
|
507
|
+
return this.get(key)?.toString() ?? '';
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Get integer value for a key
|
|
511
|
+
*/
|
|
512
|
+
getInt(key, defaultValue = 0) {
|
|
513
|
+
const obj = this.get(key);
|
|
514
|
+
return obj ? obj.toInt() : defaultValue;
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Get real (float) value for a key
|
|
518
|
+
*/
|
|
519
|
+
getReal(key, defaultValue = 0) {
|
|
520
|
+
const obj = this.get(key);
|
|
521
|
+
return obj ? obj.toReal() : defaultValue;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Get boolean value for a key
|
|
525
|
+
*/
|
|
526
|
+
getBool(key, defaultValue = false) {
|
|
527
|
+
const obj = this.get(key);
|
|
528
|
+
return obj ? obj.toBool() : defaultValue;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Get array for a key
|
|
532
|
+
*/
|
|
533
|
+
getArray(key) {
|
|
534
|
+
const obj = this.get(key);
|
|
535
|
+
return obj instanceof PdfArray ? obj : undefined;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Get dictionary for a key
|
|
539
|
+
*/
|
|
540
|
+
getDict(key) {
|
|
541
|
+
const obj = this.get(key);
|
|
542
|
+
return obj instanceof PdfDict ? obj : undefined;
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Get stream for a key
|
|
546
|
+
*/
|
|
547
|
+
getStream(key) {
|
|
548
|
+
const obj = this.get(key);
|
|
549
|
+
return obj instanceof PdfStream ? obj : undefined;
|
|
550
|
+
}
|
|
551
|
+
// ============================================================================
|
|
552
|
+
// Dirty tracking
|
|
553
|
+
// ============================================================================
|
|
554
|
+
/**
|
|
555
|
+
* Check if this dictionary has been modified
|
|
556
|
+
*/
|
|
557
|
+
isDirty() {
|
|
558
|
+
return this.dirty;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Mark this dictionary as dirty (modified)
|
|
562
|
+
*/
|
|
563
|
+
markDirty() {
|
|
564
|
+
this.dirty = true;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Mark this dictionary as clean (not modified)
|
|
568
|
+
*/
|
|
569
|
+
markClean() {
|
|
570
|
+
this.dirty = false;
|
|
571
|
+
}
|
|
572
|
+
// ============================================================================
|
|
573
|
+
// Copying
|
|
574
|
+
// ============================================================================
|
|
575
|
+
/**
|
|
576
|
+
* Create a shallow copy of this dictionary
|
|
577
|
+
*/
|
|
578
|
+
copy() {
|
|
579
|
+
const entries = {};
|
|
580
|
+
for (const [key, value] of this.entries) {
|
|
581
|
+
entries[key] = value;
|
|
582
|
+
}
|
|
583
|
+
return new PdfDict(entries);
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Create a deep copy of this dictionary
|
|
587
|
+
*/
|
|
588
|
+
deepCopy() {
|
|
589
|
+
const entries = {};
|
|
590
|
+
for (const [key, value] of this.entries) {
|
|
591
|
+
if (value instanceof PdfArray) {
|
|
592
|
+
entries[key] = value.deepCopy();
|
|
593
|
+
}
|
|
594
|
+
else if (value instanceof PdfDict) {
|
|
595
|
+
entries[key] = value.deepCopy();
|
|
596
|
+
}
|
|
597
|
+
else if (value instanceof PdfStream) {
|
|
598
|
+
entries[key] = value.deepCopy();
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
entries[key] = value; // Primitive types are immutable
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return new PdfDict(entries);
|
|
605
|
+
}
|
|
606
|
+
equals(other) {
|
|
607
|
+
if (!(other instanceof PdfDict))
|
|
608
|
+
return false;
|
|
609
|
+
if (other.length !== this.length)
|
|
610
|
+
return false;
|
|
611
|
+
for (const [key, value] of this.entries) {
|
|
612
|
+
const otherValue = other.get(key);
|
|
613
|
+
if (!otherValue || !value.equals(otherValue))
|
|
614
|
+
return false;
|
|
615
|
+
}
|
|
616
|
+
return true;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* PDF Stream object
|
|
621
|
+
*/
|
|
622
|
+
export class PdfStream extends PdfObject {
|
|
623
|
+
dict;
|
|
624
|
+
_data;
|
|
625
|
+
constructor(dict, data = new Uint8Array(0)) {
|
|
626
|
+
super();
|
|
627
|
+
this.dict = dict;
|
|
628
|
+
this._data = data;
|
|
629
|
+
}
|
|
630
|
+
get type() {
|
|
631
|
+
return PdfObjectType.Stream;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Get the stream data
|
|
635
|
+
*/
|
|
636
|
+
getData() {
|
|
637
|
+
return this._data;
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Set the stream data
|
|
641
|
+
*/
|
|
642
|
+
setData(data) {
|
|
643
|
+
this._data = data;
|
|
644
|
+
this.dict.markDirty();
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Get the stream dictionary
|
|
648
|
+
*/
|
|
649
|
+
getDict() {
|
|
650
|
+
return this.dict;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Create a deep copy of this stream
|
|
654
|
+
*/
|
|
655
|
+
deepCopy() {
|
|
656
|
+
const dictCopy = this.dict.deepCopy();
|
|
657
|
+
const dataCopy = new Uint8Array(this._data);
|
|
658
|
+
return new PdfStream(dictCopy, dataCopy);
|
|
659
|
+
}
|
|
660
|
+
equals(other) {
|
|
661
|
+
if (!(other instanceof PdfStream))
|
|
662
|
+
return false;
|
|
663
|
+
if (!this.dict.equals(other.dict))
|
|
664
|
+
return false;
|
|
665
|
+
if (this._data.length !== other._data.length)
|
|
666
|
+
return false;
|
|
667
|
+
for (let i = 0; i < this._data.length; i++) {
|
|
668
|
+
if (this._data[i] !== other._data[i])
|
|
669
|
+
return false;
|
|
670
|
+
}
|
|
671
|
+
return true;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* PDF Indirect Reference object
|
|
676
|
+
*/
|
|
677
|
+
export class PdfIndirectRef extends PdfObject {
|
|
678
|
+
objNum;
|
|
679
|
+
genNum;
|
|
680
|
+
constructor(objNum, genNum = 0) {
|
|
681
|
+
super();
|
|
682
|
+
this.objNum = objNum;
|
|
683
|
+
this.genNum = genNum;
|
|
684
|
+
}
|
|
685
|
+
get type() {
|
|
686
|
+
return PdfObjectType.Indirect;
|
|
687
|
+
}
|
|
688
|
+
equals(other) {
|
|
689
|
+
return (other instanceof PdfIndirectRef &&
|
|
690
|
+
other.objNum === this.objNum &&
|
|
691
|
+
other.genNum === this.genNum);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
// ============================================================================
|
|
695
|
+
// Factory Functions
|
|
696
|
+
// ============================================================================
|
|
697
|
+
const NULL_SINGLETON = new PdfNull();
|
|
698
|
+
/**
|
|
699
|
+
* Create a null PDF object
|
|
700
|
+
*/
|
|
701
|
+
export function pdfNull() {
|
|
702
|
+
return NULL_SINGLETON;
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Create a boolean PDF object
|
|
706
|
+
*/
|
|
707
|
+
export function pdfBool(value) {
|
|
708
|
+
return new PdfBool(value);
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Create an integer PDF object
|
|
712
|
+
*/
|
|
713
|
+
export function pdfInt(value) {
|
|
714
|
+
return new PdfInt(value);
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Create a real PDF object
|
|
718
|
+
*/
|
|
719
|
+
export function pdfReal(value) {
|
|
720
|
+
return new PdfReal(value);
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Create a string PDF object
|
|
724
|
+
*/
|
|
725
|
+
export function pdfString(value) {
|
|
726
|
+
return new PdfString(value);
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Create a name PDF object
|
|
730
|
+
*/
|
|
731
|
+
export function pdfName(value) {
|
|
732
|
+
return new PdfName(value);
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Create an array PDF object
|
|
736
|
+
*/
|
|
737
|
+
export function pdfArray(items = []) {
|
|
738
|
+
return new PdfArray(items);
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Create a dictionary PDF object
|
|
742
|
+
*/
|
|
743
|
+
export function pdfDict(entries = {}) {
|
|
744
|
+
return new PdfDict(entries);
|
|
745
|
+
}
|
|
746
|
+
// ============================================================================
|
|
747
|
+
// Utility Functions
|
|
748
|
+
// ============================================================================
|
|
749
|
+
/**
|
|
750
|
+
* Compare two PDF objects for equality
|
|
751
|
+
*/
|
|
752
|
+
export function pdfObjectCompare(a, b) {
|
|
753
|
+
return a.equals(b);
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Check if a PDF name equals a string value
|
|
757
|
+
*/
|
|
758
|
+
export function pdfNameEquals(obj, name) {
|
|
759
|
+
return obj.nameEquals(name);
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Create a deep copy of a PDF object
|
|
763
|
+
*/
|
|
764
|
+
export function pdfDeepCopy(obj) {
|
|
765
|
+
if (obj instanceof PdfArray)
|
|
766
|
+
return obj.deepCopy();
|
|
767
|
+
if (obj instanceof PdfDict)
|
|
768
|
+
return obj.deepCopy();
|
|
769
|
+
if (obj instanceof PdfStream)
|
|
770
|
+
return obj.deepCopy();
|
|
771
|
+
// Primitive types are immutable, so return as-is
|
|
772
|
+
return obj;
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Create a shallow copy of an array
|
|
776
|
+
*/
|
|
777
|
+
export function pdfCopyArray(array) {
|
|
778
|
+
return array.copy();
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Create a shallow copy of a dictionary
|
|
782
|
+
*/
|
|
783
|
+
export function pdfCopyDict(dict) {
|
|
784
|
+
return dict.copy();
|
|
785
|
+
}
|
|
786
|
+
// ============================================================================
|
|
787
|
+
// Type Checking Functions
|
|
788
|
+
// ============================================================================
|
|
789
|
+
/**
|
|
790
|
+
* Check if object is null
|
|
791
|
+
*/
|
|
792
|
+
export function isNull(obj) {
|
|
793
|
+
return obj.isNull;
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Check if object is a boolean
|
|
797
|
+
*/
|
|
798
|
+
export function isBool(obj) {
|
|
799
|
+
return obj.isBool;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Check if object is an integer
|
|
803
|
+
*/
|
|
804
|
+
export function isInt(obj) {
|
|
805
|
+
return obj.isInt;
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Check if object is a real number
|
|
809
|
+
*/
|
|
810
|
+
export function isReal(obj) {
|
|
811
|
+
return obj.isReal;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Check if object is a number (int or real)
|
|
815
|
+
*/
|
|
816
|
+
export function isNumber(obj) {
|
|
817
|
+
return obj.isNumber;
|
|
818
|
+
}
|
|
819
|
+
/**
|
|
820
|
+
* Check if object is a name
|
|
821
|
+
*/
|
|
822
|
+
export function isName(obj) {
|
|
823
|
+
return obj.isName;
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Check if object is a string
|
|
827
|
+
*/
|
|
828
|
+
export function isString(obj) {
|
|
829
|
+
return obj.isString;
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Check if object is an array
|
|
833
|
+
*/
|
|
834
|
+
export function isArray(obj) {
|
|
835
|
+
return obj.isArray;
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Check if object is a dictionary
|
|
839
|
+
*/
|
|
840
|
+
export function isDict(obj) {
|
|
841
|
+
return obj.isDict;
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* Check if object is a stream
|
|
845
|
+
*/
|
|
846
|
+
export function isStream(obj) {
|
|
847
|
+
return obj.isStream;
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Check if object is an indirect reference
|
|
851
|
+
*/
|
|
852
|
+
export function isIndirect(obj) {
|
|
853
|
+
return obj.isIndirect;
|
|
854
|
+
}
|
|
855
|
+
// ============================================================================
|
|
856
|
+
// Value Extraction Functions (with defaults)
|
|
857
|
+
// ============================================================================
|
|
858
|
+
/**
|
|
859
|
+
* Convert object to boolean with default value
|
|
860
|
+
*/
|
|
861
|
+
export function toBoolDefault(obj, defaultValue) {
|
|
862
|
+
return obj ? obj.toBool() : defaultValue;
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Convert object to integer with default value
|
|
866
|
+
*/
|
|
867
|
+
export function toIntDefault(obj, defaultValue) {
|
|
868
|
+
return obj ? obj.toInt() : defaultValue;
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Convert object to real with default value
|
|
872
|
+
*/
|
|
873
|
+
export function toRealDefault(obj, defaultValue) {
|
|
874
|
+
return obj ? obj.toReal() : defaultValue;
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* Get object number from indirect reference
|
|
878
|
+
*/
|
|
879
|
+
export function toObjNum(obj) {
|
|
880
|
+
if (obj instanceof PdfIndirectRef) {
|
|
881
|
+
return obj.objNum;
|
|
882
|
+
}
|
|
883
|
+
return 0;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Get generation number from indirect reference
|
|
887
|
+
*/
|
|
888
|
+
export function toGenNum(obj) {
|
|
889
|
+
if (obj instanceof PdfIndirectRef) {
|
|
890
|
+
return obj.genNum;
|
|
891
|
+
}
|
|
892
|
+
return 0;
|
|
893
|
+
}
|
|
894
|
+
// ============================================================================
|
|
895
|
+
// Reference Counting Functions
|
|
896
|
+
// ============================================================================
|
|
897
|
+
/**
|
|
898
|
+
* Increment reference count on object
|
|
899
|
+
*/
|
|
900
|
+
export function pdfKeepObj(obj) {
|
|
901
|
+
return obj.keep();
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Decrement reference count on object
|
|
905
|
+
*/
|
|
906
|
+
export function pdfDropObj(obj) {
|
|
907
|
+
obj.drop();
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Get reference count for object
|
|
911
|
+
*/
|
|
912
|
+
export function pdfObjRefs(obj) {
|
|
913
|
+
return obj.getRefs();
|
|
914
|
+
}
|
|
915
|
+
// ============================================================================
|
|
916
|
+
// Object Marking Functions
|
|
917
|
+
// ============================================================================
|
|
918
|
+
/**
|
|
919
|
+
* Check if object is marked
|
|
920
|
+
*/
|
|
921
|
+
export function pdfObjMarked(obj) {
|
|
922
|
+
return obj.isMarked();
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* Mark an object
|
|
926
|
+
*/
|
|
927
|
+
export function pdfMarkObj(obj) {
|
|
928
|
+
obj.mark();
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* Unmark an object
|
|
932
|
+
*/
|
|
933
|
+
export function pdfUnmarkObj(obj) {
|
|
934
|
+
obj.unmark();
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Set parent object number
|
|
938
|
+
*/
|
|
939
|
+
export function pdfSetObjParent(obj, parentNum) {
|
|
940
|
+
obj.setParent(parentNum);
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
* Get parent object number
|
|
944
|
+
*/
|
|
945
|
+
export function pdfObjParentNum(obj) {
|
|
946
|
+
return obj.getParentNum();
|
|
947
|
+
}
|
|
948
|
+
// ============================================================================
|
|
949
|
+
// Geometry Creation Utilities
|
|
950
|
+
// ============================================================================
|
|
951
|
+
/**
|
|
952
|
+
* Create a point dictionary (for use in PDF objects)
|
|
953
|
+
*/
|
|
954
|
+
export function pdfNewPoint(x, y) {
|
|
955
|
+
return pdfArray([pdfReal(x), pdfReal(y)]);
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Create a rectangle dictionary (for use in PDF objects)
|
|
959
|
+
*/
|
|
960
|
+
export function pdfNewRect(x0, y0, x1, y1) {
|
|
961
|
+
return pdfArray([pdfReal(x0), pdfReal(y0), pdfReal(x1), pdfReal(y1)]);
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Create a matrix dictionary (for use in PDF objects)
|
|
965
|
+
*/
|
|
966
|
+
export function pdfNewMatrix(a, b, c, d, e, f) {
|
|
967
|
+
return pdfArray([pdfReal(a), pdfReal(b), pdfReal(c), pdfReal(d), pdfReal(e), pdfReal(f)]);
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Create a date string in PDF format
|
|
971
|
+
* Format: D:YYYYMMDDHHmmSSOHH'mm
|
|
972
|
+
*/
|
|
973
|
+
export function pdfNewDate(date = new Date()) {
|
|
974
|
+
const year = date.getFullYear();
|
|
975
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
976
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
977
|
+
const hours = String(date.getHours()).padStart(2, '0');
|
|
978
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
979
|
+
const seconds = String(date.getSeconds()).padStart(2, '0');
|
|
980
|
+
// Get timezone offset
|
|
981
|
+
const offset = -date.getTimezoneOffset();
|
|
982
|
+
const offsetSign = offset >= 0 ? '+' : '-';
|
|
983
|
+
const offsetHours = String(Math.floor(Math.abs(offset) / 60)).padStart(2, '0');
|
|
984
|
+
const offsetMinutes = String(Math.abs(offset) % 60).padStart(2, '0');
|
|
985
|
+
const dateStr = `D:${year}${month}${day}${hours}${minutes}${seconds}${offsetSign}${offsetHours}'${offsetMinutes}`;
|
|
986
|
+
return pdfString(dateStr);
|
|
987
|
+
}
|
|
988
|
+
// ============================================================================
|
|
989
|
+
// Dictionary Utility Functions
|
|
990
|
+
// ============================================================================
|
|
991
|
+
/**
|
|
992
|
+
* Get key at index from dictionary (for iteration)
|
|
993
|
+
*/
|
|
994
|
+
export function pdfDictGetKey(dict, index) {
|
|
995
|
+
const keys = dict.keys();
|
|
996
|
+
return keys[index];
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Get value at index from dictionary (for iteration)
|
|
1000
|
+
*/
|
|
1001
|
+
export function pdfDictGetVal(dict, index) {
|
|
1002
|
+
const key = pdfDictGetKey(dict, index);
|
|
1003
|
+
return key ? dict.get(key) : undefined;
|
|
1004
|
+
}
|
|
1005
|
+
// ============================================================================
|
|
1006
|
+
// Indirect Reference Resolution
|
|
1007
|
+
// ============================================================================
|
|
1008
|
+
// Note: These functions require document context for actual resolution
|
|
1009
|
+
// Here we provide type-level support; actual resolution happens in Document class
|
|
1010
|
+
/**
|
|
1011
|
+
* Check if an indirect reference is resolved
|
|
1012
|
+
* @param obj The object to check
|
|
1013
|
+
* @returns Always true for direct objects, requires document context for indirect refs
|
|
1014
|
+
*/
|
|
1015
|
+
export function pdfObjIsResolved(obj) {
|
|
1016
|
+
// Direct objects are always "resolved"
|
|
1017
|
+
if (!(obj instanceof PdfIndirectRef)) {
|
|
1018
|
+
return true;
|
|
1019
|
+
}
|
|
1020
|
+
// Indirect references need document context to resolve
|
|
1021
|
+
// This is a placeholder - actual resolution requires document
|
|
1022
|
+
return false;
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Resolve an indirect reference (stub - requires document context)
|
|
1026
|
+
* @param obj The object to resolve
|
|
1027
|
+
* @returns The same object (actual resolution requires document)
|
|
1028
|
+
*/
|
|
1029
|
+
export function pdfResolveIndirect(obj) {
|
|
1030
|
+
// In actual implementation, this would look up the object in the document
|
|
1031
|
+
// For now, return as-is
|
|
1032
|
+
return obj;
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* Load an object from document (stub - requires document context)
|
|
1036
|
+
* @param objNum Object number
|
|
1037
|
+
* @param genNum Generation number
|
|
1038
|
+
* @returns undefined (actual loading requires document)
|
|
1039
|
+
*/
|
|
1040
|
+
export function pdfLoadObject(_objNum, _genNum) {
|
|
1041
|
+
// This is a placeholder - actual implementation would load from document
|
|
1042
|
+
// The real implementation will be in the Document class
|
|
1043
|
+
return undefined;
|
|
1044
|
+
}
|
|
1045
|
+
//# sourceMappingURL=object.js.map
|