@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.
Files changed (170) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +985 -0
  3. package/binding.gyp +73 -0
  4. package/dist/annot.d.ts +458 -0
  5. package/dist/annot.d.ts.map +1 -0
  6. package/dist/annot.js +697 -0
  7. package/dist/annot.js.map +1 -0
  8. package/dist/archive.d.ts +128 -0
  9. package/dist/archive.d.ts.map +1 -0
  10. package/dist/archive.js +268 -0
  11. package/dist/archive.js.map +1 -0
  12. package/dist/buffer.d.ts +572 -0
  13. package/dist/buffer.d.ts.map +1 -0
  14. package/dist/buffer.js +971 -0
  15. package/dist/buffer.js.map +1 -0
  16. package/dist/colorspace.d.ts +287 -0
  17. package/dist/colorspace.d.ts.map +1 -0
  18. package/dist/colorspace.js +542 -0
  19. package/dist/colorspace.js.map +1 -0
  20. package/dist/context.d.ts +184 -0
  21. package/dist/context.d.ts.map +1 -0
  22. package/dist/context.js +320 -0
  23. package/dist/context.js.map +1 -0
  24. package/dist/cookie.d.ts +164 -0
  25. package/dist/cookie.d.ts.map +1 -0
  26. package/dist/cookie.js +306 -0
  27. package/dist/cookie.js.map +1 -0
  28. package/dist/device.d.ts +169 -0
  29. package/dist/device.d.ts.map +1 -0
  30. package/dist/device.js +350 -0
  31. package/dist/device.js.map +1 -0
  32. package/dist/display-list.d.ts +202 -0
  33. package/dist/display-list.d.ts.map +1 -0
  34. package/dist/display-list.js +410 -0
  35. package/dist/display-list.js.map +1 -0
  36. package/dist/document.d.ts +637 -0
  37. package/dist/document.d.ts.map +1 -0
  38. package/dist/document.js +902 -0
  39. package/dist/document.js.map +1 -0
  40. package/dist/easy.d.ts +423 -0
  41. package/dist/easy.d.ts.map +1 -0
  42. package/dist/easy.js +644 -0
  43. package/dist/easy.js.map +1 -0
  44. package/dist/enhanced.d.ts +226 -0
  45. package/dist/enhanced.d.ts.map +1 -0
  46. package/dist/enhanced.js +368 -0
  47. package/dist/enhanced.js.map +1 -0
  48. package/dist/filter.d.ts +51 -0
  49. package/dist/filter.d.ts.map +1 -0
  50. package/dist/filter.js +381 -0
  51. package/dist/filter.js.map +1 -0
  52. package/dist/font.d.ts +222 -0
  53. package/dist/font.d.ts.map +1 -0
  54. package/dist/font.js +381 -0
  55. package/dist/font.js.map +1 -0
  56. package/dist/form.d.ts +214 -0
  57. package/dist/form.d.ts.map +1 -0
  58. package/dist/form.js +497 -0
  59. package/dist/form.js.map +1 -0
  60. package/dist/geometry.d.ts +469 -0
  61. package/dist/geometry.d.ts.map +1 -0
  62. package/dist/geometry.js +780 -0
  63. package/dist/geometry.js.map +1 -0
  64. package/dist/image.d.ts +172 -0
  65. package/dist/image.d.ts.map +1 -0
  66. package/dist/image.js +348 -0
  67. package/dist/image.js.map +1 -0
  68. package/dist/index.d.ts +171 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +339 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/link.d.ts +168 -0
  73. package/dist/link.d.ts.map +1 -0
  74. package/dist/link.js +343 -0
  75. package/dist/link.js.map +1 -0
  76. package/dist/micropdf.d.ts +40 -0
  77. package/dist/micropdf.d.ts.map +1 -0
  78. package/dist/micropdf.js +45 -0
  79. package/dist/micropdf.js.map +1 -0
  80. package/dist/nanopdf.d.ts +40 -0
  81. package/dist/nanopdf.d.ts.map +1 -0
  82. package/dist/nanopdf.js +45 -0
  83. package/dist/nanopdf.js.map +1 -0
  84. package/dist/native.d.ts +242 -0
  85. package/dist/native.d.ts.map +1 -0
  86. package/dist/native.js +509 -0
  87. package/dist/native.js.map +1 -0
  88. package/dist/output.d.ts +166 -0
  89. package/dist/output.d.ts.map +1 -0
  90. package/dist/output.js +365 -0
  91. package/dist/output.js.map +1 -0
  92. package/dist/path.d.ts +420 -0
  93. package/dist/path.d.ts.map +1 -0
  94. package/dist/path.js +687 -0
  95. package/dist/path.js.map +1 -0
  96. package/dist/pdf/object.d.ts +489 -0
  97. package/dist/pdf/object.d.ts.map +1 -0
  98. package/dist/pdf/object.js +1045 -0
  99. package/dist/pdf/object.js.map +1 -0
  100. package/dist/pixmap.d.ts +315 -0
  101. package/dist/pixmap.d.ts.map +1 -0
  102. package/dist/pixmap.js +590 -0
  103. package/dist/pixmap.js.map +1 -0
  104. package/dist/profiler.d.ts +159 -0
  105. package/dist/profiler.d.ts.map +1 -0
  106. package/dist/profiler.js +380 -0
  107. package/dist/profiler.js.map +1 -0
  108. package/dist/render-options.d.ts +227 -0
  109. package/dist/render-options.d.ts.map +1 -0
  110. package/dist/render-options.js +130 -0
  111. package/dist/render-options.js.map +1 -0
  112. package/dist/resource-tracking.d.ts +332 -0
  113. package/dist/resource-tracking.d.ts.map +1 -0
  114. package/dist/resource-tracking.js +653 -0
  115. package/dist/resource-tracking.js.map +1 -0
  116. package/dist/simple.d.ts +276 -0
  117. package/dist/simple.d.ts.map +1 -0
  118. package/dist/simple.js +343 -0
  119. package/dist/simple.js.map +1 -0
  120. package/dist/stext.d.ts +290 -0
  121. package/dist/stext.d.ts.map +1 -0
  122. package/dist/stext.js +312 -0
  123. package/dist/stext.js.map +1 -0
  124. package/dist/stream.d.ts +174 -0
  125. package/dist/stream.d.ts.map +1 -0
  126. package/dist/stream.js +476 -0
  127. package/dist/stream.js.map +1 -0
  128. package/dist/text.d.ts +337 -0
  129. package/dist/text.d.ts.map +1 -0
  130. package/dist/text.js +454 -0
  131. package/dist/text.js.map +1 -0
  132. package/dist/typed-arrays.d.ts +127 -0
  133. package/dist/typed-arrays.d.ts.map +1 -0
  134. package/dist/typed-arrays.js +410 -0
  135. package/dist/typed-arrays.js.map +1 -0
  136. package/dist/types.d.ts +358 -0
  137. package/dist/types.d.ts.map +1 -0
  138. package/dist/types.js +216 -0
  139. package/dist/types.js.map +1 -0
  140. package/native/annot.cc +557 -0
  141. package/native/buffer.cc +204 -0
  142. package/native/colorspace.cc +166 -0
  143. package/native/context.cc +84 -0
  144. package/native/cookie.cc +179 -0
  145. package/native/device.cc +179 -0
  146. package/native/display_list.cc +179 -0
  147. package/native/document.cc +268 -0
  148. package/native/enhanced.cc +70 -0
  149. package/native/font.cc +282 -0
  150. package/native/form.cc +523 -0
  151. package/native/geometry.cc +255 -0
  152. package/native/image.cc +216 -0
  153. package/native/include/micropdf/enhanced.h +38 -0
  154. package/native/include/micropdf/types.h +36 -0
  155. package/native/include/micropdf.h +106 -0
  156. package/native/include/mupdf-ffi.h +39 -0
  157. package/native/include/mupdf.h +11 -0
  158. package/native/include/mupdf_minimal.h +381 -0
  159. package/native/lib/linux-x64/libmicropdf.a +0 -0
  160. package/native/link.cc +234 -0
  161. package/native/micropdf.cc +71 -0
  162. package/native/output.cc +229 -0
  163. package/native/page.cc +572 -0
  164. package/native/path.cc +259 -0
  165. package/native/pixmap.cc +240 -0
  166. package/native/stext.cc +610 -0
  167. package/native/stream.cc +239 -0
  168. package/package.json +120 -0
  169. package/scripts/build-from-rust.js +97 -0
  170. 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