@libpdf/core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +37 -44
- package/dist/index.mjs +1143 -1485
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { createCMSECDSASignature } from "pkijs";
|
|
|
9
9
|
import { base64 } from "@scure/base";
|
|
10
10
|
|
|
11
11
|
//#region package.json
|
|
12
|
-
var version = "0.
|
|
12
|
+
var version = "0.2.0";
|
|
13
13
|
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/objects/pdf-array.ts
|
|
@@ -44,9 +44,12 @@ var PdfArray = class PdfArray {
|
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
46
|
* Get item at index. Returns undefined if out of bounds.
|
|
47
|
+
* If resolver is provided, resolves indirect references.
|
|
47
48
|
*/
|
|
48
|
-
at(index) {
|
|
49
|
-
|
|
49
|
+
at(index, resolver) {
|
|
50
|
+
const value = this.items.at(index);
|
|
51
|
+
if (resolver && value?.type === "ref") return resolver(value) ?? void 0;
|
|
52
|
+
return value;
|
|
50
53
|
}
|
|
51
54
|
/**
|
|
52
55
|
* Set item at index. Extends array if needed.
|
|
@@ -403,6 +406,69 @@ var PdfName = class PdfName {
|
|
|
403
406
|
}
|
|
404
407
|
};
|
|
405
408
|
|
|
409
|
+
//#endregion
|
|
410
|
+
//#region src/objects/pdf-ref.ts
|
|
411
|
+
/**
|
|
412
|
+
* Default cache size for PdfRef interning.
|
|
413
|
+
* Object references tend to be more numerous than names in typical PDFs.
|
|
414
|
+
*/
|
|
415
|
+
const DEFAULT_REF_CACHE_SIZE = 2e4;
|
|
416
|
+
/**
|
|
417
|
+
* PDF indirect reference (interned).
|
|
418
|
+
*
|
|
419
|
+
* In PDF: `1 0 R`, `42 0 R`
|
|
420
|
+
*
|
|
421
|
+
* References are interned using an LRU cache to prevent unbounded memory growth.
|
|
422
|
+
* `PdfRef.of(1, 0) === PdfRef.of(1, 0)` as long as both are in cache.
|
|
423
|
+
* Use `.of()` to get or create instances.
|
|
424
|
+
*/
|
|
425
|
+
var PdfRef = class PdfRef {
|
|
426
|
+
get type() {
|
|
427
|
+
return "ref";
|
|
428
|
+
}
|
|
429
|
+
static cache = new LRUCache(DEFAULT_REF_CACHE_SIZE);
|
|
430
|
+
constructor(objectNumber, generation) {
|
|
431
|
+
this.objectNumber = objectNumber;
|
|
432
|
+
this.generation = generation;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Get or create an interned PdfRef for the given object/generation pair.
|
|
436
|
+
*/
|
|
437
|
+
static of(objectNumber, generation = 0) {
|
|
438
|
+
const key$1 = `${objectNumber} ${generation}`;
|
|
439
|
+
let cached = PdfRef.cache.get(key$1);
|
|
440
|
+
if (!cached) {
|
|
441
|
+
cached = new PdfRef(objectNumber, generation);
|
|
442
|
+
PdfRef.cache.set(key$1, cached);
|
|
443
|
+
}
|
|
444
|
+
return cached;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Clear the reference cache.
|
|
448
|
+
*
|
|
449
|
+
* Useful for long-running applications that process many PDFs
|
|
450
|
+
* and want to reclaim memory between documents.
|
|
451
|
+
*/
|
|
452
|
+
static clearCache() {
|
|
453
|
+
PdfRef.cache.clear();
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Get the current size of the LRU cache.
|
|
457
|
+
*/
|
|
458
|
+
static get cacheSize() {
|
|
459
|
+
return PdfRef.cache.size;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Returns the PDF syntax representation: "1 0 R"
|
|
463
|
+
*/
|
|
464
|
+
toString() {
|
|
465
|
+
return `${this.objectNumber} ${this.generation} R`;
|
|
466
|
+
}
|
|
467
|
+
toBytes(writer) {
|
|
468
|
+
writer.writeAscii(`${this.objectNumber} ${this.generation} R`);
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
|
|
406
472
|
//#endregion
|
|
407
473
|
//#region src/objects/pdf-dict.ts
|
|
408
474
|
/**
|
|
@@ -441,9 +507,11 @@ var PdfDict = class PdfDict {
|
|
|
441
507
|
/**
|
|
442
508
|
* Get value for key. Key can be string or PdfName.
|
|
443
509
|
*/
|
|
444
|
-
get(key$1) {
|
|
510
|
+
get(key$1, resolver) {
|
|
445
511
|
const name = typeof key$1 === "string" ? PdfName.of(key$1) : key$1;
|
|
446
|
-
|
|
512
|
+
const value = this.entries.get(name);
|
|
513
|
+
if (resolver && value?.type === "ref") return resolver(value) ?? void 0;
|
|
514
|
+
return value;
|
|
447
515
|
}
|
|
448
516
|
/**
|
|
449
517
|
* Set value for key. Key can be string or PdfName.
|
|
@@ -482,34 +550,38 @@ var PdfDict = class PdfDict {
|
|
|
482
550
|
yield* this.entries;
|
|
483
551
|
}
|
|
484
552
|
/**
|
|
485
|
-
* Typed getters
|
|
553
|
+
* Typed getters.
|
|
554
|
+
*
|
|
555
|
+
* All typed getters accept an optional resolver function. When provided,
|
|
556
|
+
* if the value is a PdfRef, it will be automatically dereferenced.
|
|
557
|
+
* This prevents the common bug of forgetting to handle indirect references.
|
|
486
558
|
*/
|
|
487
|
-
getName(key$1) {
|
|
488
|
-
const value = this.get(key$1);
|
|
559
|
+
getName(key$1, resolver) {
|
|
560
|
+
const value = this.get(key$1, resolver);
|
|
489
561
|
return value?.type === "name" ? value : void 0;
|
|
490
562
|
}
|
|
491
|
-
getNumber(key$1) {
|
|
492
|
-
const value = this.get(key$1);
|
|
563
|
+
getNumber(key$1, resolver) {
|
|
564
|
+
const value = this.get(key$1, resolver);
|
|
493
565
|
return value?.type === "number" ? value : void 0;
|
|
494
566
|
}
|
|
495
|
-
getString(key$1) {
|
|
496
|
-
const value = this.get(key$1);
|
|
567
|
+
getString(key$1, resolver) {
|
|
568
|
+
const value = this.get(key$1, resolver);
|
|
497
569
|
return value?.type === "string" ? value : void 0;
|
|
498
570
|
}
|
|
499
|
-
getArray(key$1) {
|
|
500
|
-
const value = this.get(key$1);
|
|
571
|
+
getArray(key$1, resolver) {
|
|
572
|
+
const value = this.get(key$1, resolver);
|
|
501
573
|
return value?.type === "array" ? value : void 0;
|
|
502
574
|
}
|
|
503
|
-
getDict(key$1) {
|
|
504
|
-
const value = this.get(key$1);
|
|
575
|
+
getDict(key$1, resolver) {
|
|
576
|
+
const value = this.get(key$1, resolver);
|
|
505
577
|
return value?.type === "dict" ? value : void 0;
|
|
506
578
|
}
|
|
507
579
|
getRef(key$1) {
|
|
508
580
|
const value = this.get(key$1);
|
|
509
581
|
return value?.type === "ref" ? value : void 0;
|
|
510
582
|
}
|
|
511
|
-
getBool(key$1) {
|
|
512
|
-
const value = this.get(key$1);
|
|
583
|
+
getBool(key$1, resolver) {
|
|
584
|
+
const value = this.get(key$1, resolver);
|
|
513
585
|
return value?.type === "bool" ? value : void 0;
|
|
514
586
|
}
|
|
515
587
|
/**
|
|
@@ -2589,69 +2661,6 @@ const drawXObject = (name) => Operator.of(Op.DrawXObject, name);
|
|
|
2589
2661
|
const beginMarkedContent = (tag) => Operator.of(Op.BeginMarkedContent, tag);
|
|
2590
2662
|
const endMarkedContent = () => Operator.of(Op.EndMarkedContent);
|
|
2591
2663
|
|
|
2592
|
-
//#endregion
|
|
2593
|
-
//#region src/objects/pdf-ref.ts
|
|
2594
|
-
/**
|
|
2595
|
-
* Default cache size for PdfRef interning.
|
|
2596
|
-
* Object references tend to be more numerous than names in typical PDFs.
|
|
2597
|
-
*/
|
|
2598
|
-
const DEFAULT_REF_CACHE_SIZE = 2e4;
|
|
2599
|
-
/**
|
|
2600
|
-
* PDF indirect reference (interned).
|
|
2601
|
-
*
|
|
2602
|
-
* In PDF: `1 0 R`, `42 0 R`
|
|
2603
|
-
*
|
|
2604
|
-
* References are interned using an LRU cache to prevent unbounded memory growth.
|
|
2605
|
-
* `PdfRef.of(1, 0) === PdfRef.of(1, 0)` as long as both are in cache.
|
|
2606
|
-
* Use `.of()` to get or create instances.
|
|
2607
|
-
*/
|
|
2608
|
-
var PdfRef = class PdfRef {
|
|
2609
|
-
get type() {
|
|
2610
|
-
return "ref";
|
|
2611
|
-
}
|
|
2612
|
-
static cache = new LRUCache(DEFAULT_REF_CACHE_SIZE);
|
|
2613
|
-
constructor(objectNumber, generation) {
|
|
2614
|
-
this.objectNumber = objectNumber;
|
|
2615
|
-
this.generation = generation;
|
|
2616
|
-
}
|
|
2617
|
-
/**
|
|
2618
|
-
* Get or create an interned PdfRef for the given object/generation pair.
|
|
2619
|
-
*/
|
|
2620
|
-
static of(objectNumber, generation = 0) {
|
|
2621
|
-
const key$1 = `${objectNumber} ${generation}`;
|
|
2622
|
-
let cached = PdfRef.cache.get(key$1);
|
|
2623
|
-
if (!cached) {
|
|
2624
|
-
cached = new PdfRef(objectNumber, generation);
|
|
2625
|
-
PdfRef.cache.set(key$1, cached);
|
|
2626
|
-
}
|
|
2627
|
-
return cached;
|
|
2628
|
-
}
|
|
2629
|
-
/**
|
|
2630
|
-
* Clear the reference cache.
|
|
2631
|
-
*
|
|
2632
|
-
* Useful for long-running applications that process many PDFs
|
|
2633
|
-
* and want to reclaim memory between documents.
|
|
2634
|
-
*/
|
|
2635
|
-
static clearCache() {
|
|
2636
|
-
PdfRef.cache.clear();
|
|
2637
|
-
}
|
|
2638
|
-
/**
|
|
2639
|
-
* Get the current size of the LRU cache.
|
|
2640
|
-
*/
|
|
2641
|
-
static get cacheSize() {
|
|
2642
|
-
return PdfRef.cache.size;
|
|
2643
|
-
}
|
|
2644
|
-
/**
|
|
2645
|
-
* Returns the PDF syntax representation: "1 0 R"
|
|
2646
|
-
*/
|
|
2647
|
-
toString() {
|
|
2648
|
-
return `${this.objectNumber} ${this.generation} R`;
|
|
2649
|
-
}
|
|
2650
|
-
toBytes(writer) {
|
|
2651
|
-
writer.writeAscii(`${this.objectNumber} ${this.generation} R`);
|
|
2652
|
-
}
|
|
2653
|
-
};
|
|
2654
|
-
|
|
2655
2664
|
//#endregion
|
|
2656
2665
|
//#region src/helpers/colors.ts
|
|
2657
2666
|
/**
|
|
@@ -3478,14 +3487,14 @@ var PDFAnnotation = class {
|
|
|
3478
3487
|
* Annotation subtype (e.g., "Text", "Highlight", "Link").
|
|
3479
3488
|
*/
|
|
3480
3489
|
get type() {
|
|
3481
|
-
const subtype = this.dict.getName("Subtype")?.value;
|
|
3490
|
+
const subtype = this.dict.getName("Subtype", this.registry.resolve.bind(this.registry))?.value;
|
|
3482
3491
|
return isAnnotationSubtype(subtype) ? subtype : "Text";
|
|
3483
3492
|
}
|
|
3484
3493
|
/**
|
|
3485
3494
|
* Annotation rectangle in page coordinates.
|
|
3486
3495
|
*/
|
|
3487
3496
|
get rect() {
|
|
3488
|
-
const arr = this.dict.getArray("Rect");
|
|
3497
|
+
const arr = this.dict.getArray("Rect", this.registry.resolve.bind(this.registry));
|
|
3489
3498
|
if (!arr || arr.length < 4) return {
|
|
3490
3499
|
x: 0,
|
|
3491
3500
|
y: 0,
|
|
@@ -3504,7 +3513,7 @@ var PDFAnnotation = class {
|
|
|
3504
3513
|
* Set the annotation rectangle.
|
|
3505
3514
|
*/
|
|
3506
3515
|
setRect(rect) {
|
|
3507
|
-
const arr = this.dict.getArray("Rect");
|
|
3516
|
+
const arr = this.dict.getArray("Rect", this.registry.resolve.bind(this.registry));
|
|
3508
3517
|
if (arr && arr.length >= 4) {
|
|
3509
3518
|
arr.set(0, PdfNumber.of(rect.x));
|
|
3510
3519
|
arr.set(1, PdfNumber.of(rect.y));
|
|
@@ -3522,7 +3531,7 @@ var PDFAnnotation = class {
|
|
|
3522
3531
|
* Text content or description of the annotation.
|
|
3523
3532
|
*/
|
|
3524
3533
|
get contents() {
|
|
3525
|
-
return this.dict.getString("Contents")?.asString() ?? null;
|
|
3534
|
+
return this.dict.getString("Contents", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3526
3535
|
}
|
|
3527
3536
|
/**
|
|
3528
3537
|
* Set the annotation contents.
|
|
@@ -3535,7 +3544,7 @@ var PDFAnnotation = class {
|
|
|
3535
3544
|
* Annotation name (unique identifier within page).
|
|
3536
3545
|
*/
|
|
3537
3546
|
get name() {
|
|
3538
|
-
return this.dict.getString("NM")?.asString() ?? null;
|
|
3547
|
+
return this.dict.getString("NM", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3539
3548
|
}
|
|
3540
3549
|
/**
|
|
3541
3550
|
* Set the annotation name.
|
|
@@ -3548,7 +3557,7 @@ var PDFAnnotation = class {
|
|
|
3548
3557
|
* Modification date.
|
|
3549
3558
|
*/
|
|
3550
3559
|
get modificationDate() {
|
|
3551
|
-
return this.dict.getString("M")?.asString() ?? null;
|
|
3560
|
+
return this.dict.getString("M", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3552
3561
|
}
|
|
3553
3562
|
/**
|
|
3554
3563
|
* Set the modification date (PDF date format).
|
|
@@ -3561,7 +3570,7 @@ var PDFAnnotation = class {
|
|
|
3561
3570
|
* Annotation flags.
|
|
3562
3571
|
*/
|
|
3563
3572
|
get flags() {
|
|
3564
|
-
return this.dict.getNumber("F")?.value ?? 0;
|
|
3573
|
+
return this.dict.getNumber("F", this.registry.resolve.bind(this.registry))?.value ?? 0;
|
|
3565
3574
|
}
|
|
3566
3575
|
/**
|
|
3567
3576
|
* Check if the annotation has a specific flag set.
|
|
@@ -3607,7 +3616,7 @@ var PDFAnnotation = class {
|
|
|
3607
3616
|
* Annotation color.
|
|
3608
3617
|
*/
|
|
3609
3618
|
get color() {
|
|
3610
|
-
return parseColorArray(this.dict.getArray("C"));
|
|
3619
|
+
return parseColorArray(this.dict.getArray("C", this.registry.resolve.bind(this.registry)));
|
|
3611
3620
|
}
|
|
3612
3621
|
/**
|
|
3613
3622
|
* Set the annotation color.
|
|
@@ -3621,13 +3630,13 @@ var PDFAnnotation = class {
|
|
|
3621
3630
|
* Get the border style.
|
|
3622
3631
|
*/
|
|
3623
3632
|
getBorderStyle() {
|
|
3624
|
-
const bs = this.dict.getDict("BS");
|
|
3633
|
+
const bs = this.dict.getDict("BS", this.registry.resolve.bind(this.registry));
|
|
3625
3634
|
if (!bs) return null;
|
|
3626
3635
|
const result = {
|
|
3627
|
-
width: bs.getNumber("W")?.value ?? 1,
|
|
3628
|
-
style: BORDER_STYLE_MAP[bs.getName("S")?.value ?? "S"] ?? "solid"
|
|
3636
|
+
width: bs.getNumber("W", this.registry.resolve.bind(this.registry))?.value ?? 1,
|
|
3637
|
+
style: BORDER_STYLE_MAP[bs.getName("S", this.registry.resolve.bind(this.registry))?.value ?? "S"] ?? "solid"
|
|
3629
3638
|
};
|
|
3630
|
-
const dashArr = bs.getArray("D");
|
|
3639
|
+
const dashArr = bs.getArray("D", this.registry.resolve.bind(this.registry));
|
|
3631
3640
|
if (dashArr) {
|
|
3632
3641
|
result.dashArray = [];
|
|
3633
3642
|
for (let i = 0; i < dashArr.length; i++) {
|
|
@@ -3652,9 +3661,8 @@ var PDFAnnotation = class {
|
|
|
3652
3661
|
* Check if the annotation has a normal appearance stream.
|
|
3653
3662
|
*/
|
|
3654
3663
|
hasNormalAppearance() {
|
|
3655
|
-
|
|
3656
|
-
if (ap
|
|
3657
|
-
if (ap instanceof PdfDict) return ap.has("N");
|
|
3664
|
+
const ap = this.dict.getDict("AP", this.registry.resolve.bind(this.registry));
|
|
3665
|
+
if (ap) return ap.has("N");
|
|
3658
3666
|
return false;
|
|
3659
3667
|
}
|
|
3660
3668
|
/**
|
|
@@ -3697,12 +3705,9 @@ var PDFAnnotation = class {
|
|
|
3697
3705
|
* Get an appearance stream by type.
|
|
3698
3706
|
*/
|
|
3699
3707
|
getAppearance(type) {
|
|
3700
|
-
let ap = this.dict.
|
|
3701
|
-
if (ap
|
|
3702
|
-
|
|
3703
|
-
let entry = ap.get(type);
|
|
3704
|
-
if (!entry) return null;
|
|
3705
|
-
if (entry instanceof PdfRef) entry = this.registry.resolve(entry) ?? void 0;
|
|
3708
|
+
let ap = this.dict.getDict("AP", this.registry.resolve.bind(this.registry));
|
|
3709
|
+
if (!ap) return null;
|
|
3710
|
+
let entry = ap.get(type, this.registry.resolve.bind(this.registry));
|
|
3706
3711
|
if (entry instanceof PdfStream) return entry;
|
|
3707
3712
|
return null;
|
|
3708
3713
|
}
|
|
@@ -3710,8 +3715,7 @@ var PDFAnnotation = class {
|
|
|
3710
3715
|
* Set an appearance stream by type.
|
|
3711
3716
|
*/
|
|
3712
3717
|
setAppearance(type, stream) {
|
|
3713
|
-
let ap = this.dict.
|
|
3714
|
-
if (ap instanceof PdfRef) ap = this.registry.resolve(ap) ?? void 0;
|
|
3718
|
+
let ap = this.dict.getDict("AP", this.registry.resolve.bind(this.registry));
|
|
3715
3719
|
if (ap instanceof PdfDict) {
|
|
3716
3720
|
const streamRef = this.registry.register(stream);
|
|
3717
3721
|
ap.set(type, streamRef);
|
|
@@ -3823,7 +3827,7 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
|
|
|
3823
3827
|
* Text label for the annotation (often the author name).
|
|
3824
3828
|
*/
|
|
3825
3829
|
get title() {
|
|
3826
|
-
return this.dict.getString("T")?.asString() ?? null;
|
|
3830
|
+
return this.dict.getString("T", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3827
3831
|
}
|
|
3828
3832
|
/**
|
|
3829
3833
|
* Set the title/author.
|
|
@@ -3837,7 +3841,7 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
|
|
|
3837
3841
|
* Range 0-1, where 0 is fully transparent and 1 is fully opaque.
|
|
3838
3842
|
*/
|
|
3839
3843
|
get opacity() {
|
|
3840
|
-
return this.dict.getNumber("CA")?.value ?? 1;
|
|
3844
|
+
return this.dict.getNumber("CA", this.registry.resolve.bind(this.registry))?.value ?? 1;
|
|
3841
3845
|
}
|
|
3842
3846
|
/**
|
|
3843
3847
|
* Set the opacity.
|
|
@@ -3851,7 +3855,7 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
|
|
|
3851
3855
|
* Creation date (CreationDate).
|
|
3852
3856
|
*/
|
|
3853
3857
|
get creationDate() {
|
|
3854
|
-
return this.dict.getString("CreationDate")?.asString() ?? null;
|
|
3858
|
+
return this.dict.getString("CreationDate", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3855
3859
|
}
|
|
3856
3860
|
/**
|
|
3857
3861
|
* Set the creation date.
|
|
@@ -3864,7 +3868,7 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
|
|
|
3864
3868
|
* Subject - the subject of the annotation.
|
|
3865
3869
|
*/
|
|
3866
3870
|
get subject() {
|
|
3867
|
-
return this.dict.getString("Subj")?.asString() ?? null;
|
|
3871
|
+
return this.dict.getString("Subj", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3868
3872
|
}
|
|
3869
3873
|
/**
|
|
3870
3874
|
* Set the subject.
|
|
@@ -3929,7 +3933,7 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
|
|
|
3929
3933
|
* Intent (IT) - the intent of the markup annotation.
|
|
3930
3934
|
*/
|
|
3931
3935
|
get intent() {
|
|
3932
|
-
return this.dict.getName("IT")?.value ?? null;
|
|
3936
|
+
return this.dict.getName("IT", this.registry.resolve.bind(this.registry))?.value ?? null;
|
|
3933
3937
|
}
|
|
3934
3938
|
};
|
|
3935
3939
|
|
|
@@ -3952,7 +3956,7 @@ var PDFCaretAnnotation = class extends PDFMarkupAnnotation {
|
|
|
3952
3956
|
* "P" = paragraph symbol, "None" = no symbol.
|
|
3953
3957
|
*/
|
|
3954
3958
|
get symbol() {
|
|
3955
|
-
if (this.dict.getName("Sy")?.value === "P") return "P";
|
|
3959
|
+
if (this.dict.getName("Sy", this.registry.resolve.bind(this.registry))?.value === "P") return "P";
|
|
3956
3960
|
return "None";
|
|
3957
3961
|
}
|
|
3958
3962
|
/**
|
|
@@ -3974,7 +3978,7 @@ var PDFFileAttachmentAnnotation = class extends PDFMarkupAnnotation {
|
|
|
3974
3978
|
* Icon to display.
|
|
3975
3979
|
*/
|
|
3976
3980
|
get icon() {
|
|
3977
|
-
const name = this.dict.getName("Name");
|
|
3981
|
+
const name = this.dict.getName("Name", this.registry.resolve.bind(this.registry));
|
|
3978
3982
|
if (!name) return "PushPin";
|
|
3979
3983
|
if (isFileAttachmentIcon(name.value)) return name.value;
|
|
3980
3984
|
return "PushPin";
|
|
@@ -3997,11 +4001,7 @@ var PDFFileAttachmentAnnotation = class extends PDFMarkupAnnotation {
|
|
|
3997
4001
|
* Get the file specification dictionary.
|
|
3998
4002
|
*/
|
|
3999
4003
|
getFileSpec() {
|
|
4000
|
-
|
|
4001
|
-
if (!fsRef) return this.dict.getDict("FS") ?? null;
|
|
4002
|
-
const resolved = this.registry.resolve(fsRef);
|
|
4003
|
-
if (resolved && resolved.type === "dict") return resolved;
|
|
4004
|
-
return null;
|
|
4004
|
+
return this.dict.getDict("FS", this.registry.resolve.bind(this.registry)) ?? null;
|
|
4005
4005
|
}
|
|
4006
4006
|
/**
|
|
4007
4007
|
* Get the file name from the file specification.
|
|
@@ -4009,9 +4009,9 @@ var PDFFileAttachmentAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4009
4009
|
getFileName() {
|
|
4010
4010
|
const fs = this.getFileSpec();
|
|
4011
4011
|
if (!fs) return null;
|
|
4012
|
-
const uf = fs.getString("UF");
|
|
4012
|
+
const uf = fs.getString("UF", this.registry.resolve.bind(this.registry));
|
|
4013
4013
|
if (uf) return uf.asString();
|
|
4014
|
-
const f = fs.getString("F");
|
|
4014
|
+
const f = fs.getString("F", this.registry.resolve.bind(this.registry));
|
|
4015
4015
|
if (f) return f.asString();
|
|
4016
4016
|
return null;
|
|
4017
4017
|
}
|
|
@@ -4036,7 +4036,7 @@ var PDFFreeTextAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4036
4036
|
* Contains font and color operators.
|
|
4037
4037
|
*/
|
|
4038
4038
|
get defaultAppearance() {
|
|
4039
|
-
return this.dict.getString("DA")?.asString() ?? null;
|
|
4039
|
+
return this.dict.getString("DA", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
4040
4040
|
}
|
|
4041
4041
|
/**
|
|
4042
4042
|
* Set the default appearance.
|
|
@@ -4049,7 +4049,7 @@ var PDFFreeTextAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4049
4049
|
* Text justification: 0=left, 1=center, 2=right.
|
|
4050
4050
|
*/
|
|
4051
4051
|
get justification() {
|
|
4052
|
-
switch (this.dict.getNumber("Q")?.value ?? 0) {
|
|
4052
|
+
switch (this.dict.getNumber("Q", this.registry.resolve.bind(this.registry))?.value ?? 0) {
|
|
4053
4053
|
case 1: return "center";
|
|
4054
4054
|
case 2: return "right";
|
|
4055
4055
|
default: return "left";
|
|
@@ -4070,7 +4070,7 @@ var PDFFreeTextAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4070
4070
|
* Contains CSS-style formatting.
|
|
4071
4071
|
*/
|
|
4072
4072
|
get defaultStyle() {
|
|
4073
|
-
return this.dict.getString("DS")?.asString() ?? null;
|
|
4073
|
+
return this.dict.getString("DS", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
4074
4074
|
}
|
|
4075
4075
|
/**
|
|
4076
4076
|
* Set the default style.
|
|
@@ -4084,7 +4084,7 @@ var PDFFreeTextAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4084
4084
|
* Can be "FreeText", "FreeTextCallout", or "FreeTextTypeWriter".
|
|
4085
4085
|
*/
|
|
4086
4086
|
get freeTextIntent() {
|
|
4087
|
-
return this.dict.getName("IT")?.value ?? null;
|
|
4087
|
+
return this.dict.getName("IT", this.registry.resolve.bind(this.registry))?.value ?? null;
|
|
4088
4088
|
}
|
|
4089
4089
|
/**
|
|
4090
4090
|
* Set the intent.
|
|
@@ -4161,7 +4161,7 @@ var PDFInkAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4161
4161
|
* Each path is an array of points.
|
|
4162
4162
|
*/
|
|
4163
4163
|
get inkPaths() {
|
|
4164
|
-
const inkList = this.dict.getArray("InkList");
|
|
4164
|
+
const inkList = this.dict.getArray("InkList", this.registry.resolve.bind(this.registry));
|
|
4165
4165
|
if (!inkList) return [];
|
|
4166
4166
|
const paths = [];
|
|
4167
4167
|
for (let i = 0; i < inkList.length; i++) {
|
|
@@ -4266,7 +4266,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4266
4266
|
* Get the line endpoints.
|
|
4267
4267
|
*/
|
|
4268
4268
|
get lineEndpoints() {
|
|
4269
|
-
const l = this.dict.getArray("L");
|
|
4269
|
+
const l = this.dict.getArray("L", this.registry.resolve.bind(this.registry));
|
|
4270
4270
|
if (!l || l.length < 4) return {
|
|
4271
4271
|
start: {
|
|
4272
4272
|
x: 0,
|
|
@@ -4293,7 +4293,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4293
4293
|
* Set the line endpoints.
|
|
4294
4294
|
*/
|
|
4295
4295
|
setLineEndpoints(start, end) {
|
|
4296
|
-
const arr = this.dict.getArray("L");
|
|
4296
|
+
const arr = this.dict.getArray("L", this.registry.resolve.bind(this.registry));
|
|
4297
4297
|
if (arr && arr.length >= 4) {
|
|
4298
4298
|
arr.set(0, PdfNumber.of(start.x));
|
|
4299
4299
|
arr.set(1, PdfNumber.of(start.y));
|
|
@@ -4323,7 +4323,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4323
4323
|
* Line ending styles [start, end].
|
|
4324
4324
|
*/
|
|
4325
4325
|
get lineEndingStyles() {
|
|
4326
|
-
const le = this.dict.getArray("LE");
|
|
4326
|
+
const le = this.dict.getArray("LE", this.registry.resolve.bind(this.registry));
|
|
4327
4327
|
if (!le || le.length < 2) return ["None", "None"];
|
|
4328
4328
|
const [startStyle, endStyle] = le.toArray().map((item) => item instanceof PdfName ? item.value : "None");
|
|
4329
4329
|
return [startStyle ?? "None", endStyle ?? "None"];
|
|
@@ -4339,7 +4339,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4339
4339
|
* Interior color (fill color for closed arrow heads).
|
|
4340
4340
|
*/
|
|
4341
4341
|
get interiorColor() {
|
|
4342
|
-
return parseColorArray(this.dict.getArray("IC"));
|
|
4342
|
+
return parseColorArray(this.dict.getArray("IC", this.registry.resolve.bind(this.registry)));
|
|
4343
4343
|
}
|
|
4344
4344
|
/**
|
|
4345
4345
|
* Set the interior color.
|
|
@@ -4353,19 +4353,19 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4353
4353
|
* Line leader length (for dimension lines).
|
|
4354
4354
|
*/
|
|
4355
4355
|
get leaderLength() {
|
|
4356
|
-
return this.dict.getNumber("LL")?.value ?? 0;
|
|
4356
|
+
return this.dict.getNumber("LL", this.registry.resolve.bind(this.registry))?.value ?? 0;
|
|
4357
4357
|
}
|
|
4358
4358
|
/**
|
|
4359
4359
|
* Line leader line extension.
|
|
4360
4360
|
*/
|
|
4361
4361
|
get leaderExtension() {
|
|
4362
|
-
return this.dict.getNumber("LLE")?.value ?? 0;
|
|
4362
|
+
return this.dict.getNumber("LLE", this.registry.resolve.bind(this.registry))?.value ?? 0;
|
|
4363
4363
|
}
|
|
4364
4364
|
/**
|
|
4365
4365
|
* Caption flag - whether to show caption with the line.
|
|
4366
4366
|
*/
|
|
4367
4367
|
get hasCaption() {
|
|
4368
|
-
return this.dict.getBool("Cap")?.value ?? false;
|
|
4368
|
+
return this.dict.getBool("Cap", this.registry.resolve.bind(this.registry))?.value ?? false;
|
|
4369
4369
|
}
|
|
4370
4370
|
/**
|
|
4371
4371
|
* Line width from border style.
|
|
@@ -4872,240 +4872,6 @@ function rectsToQuadPoints(rects) {
|
|
|
4872
4872
|
return rects.map(rectToQuadPoints);
|
|
4873
4873
|
}
|
|
4874
4874
|
|
|
4875
|
-
//#endregion
|
|
4876
|
-
//#region src/helpers/unicode.ts
|
|
4877
|
-
/**
|
|
4878
|
-
* Unicode utilities for PDF text handling.
|
|
4879
|
-
*
|
|
4880
|
-
* Provides mappings between Unicode code points and PostScript glyph names.
|
|
4881
|
-
*/
|
|
4882
|
-
/**
|
|
4883
|
-
* Map Unicode code point to PostScript glyph name.
|
|
4884
|
-
* Returns undefined if no mapping exists.
|
|
4885
|
-
*/
|
|
4886
|
-
function unicodeToGlyphName(unicode) {
|
|
4887
|
-
return UNICODE_TO_GLYPH.get(unicode);
|
|
4888
|
-
}
|
|
4889
|
-
/**
|
|
4890
|
-
* Common Unicode to glyph name mappings.
|
|
4891
|
-
* Covers ASCII and common Latin-1 extended characters.
|
|
4892
|
-
*
|
|
4893
|
-
* For a complete mapping, see the Adobe Glyph List:
|
|
4894
|
-
* https://github.com/adobe-type-tools/agl-aglfn
|
|
4895
|
-
*/
|
|
4896
|
-
const UNICODE_TO_GLYPH = new Map([
|
|
4897
|
-
[32, "space"],
|
|
4898
|
-
[33, "exclam"],
|
|
4899
|
-
[34, "quotedbl"],
|
|
4900
|
-
[35, "numbersign"],
|
|
4901
|
-
[36, "dollar"],
|
|
4902
|
-
[37, "percent"],
|
|
4903
|
-
[38, "ampersand"],
|
|
4904
|
-
[39, "quotesingle"],
|
|
4905
|
-
[40, "parenleft"],
|
|
4906
|
-
[41, "parenright"],
|
|
4907
|
-
[42, "asterisk"],
|
|
4908
|
-
[43, "plus"],
|
|
4909
|
-
[44, "comma"],
|
|
4910
|
-
[45, "hyphen"],
|
|
4911
|
-
[46, "period"],
|
|
4912
|
-
[47, "slash"],
|
|
4913
|
-
[48, "zero"],
|
|
4914
|
-
[49, "one"],
|
|
4915
|
-
[50, "two"],
|
|
4916
|
-
[51, "three"],
|
|
4917
|
-
[52, "four"],
|
|
4918
|
-
[53, "five"],
|
|
4919
|
-
[54, "six"],
|
|
4920
|
-
[55, "seven"],
|
|
4921
|
-
[56, "eight"],
|
|
4922
|
-
[57, "nine"],
|
|
4923
|
-
[58, "colon"],
|
|
4924
|
-
[59, "semicolon"],
|
|
4925
|
-
[60, "less"],
|
|
4926
|
-
[61, "equal"],
|
|
4927
|
-
[62, "greater"],
|
|
4928
|
-
[63, "question"],
|
|
4929
|
-
[64, "at"],
|
|
4930
|
-
[65, "A"],
|
|
4931
|
-
[66, "B"],
|
|
4932
|
-
[67, "C"],
|
|
4933
|
-
[68, "D"],
|
|
4934
|
-
[69, "E"],
|
|
4935
|
-
[70, "F"],
|
|
4936
|
-
[71, "G"],
|
|
4937
|
-
[72, "H"],
|
|
4938
|
-
[73, "I"],
|
|
4939
|
-
[74, "J"],
|
|
4940
|
-
[75, "K"],
|
|
4941
|
-
[76, "L"],
|
|
4942
|
-
[77, "M"],
|
|
4943
|
-
[78, "N"],
|
|
4944
|
-
[79, "O"],
|
|
4945
|
-
[80, "P"],
|
|
4946
|
-
[81, "Q"],
|
|
4947
|
-
[82, "R"],
|
|
4948
|
-
[83, "S"],
|
|
4949
|
-
[84, "T"],
|
|
4950
|
-
[85, "U"],
|
|
4951
|
-
[86, "V"],
|
|
4952
|
-
[87, "W"],
|
|
4953
|
-
[88, "X"],
|
|
4954
|
-
[89, "Y"],
|
|
4955
|
-
[90, "Z"],
|
|
4956
|
-
[91, "bracketleft"],
|
|
4957
|
-
[92, "backslash"],
|
|
4958
|
-
[93, "bracketright"],
|
|
4959
|
-
[94, "asciicircum"],
|
|
4960
|
-
[95, "underscore"],
|
|
4961
|
-
[96, "grave"],
|
|
4962
|
-
[97, "a"],
|
|
4963
|
-
[98, "b"],
|
|
4964
|
-
[99, "c"],
|
|
4965
|
-
[100, "d"],
|
|
4966
|
-
[101, "e"],
|
|
4967
|
-
[102, "f"],
|
|
4968
|
-
[103, "g"],
|
|
4969
|
-
[104, "h"],
|
|
4970
|
-
[105, "i"],
|
|
4971
|
-
[106, "j"],
|
|
4972
|
-
[107, "k"],
|
|
4973
|
-
[108, "l"],
|
|
4974
|
-
[109, "m"],
|
|
4975
|
-
[110, "n"],
|
|
4976
|
-
[111, "o"],
|
|
4977
|
-
[112, "p"],
|
|
4978
|
-
[113, "q"],
|
|
4979
|
-
[114, "r"],
|
|
4980
|
-
[115, "s"],
|
|
4981
|
-
[116, "t"],
|
|
4982
|
-
[117, "u"],
|
|
4983
|
-
[118, "v"],
|
|
4984
|
-
[119, "w"],
|
|
4985
|
-
[120, "x"],
|
|
4986
|
-
[121, "y"],
|
|
4987
|
-
[122, "z"],
|
|
4988
|
-
[123, "braceleft"],
|
|
4989
|
-
[124, "bar"],
|
|
4990
|
-
[125, "braceright"],
|
|
4991
|
-
[126, "asciitilde"],
|
|
4992
|
-
[160, "nbspace"],
|
|
4993
|
-
[161, "exclamdown"],
|
|
4994
|
-
[162, "cent"],
|
|
4995
|
-
[163, "sterling"],
|
|
4996
|
-
[164, "currency"],
|
|
4997
|
-
[165, "yen"],
|
|
4998
|
-
[166, "brokenbar"],
|
|
4999
|
-
[167, "section"],
|
|
5000
|
-
[168, "dieresis"],
|
|
5001
|
-
[169, "copyright"],
|
|
5002
|
-
[170, "ordfeminine"],
|
|
5003
|
-
[171, "guillemotleft"],
|
|
5004
|
-
[172, "logicalnot"],
|
|
5005
|
-
[173, "softhyphen"],
|
|
5006
|
-
[174, "registered"],
|
|
5007
|
-
[175, "macron"],
|
|
5008
|
-
[176, "degree"],
|
|
5009
|
-
[177, "plusminus"],
|
|
5010
|
-
[178, "twosuperior"],
|
|
5011
|
-
[179, "threesuperior"],
|
|
5012
|
-
[180, "acute"],
|
|
5013
|
-
[181, "mu"],
|
|
5014
|
-
[182, "paragraph"],
|
|
5015
|
-
[183, "periodcentered"],
|
|
5016
|
-
[184, "cedilla"],
|
|
5017
|
-
[185, "onesuperior"],
|
|
5018
|
-
[186, "ordmasculine"],
|
|
5019
|
-
[187, "guillemotright"],
|
|
5020
|
-
[188, "onequarter"],
|
|
5021
|
-
[189, "onehalf"],
|
|
5022
|
-
[190, "threequarters"],
|
|
5023
|
-
[191, "questiondown"],
|
|
5024
|
-
[192, "Agrave"],
|
|
5025
|
-
[193, "Aacute"],
|
|
5026
|
-
[194, "Acircumflex"],
|
|
5027
|
-
[195, "Atilde"],
|
|
5028
|
-
[196, "Adieresis"],
|
|
5029
|
-
[197, "Aring"],
|
|
5030
|
-
[198, "AE"],
|
|
5031
|
-
[199, "Ccedilla"],
|
|
5032
|
-
[200, "Egrave"],
|
|
5033
|
-
[201, "Eacute"],
|
|
5034
|
-
[202, "Ecircumflex"],
|
|
5035
|
-
[203, "Edieresis"],
|
|
5036
|
-
[204, "Igrave"],
|
|
5037
|
-
[205, "Iacute"],
|
|
5038
|
-
[206, "Icircumflex"],
|
|
5039
|
-
[207, "Idieresis"],
|
|
5040
|
-
[208, "Eth"],
|
|
5041
|
-
[209, "Ntilde"],
|
|
5042
|
-
[210, "Ograve"],
|
|
5043
|
-
[211, "Oacute"],
|
|
5044
|
-
[212, "Ocircumflex"],
|
|
5045
|
-
[213, "Otilde"],
|
|
5046
|
-
[214, "Odieresis"],
|
|
5047
|
-
[215, "multiply"],
|
|
5048
|
-
[216, "Oslash"],
|
|
5049
|
-
[217, "Ugrave"],
|
|
5050
|
-
[218, "Uacute"],
|
|
5051
|
-
[219, "Ucircumflex"],
|
|
5052
|
-
[220, "Udieresis"],
|
|
5053
|
-
[221, "Yacute"],
|
|
5054
|
-
[222, "Thorn"],
|
|
5055
|
-
[223, "germandbls"],
|
|
5056
|
-
[224, "agrave"],
|
|
5057
|
-
[225, "aacute"],
|
|
5058
|
-
[226, "acircumflex"],
|
|
5059
|
-
[227, "atilde"],
|
|
5060
|
-
[228, "adieresis"],
|
|
5061
|
-
[229, "aring"],
|
|
5062
|
-
[230, "ae"],
|
|
5063
|
-
[231, "ccedilla"],
|
|
5064
|
-
[232, "egrave"],
|
|
5065
|
-
[233, "eacute"],
|
|
5066
|
-
[234, "ecircumflex"],
|
|
5067
|
-
[235, "edieresis"],
|
|
5068
|
-
[236, "igrave"],
|
|
5069
|
-
[237, "iacute"],
|
|
5070
|
-
[238, "icircumflex"],
|
|
5071
|
-
[239, "idieresis"],
|
|
5072
|
-
[240, "eth"],
|
|
5073
|
-
[241, "ntilde"],
|
|
5074
|
-
[242, "ograve"],
|
|
5075
|
-
[243, "oacute"],
|
|
5076
|
-
[244, "ocircumflex"],
|
|
5077
|
-
[245, "otilde"],
|
|
5078
|
-
[246, "odieresis"],
|
|
5079
|
-
[247, "divide"],
|
|
5080
|
-
[248, "oslash"],
|
|
5081
|
-
[249, "ugrave"],
|
|
5082
|
-
[250, "uacute"],
|
|
5083
|
-
[251, "ucircumflex"],
|
|
5084
|
-
[252, "udieresis"],
|
|
5085
|
-
[253, "yacute"],
|
|
5086
|
-
[254, "thorn"],
|
|
5087
|
-
[255, "ydieresis"],
|
|
5088
|
-
[8211, "endash"],
|
|
5089
|
-
[8212, "emdash"],
|
|
5090
|
-
[8216, "quoteleft"],
|
|
5091
|
-
[8217, "quoteright"],
|
|
5092
|
-
[8218, "quotesinglbase"],
|
|
5093
|
-
[8220, "quotedblleft"],
|
|
5094
|
-
[8221, "quotedblright"],
|
|
5095
|
-
[8222, "quotedblbase"],
|
|
5096
|
-
[8224, "dagger"],
|
|
5097
|
-
[8225, "daggerdbl"],
|
|
5098
|
-
[8226, "bullet"],
|
|
5099
|
-
[8230, "ellipsis"],
|
|
5100
|
-
[8240, "perthousand"],
|
|
5101
|
-
[8249, "guilsinglleft"],
|
|
5102
|
-
[8250, "guilsinglright"],
|
|
5103
|
-
[8364, "Euro"],
|
|
5104
|
-
[8482, "trademark"],
|
|
5105
|
-
[64257, "fi"],
|
|
5106
|
-
[64258, "fl"]
|
|
5107
|
-
]);
|
|
5108
|
-
|
|
5109
4875
|
//#endregion
|
|
5110
4876
|
//#region src/io/scanner.ts
|
|
5111
4877
|
/**
|
|
@@ -10955,9 +10721,9 @@ function parseEmbeddedProgram(descriptor, options) {
|
|
|
10955
10721
|
* Try to parse a TrueType font from /FontFile2.
|
|
10956
10722
|
*/
|
|
10957
10723
|
function tryParseFontFile2(descriptor, options) {
|
|
10958
|
-
const fontFile2 =
|
|
10959
|
-
if (!fontFile2) return null;
|
|
10960
|
-
const data =
|
|
10724
|
+
const fontFile2 = descriptor.get("FontFile2", options.resolver);
|
|
10725
|
+
if (!(fontFile2 instanceof PdfStream)) return null;
|
|
10726
|
+
const data = fontFile2.getDecodedData();
|
|
10961
10727
|
if (!data || data.length === 0) return null;
|
|
10962
10728
|
try {
|
|
10963
10729
|
return new TrueTypeFontProgram(parseTTF(data, { isEmbedded: true }), data);
|
|
@@ -10970,10 +10736,10 @@ function tryParseFontFile2(descriptor, options) {
|
|
|
10970
10736
|
* Try to parse a CFF or OpenType font from /FontFile3.
|
|
10971
10737
|
*/
|
|
10972
10738
|
function tryParseFontFile3(descriptor, options) {
|
|
10973
|
-
const fontFile3 =
|
|
10974
|
-
if (!fontFile3) return null;
|
|
10739
|
+
const fontFile3 = descriptor.get("FontFile3", options.resolver);
|
|
10740
|
+
if (!(fontFile3 instanceof PdfStream)) return null;
|
|
10975
10741
|
const subtype = getStreamSubtype(fontFile3);
|
|
10976
|
-
const data =
|
|
10742
|
+
const data = fontFile3.getDecodedData();
|
|
10977
10743
|
if (!data || data.length === 0) return null;
|
|
10978
10744
|
try {
|
|
10979
10745
|
if (subtype === "OpenType") return new TrueTypeFontProgram(parseTTF(data, { isEmbedded: true }), data);
|
|
@@ -10994,9 +10760,9 @@ function tryParseFontFile3(descriptor, options) {
|
|
|
10994
10760
|
* Try to parse a Type1 font from /FontFile.
|
|
10995
10761
|
*/
|
|
10996
10762
|
function tryParseFontFile(descriptor, options) {
|
|
10997
|
-
const fontFile =
|
|
10998
|
-
if (!fontFile) return null;
|
|
10999
|
-
const data =
|
|
10763
|
+
const fontFile = descriptor.get("FontFile", options.resolver);
|
|
10764
|
+
if (!(fontFile instanceof PdfStream)) return null;
|
|
10765
|
+
const data = fontFile.getDecodedData();
|
|
11000
10766
|
if (!data || data.length === 0) return null;
|
|
11001
10767
|
try {
|
|
11002
10768
|
return new Type1FontProgram(parsePfb(data), data);
|
|
@@ -11029,15 +10795,7 @@ function tryAutoDetectFontFile3(data) {
|
|
|
11029
10795
|
* Get the /Subtype from a stream dictionary.
|
|
11030
10796
|
*/
|
|
11031
10797
|
function getStreamSubtype(stream) {
|
|
11032
|
-
if (stream
|
|
11033
|
-
}
|
|
11034
|
-
/**
|
|
11035
|
-
* Resolve a value through indirect references.
|
|
11036
|
-
*/
|
|
11037
|
-
function resolveValue(value, options) {
|
|
11038
|
-
if (!value) return null;
|
|
11039
|
-
if (options.resolveRef && value instanceof PdfRef) return options.resolveRef(value);
|
|
11040
|
-
return value;
|
|
10798
|
+
if (stream) return stream.getName("Subtype")?.value;
|
|
11041
10799
|
}
|
|
11042
10800
|
/**
|
|
11043
10801
|
* Parse a font program directly from bytes.
|
|
@@ -11071,6 +10829,725 @@ function parseFontProgram(data) {
|
|
|
11071
10829
|
throw new Error("Unrecognized font format");
|
|
11072
10830
|
}
|
|
11073
10831
|
|
|
10832
|
+
//#endregion
|
|
10833
|
+
//#region src/fonts/font-descriptor.ts
|
|
10834
|
+
/**
|
|
10835
|
+
* Font flags as defined in PDF spec Table 123.
|
|
10836
|
+
*/
|
|
10837
|
+
const FontFlags = {
|
|
10838
|
+
FIXED_PITCH: 1,
|
|
10839
|
+
SERIF: 2,
|
|
10840
|
+
SYMBOLIC: 4,
|
|
10841
|
+
SCRIPT: 8,
|
|
10842
|
+
NONSYMBOLIC: 32,
|
|
10843
|
+
ITALIC: 64,
|
|
10844
|
+
ALL_CAP: 65536,
|
|
10845
|
+
SMALL_CAP: 1 << 17,
|
|
10846
|
+
FORCE_BOLD: 1 << 18
|
|
10847
|
+
};
|
|
10848
|
+
/**
|
|
10849
|
+
* FontDescriptor contains font metrics and flags.
|
|
10850
|
+
*/
|
|
10851
|
+
var FontDescriptor = class FontDescriptor {
|
|
10852
|
+
fontName;
|
|
10853
|
+
flags;
|
|
10854
|
+
fontBBox;
|
|
10855
|
+
italicAngle;
|
|
10856
|
+
ascent;
|
|
10857
|
+
descent;
|
|
10858
|
+
leading;
|
|
10859
|
+
capHeight;
|
|
10860
|
+
xHeight;
|
|
10861
|
+
stemV;
|
|
10862
|
+
stemH;
|
|
10863
|
+
avgWidth;
|
|
10864
|
+
maxWidth;
|
|
10865
|
+
missingWidth;
|
|
10866
|
+
constructor(data) {
|
|
10867
|
+
this.fontName = data.fontName;
|
|
10868
|
+
this.flags = data.flags;
|
|
10869
|
+
this.fontBBox = data.fontBBox;
|
|
10870
|
+
this.italicAngle = data.italicAngle;
|
|
10871
|
+
this.ascent = data.ascent;
|
|
10872
|
+
this.descent = data.descent;
|
|
10873
|
+
this.leading = data.leading;
|
|
10874
|
+
this.capHeight = data.capHeight;
|
|
10875
|
+
this.xHeight = data.xHeight;
|
|
10876
|
+
this.stemV = data.stemV;
|
|
10877
|
+
this.stemH = data.stemH;
|
|
10878
|
+
this.avgWidth = data.avgWidth;
|
|
10879
|
+
this.maxWidth = data.maxWidth;
|
|
10880
|
+
this.missingWidth = data.missingWidth;
|
|
10881
|
+
}
|
|
10882
|
+
/** Check if font is fixed-pitch (monospace) */
|
|
10883
|
+
get isFixedPitch() {
|
|
10884
|
+
return (this.flags & FontFlags.FIXED_PITCH) !== 0;
|
|
10885
|
+
}
|
|
10886
|
+
/** Check if font is serif */
|
|
10887
|
+
get isSerif() {
|
|
10888
|
+
return (this.flags & FontFlags.SERIF) !== 0;
|
|
10889
|
+
}
|
|
10890
|
+
/** Check if font is symbolic (uses custom encoding) */
|
|
10891
|
+
get isSymbolic() {
|
|
10892
|
+
return (this.flags & FontFlags.SYMBOLIC) !== 0;
|
|
10893
|
+
}
|
|
10894
|
+
/** Check if font is script (cursive) */
|
|
10895
|
+
get isScript() {
|
|
10896
|
+
return (this.flags & FontFlags.SCRIPT) !== 0;
|
|
10897
|
+
}
|
|
10898
|
+
/** Check if font is non-symbolic (uses standard encoding) */
|
|
10899
|
+
get isNonSymbolic() {
|
|
10900
|
+
return (this.flags & FontFlags.NONSYMBOLIC) !== 0;
|
|
10901
|
+
}
|
|
10902
|
+
/** Check if font is italic */
|
|
10903
|
+
get isItalic() {
|
|
10904
|
+
return (this.flags & FontFlags.ITALIC) !== 0;
|
|
10905
|
+
}
|
|
10906
|
+
/** Check if font is all caps */
|
|
10907
|
+
get isAllCap() {
|
|
10908
|
+
return (this.flags & FontFlags.ALL_CAP) !== 0;
|
|
10909
|
+
}
|
|
10910
|
+
/** Check if font is small caps */
|
|
10911
|
+
get isSmallCap() {
|
|
10912
|
+
return (this.flags & FontFlags.SMALL_CAP) !== 0;
|
|
10913
|
+
}
|
|
10914
|
+
/** Check if font should be bold */
|
|
10915
|
+
get isForceBold() {
|
|
10916
|
+
return (this.flags & FontFlags.FORCE_BOLD) !== 0;
|
|
10917
|
+
}
|
|
10918
|
+
/**
|
|
10919
|
+
* Parse FontDescriptor from a PDF dictionary.
|
|
10920
|
+
*/
|
|
10921
|
+
static parse(dict) {
|
|
10922
|
+
const bboxArray = dict.getArray("FontBBox");
|
|
10923
|
+
const fontBBox = [
|
|
10924
|
+
0,
|
|
10925
|
+
0,
|
|
10926
|
+
0,
|
|
10927
|
+
0
|
|
10928
|
+
];
|
|
10929
|
+
if (bboxArray && bboxArray.length >= 4) for (let i = 0; i < 4; i++) {
|
|
10930
|
+
const item = bboxArray.at(i);
|
|
10931
|
+
if (item instanceof PdfNumber) fontBBox[i] = item.value;
|
|
10932
|
+
}
|
|
10933
|
+
return new FontDescriptor({
|
|
10934
|
+
fontName: dict.getName("FontName")?.value ?? "",
|
|
10935
|
+
flags: dict.getNumber("Flags")?.value ?? 0,
|
|
10936
|
+
fontBBox,
|
|
10937
|
+
italicAngle: dict.getNumber("ItalicAngle")?.value ?? 0,
|
|
10938
|
+
ascent: dict.getNumber("Ascent")?.value ?? 0,
|
|
10939
|
+
descent: dict.getNumber("Descent")?.value ?? 0,
|
|
10940
|
+
leading: dict.getNumber("Leading")?.value ?? 0,
|
|
10941
|
+
capHeight: dict.getNumber("CapHeight")?.value ?? 0,
|
|
10942
|
+
xHeight: dict.getNumber("XHeight")?.value ?? 0,
|
|
10943
|
+
stemV: dict.getNumber("StemV")?.value ?? 0,
|
|
10944
|
+
stemH: dict.getNumber("StemH")?.value ?? 0,
|
|
10945
|
+
avgWidth: dict.getNumber("AvgWidth")?.value ?? 0,
|
|
10946
|
+
maxWidth: dict.getNumber("MaxWidth")?.value ?? 0,
|
|
10947
|
+
missingWidth: dict.getNumber("MissingWidth")?.value ?? 0
|
|
10948
|
+
});
|
|
10949
|
+
}
|
|
10950
|
+
};
|
|
10951
|
+
|
|
10952
|
+
//#endregion
|
|
10953
|
+
//#region src/fonts/pdf-font.ts
|
|
10954
|
+
/**
|
|
10955
|
+
* Abstract base class for PDF fonts.
|
|
10956
|
+
*/
|
|
10957
|
+
var PdfFont = class {
|
|
10958
|
+
/**
|
|
10959
|
+
* Get width of text in points at a given font size.
|
|
10960
|
+
*
|
|
10961
|
+
* @param text - Unicode text to measure
|
|
10962
|
+
* @param fontSize - Font size in points
|
|
10963
|
+
* @returns Width in points
|
|
10964
|
+
*/
|
|
10965
|
+
getTextWidth(text, fontSize) {
|
|
10966
|
+
let totalWidth = 0;
|
|
10967
|
+
const codes = this.encodeText(text);
|
|
10968
|
+
for (const code of codes) totalWidth += this.getWidth(code);
|
|
10969
|
+
return totalWidth * fontSize / 1e3;
|
|
10970
|
+
}
|
|
10971
|
+
};
|
|
10972
|
+
|
|
10973
|
+
//#endregion
|
|
10974
|
+
//#region src/fonts/embedded-font.ts
|
|
10975
|
+
/**
|
|
10976
|
+
* EmbeddedFont represents a font that will be embedded into a PDF.
|
|
10977
|
+
*
|
|
10978
|
+
* Usage:
|
|
10979
|
+
* ```typescript
|
|
10980
|
+
* const fontBytes = await fs.readFile("NotoSans-Regular.ttf");
|
|
10981
|
+
* const font = EmbeddedFont.fromBytes(fontBytes);
|
|
10982
|
+
*
|
|
10983
|
+
* // Check if text can be encoded
|
|
10984
|
+
* if (font.canEncode("Hello ")) {
|
|
10985
|
+
* const codes = font.encodeText("Hello ");
|
|
10986
|
+
* const width = font.getTextWidth("Hello ", 12);
|
|
10987
|
+
* }
|
|
10988
|
+
* ```
|
|
10989
|
+
*/
|
|
10990
|
+
var EmbeddedFont = class EmbeddedFont extends PdfFont {
|
|
10991
|
+
subtype = "Type0";
|
|
10992
|
+
/** Underlying font program */
|
|
10993
|
+
fontProgram;
|
|
10994
|
+
/** Original font data */
|
|
10995
|
+
fontData;
|
|
10996
|
+
/** Track used glyphs for subsetting (GID -> code points that use it) */
|
|
10997
|
+
usedGlyphs = new Map([[0, /* @__PURE__ */ new Set()]]);
|
|
10998
|
+
/** Track used code points for ToUnicode (codePoint -> GID) */
|
|
10999
|
+
usedCodePoints = /* @__PURE__ */ new Map();
|
|
11000
|
+
/** Subset tag (generated during save) */
|
|
11001
|
+
_subsetTag = null;
|
|
11002
|
+
/** Whether this font is used in a form field (prevents subsetting) */
|
|
11003
|
+
_usedInForm = false;
|
|
11004
|
+
/** Cached descriptor */
|
|
11005
|
+
_descriptor = null;
|
|
11006
|
+
constructor(fontProgram, fontData) {
|
|
11007
|
+
super();
|
|
11008
|
+
this.fontProgram = fontProgram;
|
|
11009
|
+
this.fontData = fontData;
|
|
11010
|
+
}
|
|
11011
|
+
/**
|
|
11012
|
+
* Create an EmbeddedFont from raw font bytes.
|
|
11013
|
+
*
|
|
11014
|
+
* @param data - TTF, OTF, or Type1 font data
|
|
11015
|
+
* @param options - Embedding options
|
|
11016
|
+
* @returns EmbeddedFont instance
|
|
11017
|
+
* @throws {Error} if font format is not recognized
|
|
11018
|
+
*/
|
|
11019
|
+
static fromBytes(data, _options) {
|
|
11020
|
+
return new EmbeddedFont(parseFontProgram(data), data);
|
|
11021
|
+
}
|
|
11022
|
+
/**
|
|
11023
|
+
* Create an EmbeddedFont from an already-parsed TrueType font.
|
|
11024
|
+
*/
|
|
11025
|
+
static fromTrueTypeFont(font, data) {
|
|
11026
|
+
return new EmbeddedFont(new TrueTypeFontProgram(font, data), data);
|
|
11027
|
+
}
|
|
11028
|
+
/**
|
|
11029
|
+
* Get the base font name.
|
|
11030
|
+
* During save, this will include a subset tag prefix (e.g., "ABCDEF+FontName").
|
|
11031
|
+
*/
|
|
11032
|
+
get baseFontName() {
|
|
11033
|
+
const name = this.fontProgram.postScriptName ?? "Unknown";
|
|
11034
|
+
return this._subsetTag ? `${this._subsetTag}+${name}` : name;
|
|
11035
|
+
}
|
|
11036
|
+
/**
|
|
11037
|
+
* Get the font descriptor.
|
|
11038
|
+
*/
|
|
11039
|
+
get descriptor() {
|
|
11040
|
+
if (!this._descriptor) this._descriptor = this.buildDescriptor();
|
|
11041
|
+
return this._descriptor;
|
|
11042
|
+
}
|
|
11043
|
+
/**
|
|
11044
|
+
* Get the underlying font program.
|
|
11045
|
+
*/
|
|
11046
|
+
get program() {
|
|
11047
|
+
return this.fontProgram;
|
|
11048
|
+
}
|
|
11049
|
+
/**
|
|
11050
|
+
* Get the original font data.
|
|
11051
|
+
*/
|
|
11052
|
+
get data() {
|
|
11053
|
+
return this.fontData;
|
|
11054
|
+
}
|
|
11055
|
+
/**
|
|
11056
|
+
* Get the subset tag (only available after save).
|
|
11057
|
+
*/
|
|
11058
|
+
get subsetTag() {
|
|
11059
|
+
return this._subsetTag;
|
|
11060
|
+
}
|
|
11061
|
+
/**
|
|
11062
|
+
* Set the subset tag (called during save).
|
|
11063
|
+
*/
|
|
11064
|
+
setSubsetTag(tag) {
|
|
11065
|
+
this._subsetTag = tag;
|
|
11066
|
+
}
|
|
11067
|
+
/**
|
|
11068
|
+
* Get all used glyph IDs.
|
|
11069
|
+
*/
|
|
11070
|
+
getUsedGlyphIds() {
|
|
11071
|
+
return [...this.usedGlyphs.keys()].sort((a, b) => a - b);
|
|
11072
|
+
}
|
|
11073
|
+
/**
|
|
11074
|
+
* Get mapping from code point to GID.
|
|
11075
|
+
*/
|
|
11076
|
+
getCodePointToGidMap() {
|
|
11077
|
+
return new Map(this.usedCodePoints);
|
|
11078
|
+
}
|
|
11079
|
+
/**
|
|
11080
|
+
* Get mapping from GID to Unicode code point.
|
|
11081
|
+
*
|
|
11082
|
+
* This is used for building the /W widths array and ToUnicode CMap.
|
|
11083
|
+
* Since the content stream contains GIDs (with CIDToGIDMap /Identity),
|
|
11084
|
+
* the /W array must be keyed by GID, and ToUnicode must map GID → Unicode.
|
|
11085
|
+
*
|
|
11086
|
+
* If multiple code points map to the same GID, returns the first one found.
|
|
11087
|
+
*/
|
|
11088
|
+
getGidToCodePointMap() {
|
|
11089
|
+
const result = /* @__PURE__ */ new Map();
|
|
11090
|
+
for (const [gid, codePoints] of this.usedGlyphs) if (codePoints.size > 0) {
|
|
11091
|
+
const firstCodePoint = codePoints.values().next().value;
|
|
11092
|
+
if (firstCodePoint !== void 0) result.set(gid, firstCodePoint);
|
|
11093
|
+
}
|
|
11094
|
+
return result;
|
|
11095
|
+
}
|
|
11096
|
+
/**
|
|
11097
|
+
* Iterate over text, tracking glyph usage and returning codePoint/GID pairs.
|
|
11098
|
+
* This is the shared implementation for encodeText and encodeTextToGids.
|
|
11099
|
+
*/
|
|
11100
|
+
trackAndEncode(text) {
|
|
11101
|
+
const result = [];
|
|
11102
|
+
for (const char of text) {
|
|
11103
|
+
const codePoint = char.codePointAt(0);
|
|
11104
|
+
if (codePoint === void 0) continue;
|
|
11105
|
+
const gid = this.fontProgram.getGlyphId(codePoint);
|
|
11106
|
+
if (!this.usedGlyphs.has(gid)) this.usedGlyphs.set(gid, /* @__PURE__ */ new Set());
|
|
11107
|
+
this.usedGlyphs.get(gid).add(codePoint);
|
|
11108
|
+
this.usedCodePoints.set(codePoint, gid);
|
|
11109
|
+
result.push({
|
|
11110
|
+
codePoint,
|
|
11111
|
+
gid
|
|
11112
|
+
});
|
|
11113
|
+
}
|
|
11114
|
+
return result;
|
|
11115
|
+
}
|
|
11116
|
+
/**
|
|
11117
|
+
* Encode text to character codes.
|
|
11118
|
+
*
|
|
11119
|
+
* Returns Unicode code points, which is intuitive for users.
|
|
11120
|
+
* The conversion to glyph IDs happens internally when writing to the PDF.
|
|
11121
|
+
*
|
|
11122
|
+
* Also tracks glyph usage for subsetting.
|
|
11123
|
+
*/
|
|
11124
|
+
encodeText(text) {
|
|
11125
|
+
return this.trackAndEncode(text).map((e) => e.codePoint);
|
|
11126
|
+
}
|
|
11127
|
+
/**
|
|
11128
|
+
* Encode text to glyph IDs for PDF content stream.
|
|
11129
|
+
*
|
|
11130
|
+
* This is an internal method used when writing to the PDF.
|
|
11131
|
+
* With CIDToGIDMap /Identity, the content stream must contain GIDs.
|
|
11132
|
+
*
|
|
11133
|
+
* @internal
|
|
11134
|
+
*/
|
|
11135
|
+
encodeTextToGids(text) {
|
|
11136
|
+
return this.trackAndEncode(text).map((e) => e.gid);
|
|
11137
|
+
}
|
|
11138
|
+
/**
|
|
11139
|
+
* Convert a code point to its glyph ID.
|
|
11140
|
+
*
|
|
11141
|
+
* @internal
|
|
11142
|
+
*/
|
|
11143
|
+
codePointToGid(codePoint) {
|
|
11144
|
+
return this.fontProgram.getGlyphId(codePoint);
|
|
11145
|
+
}
|
|
11146
|
+
/**
|
|
11147
|
+
* Get width of a character in glyph units (1000 = 1 em).
|
|
11148
|
+
*
|
|
11149
|
+
* Takes a Unicode code point (user-friendly API).
|
|
11150
|
+
*/
|
|
11151
|
+
getWidth(code) {
|
|
11152
|
+
const gid = this.fontProgram.getGlyphId(code);
|
|
11153
|
+
const width = this.fontProgram.getAdvanceWidth(gid);
|
|
11154
|
+
return Math.round(width * 1e3 / this.fontProgram.unitsPerEm);
|
|
11155
|
+
}
|
|
11156
|
+
/**
|
|
11157
|
+
* Decode character code to Unicode string.
|
|
11158
|
+
*
|
|
11159
|
+
* For embedded fonts with Identity-H encoding, the code is the code point,
|
|
11160
|
+
* so this just converts the code point back to a string.
|
|
11161
|
+
*/
|
|
11162
|
+
toUnicode(code) {
|
|
11163
|
+
return String.fromCodePoint(code);
|
|
11164
|
+
}
|
|
11165
|
+
/**
|
|
11166
|
+
* Check if the font can encode the given text.
|
|
11167
|
+
* Returns true if all characters have glyphs in the font.
|
|
11168
|
+
*/
|
|
11169
|
+
canEncode(text) {
|
|
11170
|
+
for (const char of text) {
|
|
11171
|
+
const codePoint = char.codePointAt(0);
|
|
11172
|
+
if (codePoint === void 0) continue;
|
|
11173
|
+
if (!this.fontProgram.hasGlyph(codePoint)) return false;
|
|
11174
|
+
}
|
|
11175
|
+
return true;
|
|
11176
|
+
}
|
|
11177
|
+
/**
|
|
11178
|
+
* Get the characters that cannot be encoded.
|
|
11179
|
+
*/
|
|
11180
|
+
getUnencodableCharacters(text) {
|
|
11181
|
+
const unencodable = [];
|
|
11182
|
+
for (const char of text) {
|
|
11183
|
+
const codePoint = char.codePointAt(0);
|
|
11184
|
+
if (codePoint === void 0) continue;
|
|
11185
|
+
if (!this.fontProgram.hasGlyph(codePoint)) unencodable.push(char);
|
|
11186
|
+
}
|
|
11187
|
+
return unencodable;
|
|
11188
|
+
}
|
|
11189
|
+
/**
|
|
11190
|
+
* Reset glyph usage tracking.
|
|
11191
|
+
* Call this before re-encoding if you want a fresh subset.
|
|
11192
|
+
*/
|
|
11193
|
+
resetUsage() {
|
|
11194
|
+
this.usedGlyphs.clear();
|
|
11195
|
+
this.usedGlyphs.set(0, /* @__PURE__ */ new Set());
|
|
11196
|
+
this.usedCodePoints.clear();
|
|
11197
|
+
this._subsetTag = null;
|
|
11198
|
+
}
|
|
11199
|
+
/**
|
|
11200
|
+
* Mark this font as used in a form field.
|
|
11201
|
+
*
|
|
11202
|
+
* Fonts used in form fields cannot be subsetted because users may type
|
|
11203
|
+
* any character at runtime. This method is called automatically when
|
|
11204
|
+
* an EmbeddedFont is used in form field appearances.
|
|
11205
|
+
*/
|
|
11206
|
+
markUsedInForm() {
|
|
11207
|
+
this._usedInForm = true;
|
|
11208
|
+
}
|
|
11209
|
+
/**
|
|
11210
|
+
* Check if this font is used in a form field.
|
|
11211
|
+
*/
|
|
11212
|
+
get usedInForm() {
|
|
11213
|
+
return this._usedInForm;
|
|
11214
|
+
}
|
|
11215
|
+
/**
|
|
11216
|
+
* Check if this font can be subsetted.
|
|
11217
|
+
*
|
|
11218
|
+
* Returns false if the font is used in a form field (since users can
|
|
11219
|
+
* type any character at runtime).
|
|
11220
|
+
*/
|
|
11221
|
+
canSubset() {
|
|
11222
|
+
return !this._usedInForm;
|
|
11223
|
+
}
|
|
11224
|
+
/**
|
|
11225
|
+
* Get width of text in points at a given font size.
|
|
11226
|
+
*
|
|
11227
|
+
* Alias for getTextWidth() to match Standard14Font API.
|
|
11228
|
+
*
|
|
11229
|
+
* @param text - The text to measure
|
|
11230
|
+
* @param size - Font size in points
|
|
11231
|
+
* @returns Width in points
|
|
11232
|
+
*/
|
|
11233
|
+
widthOfTextAtSize(text, size) {
|
|
11234
|
+
return this.getTextWidth(text, size);
|
|
11235
|
+
}
|
|
11236
|
+
/**
|
|
11237
|
+
* Get the height of the font at a given size.
|
|
11238
|
+
*
|
|
11239
|
+
* This returns the full height from descender to ascender.
|
|
11240
|
+
*
|
|
11241
|
+
* @param size - Font size in points
|
|
11242
|
+
* @returns Height in points
|
|
11243
|
+
*/
|
|
11244
|
+
heightAtSize(size) {
|
|
11245
|
+
const desc = this.descriptor;
|
|
11246
|
+
if (!desc) return size;
|
|
11247
|
+
return (desc.ascent - desc.descent) * size / 1e3;
|
|
11248
|
+
}
|
|
11249
|
+
/**
|
|
11250
|
+
* Calculate font size needed to achieve a specific text height.
|
|
11251
|
+
*
|
|
11252
|
+
* @param height - Desired height in points
|
|
11253
|
+
* @returns Font size in points
|
|
11254
|
+
*/
|
|
11255
|
+
sizeAtHeight(height) {
|
|
11256
|
+
const desc = this.descriptor;
|
|
11257
|
+
if (!desc) return height;
|
|
11258
|
+
const unitsHeight = desc.ascent - desc.descent;
|
|
11259
|
+
return height * 1e3 / unitsHeight;
|
|
11260
|
+
}
|
|
11261
|
+
/**
|
|
11262
|
+
* Calculate font size needed for text to fit a specific width.
|
|
11263
|
+
*
|
|
11264
|
+
* @param text - The text to measure
|
|
11265
|
+
* @param width - Desired width in points
|
|
11266
|
+
* @returns Font size in points
|
|
11267
|
+
*/
|
|
11268
|
+
sizeAtWidth(text, width) {
|
|
11269
|
+
if (text.length === 0) return 0;
|
|
11270
|
+
const codes = this.encodeText(text);
|
|
11271
|
+
let totalWidth = 0;
|
|
11272
|
+
for (const code of codes) totalWidth += this.getWidth(code);
|
|
11273
|
+
if (totalWidth === 0) return 0;
|
|
11274
|
+
return width * 1e3 / totalWidth;
|
|
11275
|
+
}
|
|
11276
|
+
/**
|
|
11277
|
+
* Build a FontDescriptor from the font program.
|
|
11278
|
+
*/
|
|
11279
|
+
buildDescriptor() {
|
|
11280
|
+
const program = this.fontProgram;
|
|
11281
|
+
const bbox = program.bbox;
|
|
11282
|
+
const scale = 1e3 / program.unitsPerEm;
|
|
11283
|
+
return new FontDescriptor({
|
|
11284
|
+
fontName: program.postScriptName ?? "Unknown",
|
|
11285
|
+
flags: this.computeFlags(),
|
|
11286
|
+
fontBBox: [
|
|
11287
|
+
Math.round(bbox[0] * scale),
|
|
11288
|
+
Math.round(bbox[1] * scale),
|
|
11289
|
+
Math.round(bbox[2] * scale),
|
|
11290
|
+
Math.round(bbox[3] * scale)
|
|
11291
|
+
],
|
|
11292
|
+
italicAngle: program.italicAngle,
|
|
11293
|
+
ascent: Math.round(program.ascent * scale),
|
|
11294
|
+
descent: Math.round(program.descent * scale),
|
|
11295
|
+
leading: 0,
|
|
11296
|
+
capHeight: Math.round(program.capHeight * scale),
|
|
11297
|
+
xHeight: Math.round(program.xHeight * scale),
|
|
11298
|
+
stemV: program.stemV,
|
|
11299
|
+
stemH: 0,
|
|
11300
|
+
avgWidth: 0,
|
|
11301
|
+
maxWidth: 0,
|
|
11302
|
+
missingWidth: this.getWidth(0)
|
|
11303
|
+
});
|
|
11304
|
+
}
|
|
11305
|
+
/**
|
|
11306
|
+
* Compute font flags for the descriptor.
|
|
11307
|
+
*/
|
|
11308
|
+
computeFlags() {
|
|
11309
|
+
let flags = 0;
|
|
11310
|
+
if (this.fontProgram.isFixedPitch) flags |= 1;
|
|
11311
|
+
flags |= 4;
|
|
11312
|
+
if (this.fontProgram.italicAngle !== 0) flags |= 64;
|
|
11313
|
+
return flags;
|
|
11314
|
+
}
|
|
11315
|
+
};
|
|
11316
|
+
|
|
11317
|
+
//#endregion
|
|
11318
|
+
//#region src/helpers/unicode.ts
|
|
11319
|
+
/**
|
|
11320
|
+
* Unicode utilities for PDF text handling.
|
|
11321
|
+
*
|
|
11322
|
+
* Provides mappings between Unicode code points and PostScript glyph names.
|
|
11323
|
+
*/
|
|
11324
|
+
/**
|
|
11325
|
+
* Map Unicode code point to PostScript glyph name.
|
|
11326
|
+
* Returns undefined if no mapping exists.
|
|
11327
|
+
*/
|
|
11328
|
+
function unicodeToGlyphName(unicode) {
|
|
11329
|
+
return UNICODE_TO_GLYPH.get(unicode);
|
|
11330
|
+
}
|
|
11331
|
+
/**
|
|
11332
|
+
* Common Unicode to glyph name mappings.
|
|
11333
|
+
* Covers ASCII and common Latin-1 extended characters.
|
|
11334
|
+
*
|
|
11335
|
+
* For a complete mapping, see the Adobe Glyph List:
|
|
11336
|
+
* https://github.com/adobe-type-tools/agl-aglfn
|
|
11337
|
+
*/
|
|
11338
|
+
const UNICODE_TO_GLYPH = new Map([
|
|
11339
|
+
[32, "space"],
|
|
11340
|
+
[33, "exclam"],
|
|
11341
|
+
[34, "quotedbl"],
|
|
11342
|
+
[35, "numbersign"],
|
|
11343
|
+
[36, "dollar"],
|
|
11344
|
+
[37, "percent"],
|
|
11345
|
+
[38, "ampersand"],
|
|
11346
|
+
[39, "quotesingle"],
|
|
11347
|
+
[40, "parenleft"],
|
|
11348
|
+
[41, "parenright"],
|
|
11349
|
+
[42, "asterisk"],
|
|
11350
|
+
[43, "plus"],
|
|
11351
|
+
[44, "comma"],
|
|
11352
|
+
[45, "hyphen"],
|
|
11353
|
+
[46, "period"],
|
|
11354
|
+
[47, "slash"],
|
|
11355
|
+
[48, "zero"],
|
|
11356
|
+
[49, "one"],
|
|
11357
|
+
[50, "two"],
|
|
11358
|
+
[51, "three"],
|
|
11359
|
+
[52, "four"],
|
|
11360
|
+
[53, "five"],
|
|
11361
|
+
[54, "six"],
|
|
11362
|
+
[55, "seven"],
|
|
11363
|
+
[56, "eight"],
|
|
11364
|
+
[57, "nine"],
|
|
11365
|
+
[58, "colon"],
|
|
11366
|
+
[59, "semicolon"],
|
|
11367
|
+
[60, "less"],
|
|
11368
|
+
[61, "equal"],
|
|
11369
|
+
[62, "greater"],
|
|
11370
|
+
[63, "question"],
|
|
11371
|
+
[64, "at"],
|
|
11372
|
+
[65, "A"],
|
|
11373
|
+
[66, "B"],
|
|
11374
|
+
[67, "C"],
|
|
11375
|
+
[68, "D"],
|
|
11376
|
+
[69, "E"],
|
|
11377
|
+
[70, "F"],
|
|
11378
|
+
[71, "G"],
|
|
11379
|
+
[72, "H"],
|
|
11380
|
+
[73, "I"],
|
|
11381
|
+
[74, "J"],
|
|
11382
|
+
[75, "K"],
|
|
11383
|
+
[76, "L"],
|
|
11384
|
+
[77, "M"],
|
|
11385
|
+
[78, "N"],
|
|
11386
|
+
[79, "O"],
|
|
11387
|
+
[80, "P"],
|
|
11388
|
+
[81, "Q"],
|
|
11389
|
+
[82, "R"],
|
|
11390
|
+
[83, "S"],
|
|
11391
|
+
[84, "T"],
|
|
11392
|
+
[85, "U"],
|
|
11393
|
+
[86, "V"],
|
|
11394
|
+
[87, "W"],
|
|
11395
|
+
[88, "X"],
|
|
11396
|
+
[89, "Y"],
|
|
11397
|
+
[90, "Z"],
|
|
11398
|
+
[91, "bracketleft"],
|
|
11399
|
+
[92, "backslash"],
|
|
11400
|
+
[93, "bracketright"],
|
|
11401
|
+
[94, "asciicircum"],
|
|
11402
|
+
[95, "underscore"],
|
|
11403
|
+
[96, "grave"],
|
|
11404
|
+
[97, "a"],
|
|
11405
|
+
[98, "b"],
|
|
11406
|
+
[99, "c"],
|
|
11407
|
+
[100, "d"],
|
|
11408
|
+
[101, "e"],
|
|
11409
|
+
[102, "f"],
|
|
11410
|
+
[103, "g"],
|
|
11411
|
+
[104, "h"],
|
|
11412
|
+
[105, "i"],
|
|
11413
|
+
[106, "j"],
|
|
11414
|
+
[107, "k"],
|
|
11415
|
+
[108, "l"],
|
|
11416
|
+
[109, "m"],
|
|
11417
|
+
[110, "n"],
|
|
11418
|
+
[111, "o"],
|
|
11419
|
+
[112, "p"],
|
|
11420
|
+
[113, "q"],
|
|
11421
|
+
[114, "r"],
|
|
11422
|
+
[115, "s"],
|
|
11423
|
+
[116, "t"],
|
|
11424
|
+
[117, "u"],
|
|
11425
|
+
[118, "v"],
|
|
11426
|
+
[119, "w"],
|
|
11427
|
+
[120, "x"],
|
|
11428
|
+
[121, "y"],
|
|
11429
|
+
[122, "z"],
|
|
11430
|
+
[123, "braceleft"],
|
|
11431
|
+
[124, "bar"],
|
|
11432
|
+
[125, "braceright"],
|
|
11433
|
+
[126, "asciitilde"],
|
|
11434
|
+
[160, "nbspace"],
|
|
11435
|
+
[161, "exclamdown"],
|
|
11436
|
+
[162, "cent"],
|
|
11437
|
+
[163, "sterling"],
|
|
11438
|
+
[164, "currency"],
|
|
11439
|
+
[165, "yen"],
|
|
11440
|
+
[166, "brokenbar"],
|
|
11441
|
+
[167, "section"],
|
|
11442
|
+
[168, "dieresis"],
|
|
11443
|
+
[169, "copyright"],
|
|
11444
|
+
[170, "ordfeminine"],
|
|
11445
|
+
[171, "guillemotleft"],
|
|
11446
|
+
[172, "logicalnot"],
|
|
11447
|
+
[173, "softhyphen"],
|
|
11448
|
+
[174, "registered"],
|
|
11449
|
+
[175, "macron"],
|
|
11450
|
+
[176, "degree"],
|
|
11451
|
+
[177, "plusminus"],
|
|
11452
|
+
[178, "twosuperior"],
|
|
11453
|
+
[179, "threesuperior"],
|
|
11454
|
+
[180, "acute"],
|
|
11455
|
+
[181, "mu"],
|
|
11456
|
+
[182, "paragraph"],
|
|
11457
|
+
[183, "periodcentered"],
|
|
11458
|
+
[184, "cedilla"],
|
|
11459
|
+
[185, "onesuperior"],
|
|
11460
|
+
[186, "ordmasculine"],
|
|
11461
|
+
[187, "guillemotright"],
|
|
11462
|
+
[188, "onequarter"],
|
|
11463
|
+
[189, "onehalf"],
|
|
11464
|
+
[190, "threequarters"],
|
|
11465
|
+
[191, "questiondown"],
|
|
11466
|
+
[192, "Agrave"],
|
|
11467
|
+
[193, "Aacute"],
|
|
11468
|
+
[194, "Acircumflex"],
|
|
11469
|
+
[195, "Atilde"],
|
|
11470
|
+
[196, "Adieresis"],
|
|
11471
|
+
[197, "Aring"],
|
|
11472
|
+
[198, "AE"],
|
|
11473
|
+
[199, "Ccedilla"],
|
|
11474
|
+
[200, "Egrave"],
|
|
11475
|
+
[201, "Eacute"],
|
|
11476
|
+
[202, "Ecircumflex"],
|
|
11477
|
+
[203, "Edieresis"],
|
|
11478
|
+
[204, "Igrave"],
|
|
11479
|
+
[205, "Iacute"],
|
|
11480
|
+
[206, "Icircumflex"],
|
|
11481
|
+
[207, "Idieresis"],
|
|
11482
|
+
[208, "Eth"],
|
|
11483
|
+
[209, "Ntilde"],
|
|
11484
|
+
[210, "Ograve"],
|
|
11485
|
+
[211, "Oacute"],
|
|
11486
|
+
[212, "Ocircumflex"],
|
|
11487
|
+
[213, "Otilde"],
|
|
11488
|
+
[214, "Odieresis"],
|
|
11489
|
+
[215, "multiply"],
|
|
11490
|
+
[216, "Oslash"],
|
|
11491
|
+
[217, "Ugrave"],
|
|
11492
|
+
[218, "Uacute"],
|
|
11493
|
+
[219, "Ucircumflex"],
|
|
11494
|
+
[220, "Udieresis"],
|
|
11495
|
+
[221, "Yacute"],
|
|
11496
|
+
[222, "Thorn"],
|
|
11497
|
+
[223, "germandbls"],
|
|
11498
|
+
[224, "agrave"],
|
|
11499
|
+
[225, "aacute"],
|
|
11500
|
+
[226, "acircumflex"],
|
|
11501
|
+
[227, "atilde"],
|
|
11502
|
+
[228, "adieresis"],
|
|
11503
|
+
[229, "aring"],
|
|
11504
|
+
[230, "ae"],
|
|
11505
|
+
[231, "ccedilla"],
|
|
11506
|
+
[232, "egrave"],
|
|
11507
|
+
[233, "eacute"],
|
|
11508
|
+
[234, "ecircumflex"],
|
|
11509
|
+
[235, "edieresis"],
|
|
11510
|
+
[236, "igrave"],
|
|
11511
|
+
[237, "iacute"],
|
|
11512
|
+
[238, "icircumflex"],
|
|
11513
|
+
[239, "idieresis"],
|
|
11514
|
+
[240, "eth"],
|
|
11515
|
+
[241, "ntilde"],
|
|
11516
|
+
[242, "ograve"],
|
|
11517
|
+
[243, "oacute"],
|
|
11518
|
+
[244, "ocircumflex"],
|
|
11519
|
+
[245, "otilde"],
|
|
11520
|
+
[246, "odieresis"],
|
|
11521
|
+
[247, "divide"],
|
|
11522
|
+
[248, "oslash"],
|
|
11523
|
+
[249, "ugrave"],
|
|
11524
|
+
[250, "uacute"],
|
|
11525
|
+
[251, "ucircumflex"],
|
|
11526
|
+
[252, "udieresis"],
|
|
11527
|
+
[253, "yacute"],
|
|
11528
|
+
[254, "thorn"],
|
|
11529
|
+
[255, "ydieresis"],
|
|
11530
|
+
[8211, "endash"],
|
|
11531
|
+
[8212, "emdash"],
|
|
11532
|
+
[8216, "quoteleft"],
|
|
11533
|
+
[8217, "quoteright"],
|
|
11534
|
+
[8218, "quotesinglbase"],
|
|
11535
|
+
[8220, "quotedblleft"],
|
|
11536
|
+
[8221, "quotedblright"],
|
|
11537
|
+
[8222, "quotedblbase"],
|
|
11538
|
+
[8224, "dagger"],
|
|
11539
|
+
[8225, "daggerdbl"],
|
|
11540
|
+
[8226, "bullet"],
|
|
11541
|
+
[8230, "ellipsis"],
|
|
11542
|
+
[8240, "perthousand"],
|
|
11543
|
+
[8249, "guilsinglleft"],
|
|
11544
|
+
[8250, "guilsinglright"],
|
|
11545
|
+
[8364, "Euro"],
|
|
11546
|
+
[8482, "trademark"],
|
|
11547
|
+
[64257, "fi"],
|
|
11548
|
+
[64258, "fl"]
|
|
11549
|
+
]);
|
|
11550
|
+
|
|
11074
11551
|
//#endregion
|
|
11075
11552
|
//#region src/fonts/encodings/glyph-list.ts
|
|
11076
11553
|
/**
|
|
@@ -13310,147 +13787,6 @@ var ZapfDingbatsEncoding = class ZapfDingbatsEncoding extends SimpleEncoding {
|
|
|
13310
13787
|
}
|
|
13311
13788
|
};
|
|
13312
13789
|
|
|
13313
|
-
//#endregion
|
|
13314
|
-
//#region src/fonts/font-descriptor.ts
|
|
13315
|
-
/**
|
|
13316
|
-
* Font flags as defined in PDF spec Table 123.
|
|
13317
|
-
*/
|
|
13318
|
-
const FontFlags = {
|
|
13319
|
-
FIXED_PITCH: 1,
|
|
13320
|
-
SERIF: 2,
|
|
13321
|
-
SYMBOLIC: 4,
|
|
13322
|
-
SCRIPT: 8,
|
|
13323
|
-
NONSYMBOLIC: 32,
|
|
13324
|
-
ITALIC: 64,
|
|
13325
|
-
ALL_CAP: 65536,
|
|
13326
|
-
SMALL_CAP: 1 << 17,
|
|
13327
|
-
FORCE_BOLD: 1 << 18
|
|
13328
|
-
};
|
|
13329
|
-
/**
|
|
13330
|
-
* FontDescriptor contains font metrics and flags.
|
|
13331
|
-
*/
|
|
13332
|
-
var FontDescriptor = class FontDescriptor {
|
|
13333
|
-
fontName;
|
|
13334
|
-
flags;
|
|
13335
|
-
fontBBox;
|
|
13336
|
-
italicAngle;
|
|
13337
|
-
ascent;
|
|
13338
|
-
descent;
|
|
13339
|
-
leading;
|
|
13340
|
-
capHeight;
|
|
13341
|
-
xHeight;
|
|
13342
|
-
stemV;
|
|
13343
|
-
stemH;
|
|
13344
|
-
avgWidth;
|
|
13345
|
-
maxWidth;
|
|
13346
|
-
missingWidth;
|
|
13347
|
-
constructor(data) {
|
|
13348
|
-
this.fontName = data.fontName;
|
|
13349
|
-
this.flags = data.flags;
|
|
13350
|
-
this.fontBBox = data.fontBBox;
|
|
13351
|
-
this.italicAngle = data.italicAngle;
|
|
13352
|
-
this.ascent = data.ascent;
|
|
13353
|
-
this.descent = data.descent;
|
|
13354
|
-
this.leading = data.leading;
|
|
13355
|
-
this.capHeight = data.capHeight;
|
|
13356
|
-
this.xHeight = data.xHeight;
|
|
13357
|
-
this.stemV = data.stemV;
|
|
13358
|
-
this.stemH = data.stemH;
|
|
13359
|
-
this.avgWidth = data.avgWidth;
|
|
13360
|
-
this.maxWidth = data.maxWidth;
|
|
13361
|
-
this.missingWidth = data.missingWidth;
|
|
13362
|
-
}
|
|
13363
|
-
/** Check if font is fixed-pitch (monospace) */
|
|
13364
|
-
get isFixedPitch() {
|
|
13365
|
-
return (this.flags & FontFlags.FIXED_PITCH) !== 0;
|
|
13366
|
-
}
|
|
13367
|
-
/** Check if font is serif */
|
|
13368
|
-
get isSerif() {
|
|
13369
|
-
return (this.flags & FontFlags.SERIF) !== 0;
|
|
13370
|
-
}
|
|
13371
|
-
/** Check if font is symbolic (uses custom encoding) */
|
|
13372
|
-
get isSymbolic() {
|
|
13373
|
-
return (this.flags & FontFlags.SYMBOLIC) !== 0;
|
|
13374
|
-
}
|
|
13375
|
-
/** Check if font is script (cursive) */
|
|
13376
|
-
get isScript() {
|
|
13377
|
-
return (this.flags & FontFlags.SCRIPT) !== 0;
|
|
13378
|
-
}
|
|
13379
|
-
/** Check if font is non-symbolic (uses standard encoding) */
|
|
13380
|
-
get isNonSymbolic() {
|
|
13381
|
-
return (this.flags & FontFlags.NONSYMBOLIC) !== 0;
|
|
13382
|
-
}
|
|
13383
|
-
/** Check if font is italic */
|
|
13384
|
-
get isItalic() {
|
|
13385
|
-
return (this.flags & FontFlags.ITALIC) !== 0;
|
|
13386
|
-
}
|
|
13387
|
-
/** Check if font is all caps */
|
|
13388
|
-
get isAllCap() {
|
|
13389
|
-
return (this.flags & FontFlags.ALL_CAP) !== 0;
|
|
13390
|
-
}
|
|
13391
|
-
/** Check if font is small caps */
|
|
13392
|
-
get isSmallCap() {
|
|
13393
|
-
return (this.flags & FontFlags.SMALL_CAP) !== 0;
|
|
13394
|
-
}
|
|
13395
|
-
/** Check if font should be bold */
|
|
13396
|
-
get isForceBold() {
|
|
13397
|
-
return (this.flags & FontFlags.FORCE_BOLD) !== 0;
|
|
13398
|
-
}
|
|
13399
|
-
/**
|
|
13400
|
-
* Parse FontDescriptor from a PDF dictionary.
|
|
13401
|
-
*/
|
|
13402
|
-
static parse(dict) {
|
|
13403
|
-
const bboxArray = dict.getArray("FontBBox");
|
|
13404
|
-
const fontBBox = [
|
|
13405
|
-
0,
|
|
13406
|
-
0,
|
|
13407
|
-
0,
|
|
13408
|
-
0
|
|
13409
|
-
];
|
|
13410
|
-
if (bboxArray && bboxArray.length >= 4) for (let i = 0; i < 4; i++) {
|
|
13411
|
-
const item = bboxArray.at(i);
|
|
13412
|
-
if (item && item.type === "number") fontBBox[i] = item.value;
|
|
13413
|
-
}
|
|
13414
|
-
return new FontDescriptor({
|
|
13415
|
-
fontName: dict.getName("FontName")?.value ?? "",
|
|
13416
|
-
flags: dict.getNumber("Flags")?.value ?? 0,
|
|
13417
|
-
fontBBox,
|
|
13418
|
-
italicAngle: dict.getNumber("ItalicAngle")?.value ?? 0,
|
|
13419
|
-
ascent: dict.getNumber("Ascent")?.value ?? 0,
|
|
13420
|
-
descent: dict.getNumber("Descent")?.value ?? 0,
|
|
13421
|
-
leading: dict.getNumber("Leading")?.value ?? 0,
|
|
13422
|
-
capHeight: dict.getNumber("CapHeight")?.value ?? 0,
|
|
13423
|
-
xHeight: dict.getNumber("XHeight")?.value ?? 0,
|
|
13424
|
-
stemV: dict.getNumber("StemV")?.value ?? 0,
|
|
13425
|
-
stemH: dict.getNumber("StemH")?.value ?? 0,
|
|
13426
|
-
avgWidth: dict.getNumber("AvgWidth")?.value ?? 0,
|
|
13427
|
-
maxWidth: dict.getNumber("MaxWidth")?.value ?? 0,
|
|
13428
|
-
missingWidth: dict.getNumber("MissingWidth")?.value ?? 0
|
|
13429
|
-
});
|
|
13430
|
-
}
|
|
13431
|
-
};
|
|
13432
|
-
|
|
13433
|
-
//#endregion
|
|
13434
|
-
//#region src/fonts/pdf-font.ts
|
|
13435
|
-
/**
|
|
13436
|
-
* Abstract base class for PDF fonts.
|
|
13437
|
-
*/
|
|
13438
|
-
var PdfFont = class {
|
|
13439
|
-
/**
|
|
13440
|
-
* Get width of text in points at a given font size.
|
|
13441
|
-
*
|
|
13442
|
-
* @param text - Unicode text to measure
|
|
13443
|
-
* @param fontSize - Font size in points
|
|
13444
|
-
* @returns Width in points
|
|
13445
|
-
*/
|
|
13446
|
-
getTextWidth(text, fontSize) {
|
|
13447
|
-
let totalWidth = 0;
|
|
13448
|
-
const codes = this.encodeText(text);
|
|
13449
|
-
for (const code of codes) totalWidth += this.getWidth(code);
|
|
13450
|
-
return totalWidth * fontSize / 1e3;
|
|
13451
|
-
}
|
|
13452
|
-
};
|
|
13453
|
-
|
|
13454
13790
|
//#endregion
|
|
13455
13791
|
//#region src/fonts/standard-14.ts
|
|
13456
13792
|
/**
|
|
@@ -16689,25 +17025,6 @@ const FONT_GLYPH_WIDTHS = {
|
|
|
16689
17025
|
|
|
16690
17026
|
//#endregion
|
|
16691
17027
|
//#region src/fonts/simple-font.ts
|
|
16692
|
-
/**
|
|
16693
|
-
* SimpleFont - Base class for single-byte encoded fonts.
|
|
16694
|
-
*
|
|
16695
|
-
* This handles TrueType, Type1, and Type3 fonts which use single-byte
|
|
16696
|
-
* character codes (0-255).
|
|
16697
|
-
*
|
|
16698
|
-
* Font structure:
|
|
16699
|
-
* <<
|
|
16700
|
-
* /Type /Font
|
|
16701
|
-
* /Subtype /TrueType (or /Type1, /Type3)
|
|
16702
|
-
* /BaseFont /Helvetica
|
|
16703
|
-
* /FirstChar 32
|
|
16704
|
-
* /LastChar 255
|
|
16705
|
-
* /Widths [278 278 355 ...]
|
|
16706
|
-
* /Encoding /WinAnsiEncoding (or dict with /Differences)
|
|
16707
|
-
* /FontDescriptor 10 0 R
|
|
16708
|
-
* /ToUnicode 11 0 R
|
|
16709
|
-
* >>
|
|
16710
|
-
*/
|
|
16711
17028
|
const isSimpleFontSubtype = (subtype) => {
|
|
16712
17029
|
return subtype === "TrueType" || subtype === "Type1" || subtype === "Type3" || subtype === "MMType1";
|
|
16713
17030
|
};
|
|
@@ -16844,34 +17161,25 @@ var SimpleFont = class extends PdfFont {
|
|
|
16844
17161
|
* Parse a SimpleFont from a PDF font dictionary.
|
|
16845
17162
|
*/
|
|
16846
17163
|
function parseSimpleFont(dict, options = {}) {
|
|
16847
|
-
const subtypeName = dict.getName("Subtype");
|
|
17164
|
+
const subtypeName = dict.getName("Subtype", options.resolver);
|
|
16848
17165
|
const subtype = isSimpleFontSubtype(subtypeName?.value) ? subtypeName.value : "TrueType";
|
|
16849
|
-
const baseFontName = dict.getName("BaseFont")?.value ?? "Unknown";
|
|
16850
|
-
const firstChar = dict.getNumber("FirstChar")?.value ?? 0;
|
|
16851
|
-
const lastChar = dict.getNumber("LastChar")?.value ?? 255;
|
|
16852
|
-
let
|
|
16853
|
-
let widthsArray = null;
|
|
16854
|
-
if (w instanceof PdfRef && options.resolveRef) w = options.resolveRef(w) ?? void 0;
|
|
16855
|
-
if (w instanceof PdfArray) widthsArray = w;
|
|
17166
|
+
const baseFontName = dict.getName("BaseFont", options.resolver)?.value ?? "Unknown";
|
|
17167
|
+
const firstChar = dict.getNumber("FirstChar", options.resolver)?.value ?? 0;
|
|
17168
|
+
const lastChar = dict.getNumber("LastChar", options.resolver)?.value ?? 255;
|
|
17169
|
+
let widthsArray = dict.getArray("Widths", options.resolver);
|
|
16856
17170
|
const widths = [];
|
|
16857
17171
|
if (widthsArray) for (let i = 0; i < widthsArray.length; i++) {
|
|
16858
|
-
const item = widthsArray.at(i);
|
|
17172
|
+
const item = widthsArray.at(i, options.resolver);
|
|
16859
17173
|
if (item instanceof PdfNumber) widths.push(item.value);
|
|
16860
17174
|
else widths.push(0);
|
|
16861
17175
|
}
|
|
16862
|
-
const encoding = parseEncoding(dict, options.
|
|
17176
|
+
const encoding = parseEncoding(dict, options.resolver);
|
|
16863
17177
|
let descriptor = null;
|
|
16864
17178
|
let embeddedProgram = null;
|
|
16865
|
-
const
|
|
16866
|
-
if (
|
|
16867
|
-
|
|
16868
|
-
|
|
16869
|
-
descriptor = FontDescriptor.parse(descriptorDict);
|
|
16870
|
-
if (options.decodeStream) embeddedProgram = parseEmbeddedProgram(descriptorDict, {
|
|
16871
|
-
decodeStream: options.decodeStream,
|
|
16872
|
-
resolveRef: options.resolveRef
|
|
16873
|
-
});
|
|
16874
|
-
}
|
|
17179
|
+
const fontDescriptor = dict.getDict("FontDescriptor", options.resolver);
|
|
17180
|
+
if (fontDescriptor) {
|
|
17181
|
+
descriptor = FontDescriptor.parse(fontDescriptor);
|
|
17182
|
+
embeddedProgram = parseEmbeddedProgram(fontDescriptor, { resolver: options.resolver });
|
|
16875
17183
|
}
|
|
16876
17184
|
return new SimpleFont({
|
|
16877
17185
|
subtype,
|
|
@@ -16888,36 +17196,31 @@ function parseSimpleFont(dict, options = {}) {
|
|
|
16888
17196
|
/**
|
|
16889
17197
|
* Parse encoding from font dictionary.
|
|
16890
17198
|
*/
|
|
16891
|
-
function parseEncoding(dict,
|
|
16892
|
-
const encodingValue = dict.get("Encoding");
|
|
17199
|
+
function parseEncoding(dict, resolver) {
|
|
17200
|
+
const encodingValue = dict.get("Encoding", resolver);
|
|
16893
17201
|
if (!encodingValue) {
|
|
16894
|
-
const baseFontName = dict.getName("BaseFont")?.value ?? "";
|
|
17202
|
+
const baseFontName = dict.getName("BaseFont", resolver)?.value ?? "";
|
|
16895
17203
|
if (baseFontName === "Symbol") return SymbolEncoding.instance;
|
|
16896
17204
|
if (baseFontName === "ZapfDingbats") return ZapfDingbatsEncoding.instance;
|
|
16897
17205
|
return StandardEncoding.instance;
|
|
16898
17206
|
}
|
|
16899
|
-
if (encodingValue
|
|
16900
|
-
if (encodingValue
|
|
16901
|
-
if (encodingValue.type === "ref" && resolveRef) {
|
|
16902
|
-
const resolved = resolveRef(encodingValue);
|
|
16903
|
-
if (resolved && resolved.type === "dict") return parseEncodingDict(resolved);
|
|
16904
|
-
}
|
|
17207
|
+
if (encodingValue instanceof PdfName) return getEncodingByName(encodingValue.value);
|
|
17208
|
+
if (encodingValue instanceof PdfDict) return parseEncodingDict(encodingValue, resolver);
|
|
16905
17209
|
return WinAnsiEncoding.instance;
|
|
16906
17210
|
}
|
|
16907
17211
|
/**
|
|
16908
17212
|
* Parse encoding dictionary.
|
|
16909
17213
|
*/
|
|
16910
|
-
function parseEncodingDict(dict) {
|
|
16911
|
-
const baseEncodingName = dict.getName("BaseEncoding");
|
|
17214
|
+
function parseEncodingDict(dict, resolver) {
|
|
17215
|
+
const baseEncodingName = dict.getName("BaseEncoding", resolver);
|
|
16912
17216
|
const baseEncoding = baseEncodingName ? getEncodingByName(baseEncodingName.value) : WinAnsiEncoding.instance;
|
|
16913
|
-
const differencesArray = dict.getArray("Differences");
|
|
17217
|
+
const differencesArray = dict.getArray("Differences", resolver);
|
|
16914
17218
|
if (!differencesArray || differencesArray.length === 0) return baseEncoding;
|
|
16915
17219
|
const items = [];
|
|
16916
17220
|
for (let i = 0; i < differencesArray.length; i++) {
|
|
16917
17221
|
const item = differencesArray.at(i);
|
|
16918
17222
|
if (item) {
|
|
16919
|
-
if (item
|
|
16920
|
-
else if (item.type === "name") items.push(item.value);
|
|
17223
|
+
if (item instanceof PdfNumber || item instanceof PdfName) items.push(item.value);
|
|
16921
17224
|
}
|
|
16922
17225
|
}
|
|
16923
17226
|
return new DifferencesEncoding(baseEncoding, DifferencesEncoding.parseDifferencesArray(items));
|
|
@@ -16939,6 +17242,15 @@ function getEncodingByName(name) {
|
|
|
16939
17242
|
//#endregion
|
|
16940
17243
|
//#region src/document/forms/form-font.ts
|
|
16941
17244
|
/**
|
|
17245
|
+
* Form font types for use in form fields.
|
|
17246
|
+
*
|
|
17247
|
+
* Supports two font types:
|
|
17248
|
+
* - EmbeddedFont: Full font with metrics and subsetting
|
|
17249
|
+
* - ExistingFont: Lightweight wrapper for fonts already in the PDF
|
|
17250
|
+
*
|
|
17251
|
+
* PDF Reference: Section 12.7.3.3 "Variable Text"
|
|
17252
|
+
*/
|
|
17253
|
+
/**
|
|
16942
17254
|
* Existing font from PDF's default resources.
|
|
16943
17255
|
*
|
|
16944
17256
|
* This is a lightweight wrapper for fonts already present in the PDF,
|
|
@@ -17062,18 +17374,11 @@ function mapToStandardFont(name) {
|
|
|
17062
17374
|
function parseExistingFont(name, fontObj, registry) {
|
|
17063
17375
|
let ref = null;
|
|
17064
17376
|
let simpleFont = null;
|
|
17065
|
-
if (fontObj
|
|
17377
|
+
if (fontObj instanceof PdfRef) {
|
|
17066
17378
|
ref = fontObj;
|
|
17067
17379
|
const resolved = registry.getObject(fontObj);
|
|
17068
|
-
if (resolved
|
|
17069
|
-
|
|
17070
|
-
if (r instanceof PdfRef) {
|
|
17071
|
-
const obj = registry.getObject(r);
|
|
17072
|
-
if (obj instanceof PdfDict || obj instanceof PdfArray || obj instanceof PdfStream) return obj;
|
|
17073
|
-
}
|
|
17074
|
-
return null;
|
|
17075
|
-
};
|
|
17076
|
-
simpleFont = parseSimpleFont(resolved, { resolveRef });
|
|
17380
|
+
if (resolved instanceof PdfDict) try {
|
|
17381
|
+
simpleFont = parseSimpleFont(resolved, { resolver: registry.resolve.bind(registry) });
|
|
17077
17382
|
} catch (err) {
|
|
17078
17383
|
console.warn(err);
|
|
17079
17384
|
}
|
|
@@ -17084,7 +17389,7 @@ function parseExistingFont(name, fontObj, registry) {
|
|
|
17084
17389
|
* Check if a font is an EmbeddedFont.
|
|
17085
17390
|
*/
|
|
17086
17391
|
function isEmbeddedFont(font) {
|
|
17087
|
-
return
|
|
17392
|
+
return font instanceof EmbeddedFont;
|
|
17088
17393
|
}
|
|
17089
17394
|
/**
|
|
17090
17395
|
* Check if a font is an ExistingFont.
|
|
@@ -18342,11 +18647,11 @@ var WidgetAnnotation = class {
|
|
|
18342
18647
|
getOnValue() {
|
|
18343
18648
|
const ap = this.dict.getDict("AP");
|
|
18344
18649
|
if (!ap) return null;
|
|
18345
|
-
const
|
|
18650
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18651
|
+
const n = ap.get("N", resolve);
|
|
18346
18652
|
if (!n) return null;
|
|
18347
|
-
|
|
18348
|
-
|
|
18349
|
-
for (const key$1 of nResolved.keys()) if (key$1.value !== "Off") return key$1.value;
|
|
18653
|
+
if (n instanceof PdfDict && !(n instanceof PdfStream)) {
|
|
18654
|
+
for (const key$1 of n.keys()) if (key$1.value !== "Off") return key$1.value;
|
|
18350
18655
|
}
|
|
18351
18656
|
return null;
|
|
18352
18657
|
}
|
|
@@ -18359,11 +18664,11 @@ var WidgetAnnotation = class {
|
|
|
18359
18664
|
hasAppearancesForStates(states) {
|
|
18360
18665
|
const ap = this.dict.getDict("AP");
|
|
18361
18666
|
if (!ap) return false;
|
|
18362
|
-
const
|
|
18667
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18668
|
+
const n = ap.get("N", resolve);
|
|
18363
18669
|
if (!n) return false;
|
|
18364
|
-
|
|
18365
|
-
|
|
18366
|
-
for (const state of states) if (!nResolved.has(state)) return false;
|
|
18670
|
+
if (n instanceof PdfDict && !(n instanceof PdfStream)) {
|
|
18671
|
+
for (const state of states) if (!n.has(state)) return false;
|
|
18367
18672
|
return true;
|
|
18368
18673
|
}
|
|
18369
18674
|
return states.length === 0;
|
|
@@ -18384,15 +18689,13 @@ var WidgetAnnotation = class {
|
|
|
18384
18689
|
getNormalAppearance(state) {
|
|
18385
18690
|
const ap = this.dict.getDict("AP");
|
|
18386
18691
|
if (!ap) return null;
|
|
18387
|
-
|
|
18692
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18693
|
+
const n = ap.get("N", resolve);
|
|
18388
18694
|
if (!n) return null;
|
|
18389
|
-
if (n instanceof PdfRef) n = this.registry.resolve(n) ?? void 0;
|
|
18390
18695
|
if (n instanceof PdfStream) return n;
|
|
18391
18696
|
if (n instanceof PdfDict) {
|
|
18392
18697
|
const stateKey = state ?? this.appearanceState ?? "Off";
|
|
18393
|
-
|
|
18394
|
-
if (!stateEntry) return null;
|
|
18395
|
-
if (stateEntry instanceof PdfRef) stateEntry = this.registry.resolve(stateEntry) ?? void 0;
|
|
18698
|
+
const stateEntry = n.get(stateKey, resolve);
|
|
18396
18699
|
if (stateEntry instanceof PdfStream) return stateEntry;
|
|
18397
18700
|
return null;
|
|
18398
18701
|
}
|
|
@@ -18404,15 +18707,13 @@ var WidgetAnnotation = class {
|
|
|
18404
18707
|
getRolloverAppearance(state) {
|
|
18405
18708
|
const ap = this.dict.getDict("AP");
|
|
18406
18709
|
if (!ap) return null;
|
|
18407
|
-
|
|
18710
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18711
|
+
const r = ap.get("R", resolve);
|
|
18408
18712
|
if (!r) return null;
|
|
18409
|
-
if (r instanceof PdfRef) r = this.registry.resolve(r) ?? void 0;
|
|
18410
18713
|
if (r instanceof PdfStream) return r;
|
|
18411
18714
|
if (r instanceof PdfDict) {
|
|
18412
18715
|
const stateKey = state ?? this.appearanceState ?? "Off";
|
|
18413
|
-
|
|
18414
|
-
if (!stateEntry) return null;
|
|
18415
|
-
if (stateEntry instanceof PdfRef) stateEntry = this.registry.resolve(stateEntry) ?? void 0;
|
|
18716
|
+
const stateEntry = r.get(stateKey, resolve);
|
|
18416
18717
|
if (stateEntry instanceof PdfStream) return stateEntry;
|
|
18417
18718
|
return null;
|
|
18418
18719
|
}
|
|
@@ -18424,15 +18725,13 @@ var WidgetAnnotation = class {
|
|
|
18424
18725
|
getDownAppearance(state) {
|
|
18425
18726
|
const ap = this.dict.getDict("AP");
|
|
18426
18727
|
if (!ap) return null;
|
|
18427
|
-
|
|
18728
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18729
|
+
const d = ap.get("D", resolve);
|
|
18428
18730
|
if (!d) return null;
|
|
18429
|
-
if (d instanceof PdfRef) d = this.registry.resolve(d) ?? void 0;
|
|
18430
18731
|
if (d instanceof PdfStream) return d;
|
|
18431
18732
|
if (d instanceof PdfDict) {
|
|
18432
18733
|
const stateKey = state ?? this.appearanceState ?? "Off";
|
|
18433
|
-
|
|
18434
|
-
if (!stateEntry) return null;
|
|
18435
|
-
if (stateEntry instanceof PdfRef) stateEntry = this.registry.resolve(stateEntry) ?? void 0;
|
|
18734
|
+
const stateEntry = d.get(stateKey, resolve);
|
|
18436
18735
|
if (stateEntry instanceof PdfStream) return stateEntry;
|
|
18437
18736
|
return null;
|
|
18438
18737
|
}
|
|
@@ -18462,14 +18761,8 @@ var WidgetAnnotation = class {
|
|
|
18462
18761
|
* Get appearance characteristics (/MK dictionary).
|
|
18463
18762
|
*/
|
|
18464
18763
|
getAppearanceCharacteristics() {
|
|
18465
|
-
const
|
|
18466
|
-
|
|
18467
|
-
let mk = null;
|
|
18468
|
-
if (mkEntry instanceof PdfDict) mk = mkEntry;
|
|
18469
|
-
else if (mkEntry.type === "ref") {
|
|
18470
|
-
const resolved = this.registry.getObject(mkEntry);
|
|
18471
|
-
if (resolved instanceof PdfDict) mk = resolved;
|
|
18472
|
-
}
|
|
18764
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18765
|
+
const mk = this.dict.getDict("MK", resolve);
|
|
18473
18766
|
if (!mk) return null;
|
|
18474
18767
|
return {
|
|
18475
18768
|
rotation: mk.getNumber("R")?.value ?? 0,
|
|
@@ -18608,11 +18901,8 @@ var FormField = class {
|
|
|
18608
18901
|
while (current) {
|
|
18609
18902
|
if (visited.has(current)) break;
|
|
18610
18903
|
visited.add(current);
|
|
18611
|
-
const value = current.get(key$1);
|
|
18612
|
-
if (value !== void 0)
|
|
18613
|
-
if (value instanceof PdfRef) return this.registry.getObject(value);
|
|
18614
|
-
return value;
|
|
18615
|
-
}
|
|
18904
|
+
const value = current.get(key$1, this.registry.resolve.bind(this.registry));
|
|
18905
|
+
if (value !== void 0) return value;
|
|
18616
18906
|
const parentRef = current.getRef("Parent");
|
|
18617
18907
|
if (!parentRef) break;
|
|
18618
18908
|
const obj = this.registry.getObject(parentRef);
|
|
@@ -18853,8 +19143,7 @@ var TerminalField = class extends FormField {
|
|
|
18853
19143
|
* This ensures getAppearanceCharacteristics() can work synchronously.
|
|
18854
19144
|
*/
|
|
18855
19145
|
resolveMK(dict) {
|
|
18856
|
-
|
|
18857
|
-
if (mkEntry instanceof PdfRef) this.registry.resolve(mkEntry);
|
|
19146
|
+
dict.getDict("MK", this.registry.resolve.bind(this.registry));
|
|
18858
19147
|
}
|
|
18859
19148
|
/**
|
|
18860
19149
|
* Add a widget to this field's /Kids array.
|
|
@@ -19204,12 +19493,6 @@ var ListBoxField = class extends TerminalField {
|
|
|
19204
19493
|
//#endregion
|
|
19205
19494
|
//#region src/document/forms/fields/other-fields.ts
|
|
19206
19495
|
/**
|
|
19207
|
-
* Other field types: Signature, Button, and Unknown.
|
|
19208
|
-
*
|
|
19209
|
-
* PDF Reference: Section 12.7.4.5 "Signature Fields"
|
|
19210
|
-
* PDF Reference: Section 12.7.4.2 "Button Fields"
|
|
19211
|
-
*/
|
|
19212
|
-
/**
|
|
19213
19496
|
* Signature field.
|
|
19214
19497
|
*/
|
|
19215
19498
|
var SignatureField = class extends TerminalField {
|
|
@@ -19224,13 +19507,7 @@ var SignatureField = class extends TerminalField {
|
|
|
19224
19507
|
* Get signature dictionary (if signed).
|
|
19225
19508
|
*/
|
|
19226
19509
|
getSignatureDict() {
|
|
19227
|
-
|
|
19228
|
-
if (!v) return null;
|
|
19229
|
-
if (v instanceof PdfRef) {
|
|
19230
|
-
const resolved = this.registry.getObject(v);
|
|
19231
|
-
return resolved instanceof PdfDict ? resolved : null;
|
|
19232
|
-
}
|
|
19233
|
-
return v instanceof PdfDict ? v : null;
|
|
19510
|
+
return this.dict.getDict("V", this.registry.resolve.bind(this.registry)) ?? null;
|
|
19234
19511
|
}
|
|
19235
19512
|
/**
|
|
19236
19513
|
* Signature fields don't have simple values.
|
|
@@ -19316,7 +19593,7 @@ var RadioField = class extends TerminalField {
|
|
|
19316
19593
|
* that are different from the widget appearance state names.
|
|
19317
19594
|
*/
|
|
19318
19595
|
getExportValues() {
|
|
19319
|
-
const opt = this.dict.getArray("Opt");
|
|
19596
|
+
const opt = this.dict.getArray("Opt", this.registry.resolve.bind(this.registry));
|
|
19320
19597
|
if (!opt) return this.getOptions();
|
|
19321
19598
|
const values = [];
|
|
19322
19599
|
for (let i = 0; i < opt.length; i++) {
|
|
@@ -19435,11 +19712,6 @@ var TextField = class extends TerminalField {
|
|
|
19435
19712
|
//#endregion
|
|
19436
19713
|
//#region src/document/forms/fields/factory.ts
|
|
19437
19714
|
/**
|
|
19438
|
-
* Form field factory function.
|
|
19439
|
-
*
|
|
19440
|
-
* Creates the appropriate field type based on /FT and /Ff values.
|
|
19441
|
-
*/
|
|
19442
|
-
/**
|
|
19443
19715
|
* Create a terminal FormField instance based on /FT and /Ff.
|
|
19444
19716
|
*
|
|
19445
19717
|
* This factory creates only terminal fields (value-holding fields with widgets).
|
|
@@ -19467,15 +19739,15 @@ function createFormField(dict, ref, registry, acroForm, name) {
|
|
|
19467
19739
|
function getInheritableFieldName(dict, key$1, registry) {
|
|
19468
19740
|
let current = dict;
|
|
19469
19741
|
const visited = /* @__PURE__ */ new Set();
|
|
19742
|
+
const resolve = registry.resolve.bind(registry);
|
|
19470
19743
|
while (current) {
|
|
19471
19744
|
if (visited.has(current)) break;
|
|
19472
19745
|
visited.add(current);
|
|
19473
|
-
const value = current.
|
|
19474
|
-
if (value
|
|
19475
|
-
const
|
|
19476
|
-
if (!
|
|
19477
|
-
|
|
19478
|
-
current = obj instanceof PdfDict ? obj : null;
|
|
19746
|
+
const value = current.getName(key$1, resolve);
|
|
19747
|
+
if (value) return value.value;
|
|
19748
|
+
const parent = current.getDict("Parent", resolve);
|
|
19749
|
+
if (!parent) break;
|
|
19750
|
+
current = parent;
|
|
19479
19751
|
}
|
|
19480
19752
|
return null;
|
|
19481
19753
|
}
|
|
@@ -19485,15 +19757,15 @@ function getInheritableFieldName(dict, key$1, registry) {
|
|
|
19485
19757
|
function getInheritableFieldNumber(dict, key$1, registry) {
|
|
19486
19758
|
let current = dict;
|
|
19487
19759
|
const visited = /* @__PURE__ */ new Set();
|
|
19760
|
+
const resolve = registry.resolve.bind(registry);
|
|
19488
19761
|
while (current) {
|
|
19489
19762
|
if (visited.has(current)) break;
|
|
19490
19763
|
visited.add(current);
|
|
19491
|
-
const value = current.
|
|
19492
|
-
if (value
|
|
19493
|
-
const
|
|
19494
|
-
if (!
|
|
19495
|
-
|
|
19496
|
-
current = obj instanceof PdfDict ? obj : null;
|
|
19764
|
+
const value = current.getNumber(key$1, resolve);
|
|
19765
|
+
if (value) return value.value;
|
|
19766
|
+
const parent = current.getDict("Parent", resolve);
|
|
19767
|
+
if (!parent) break;
|
|
19768
|
+
current = parent;
|
|
19497
19769
|
}
|
|
19498
19770
|
return 0;
|
|
19499
19771
|
}
|
|
@@ -19548,7 +19820,9 @@ var FieldTree = class FieldTree {
|
|
|
19548
19820
|
* @returns A fully-loaded FieldTree
|
|
19549
19821
|
*/
|
|
19550
19822
|
static load(acroForm, registry) {
|
|
19551
|
-
const
|
|
19823
|
+
const dict = acroForm.getDict();
|
|
19824
|
+
const resolve = registry.resolve.bind(registry);
|
|
19825
|
+
const fieldsArray = dict.getArray("Fields", resolve);
|
|
19552
19826
|
if (!fieldsArray) return new FieldTree([]);
|
|
19553
19827
|
const visited = /* @__PURE__ */ new Set();
|
|
19554
19828
|
const fields = [];
|
|
@@ -19574,7 +19848,7 @@ var FieldTree = class FieldTree {
|
|
|
19574
19848
|
if (item instanceof PdfRef) item = registry.resolve(item) ?? void 0;
|
|
19575
19849
|
if (item instanceof PdfDict) fieldDict = item;
|
|
19576
19850
|
if (!fieldDict) continue;
|
|
19577
|
-
const partialName = fieldDict.getString("T")?.asString() ?? "";
|
|
19851
|
+
const partialName = fieldDict.getString("T", resolve)?.asString() ?? "";
|
|
19578
19852
|
const fullName = parentName ? partialName ? `${parentName}.${partialName}` : parentName : partialName;
|
|
19579
19853
|
if (checkIsTerminalField(fieldDict, registry)) {
|
|
19580
19854
|
const field = createFormField(fieldDict, ref, registry, acroForm, fullName);
|
|
@@ -19587,7 +19861,7 @@ var FieldTree = class FieldTree {
|
|
|
19587
19861
|
nonTerminal.parent = parent;
|
|
19588
19862
|
fields.push(nonTerminal);
|
|
19589
19863
|
if (parent instanceof NonTerminalField) parent.addChild(nonTerminal);
|
|
19590
|
-
const kids = fieldDict.getArray("Kids");
|
|
19864
|
+
const kids = fieldDict.getArray("Kids", resolve);
|
|
19591
19865
|
if (kids) for (let i = 0; i < kids.length; i++) queue.push({
|
|
19592
19866
|
item: kids.at(i),
|
|
19593
19867
|
parentName: fullName,
|
|
@@ -19657,7 +19931,8 @@ var FieldTree = class FieldTree {
|
|
|
19657
19931
|
* - Its /Kids contain widgets (no /T) rather than child fields (have /T)
|
|
19658
19932
|
*/
|
|
19659
19933
|
function checkIsTerminalField(dict, registry) {
|
|
19660
|
-
const
|
|
19934
|
+
const resolve = registry.resolve.bind(registry);
|
|
19935
|
+
const kids = dict.getArray("Kids", resolve);
|
|
19661
19936
|
if (!kids || kids.length === 0) return true;
|
|
19662
19937
|
let firstKid = kids.at(0);
|
|
19663
19938
|
if (!firstKid) return true;
|
|
@@ -19767,7 +20042,7 @@ var FormFlattener = class {
|
|
|
19767
20042
|
for (const pageRef of pageRefs) {
|
|
19768
20043
|
const pageDict = this.registry.resolve(pageRef);
|
|
19769
20044
|
if (!(pageDict instanceof PdfDict)) continue;
|
|
19770
|
-
const annots = pageDict.getArray("Annots");
|
|
20045
|
+
const annots = pageDict.getArray("Annots", this.registry.resolve.bind(this.registry));
|
|
19771
20046
|
if (!annots) continue;
|
|
19772
20047
|
for (let i = 0; i < annots.length; i++) {
|
|
19773
20048
|
const annotRef = annots.at(i);
|
|
@@ -19788,12 +20063,13 @@ var FormFlattener = class {
|
|
|
19788
20063
|
flattenWidgetsOnPage(pageRef, widgets) {
|
|
19789
20064
|
const pageDict = this.registry.resolve(pageRef);
|
|
19790
20065
|
if (!(pageDict instanceof PdfDict)) return;
|
|
19791
|
-
|
|
20066
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
20067
|
+
let resources = pageDict.getDict("Resources", resolve);
|
|
19792
20068
|
if (!resources) {
|
|
19793
20069
|
resources = new PdfDict();
|
|
19794
20070
|
pageDict.set("Resources", resources);
|
|
19795
20071
|
}
|
|
19796
|
-
let xObjects = resources.getDict("XObject");
|
|
20072
|
+
let xObjects = resources.getDict("XObject", resolve);
|
|
19797
20073
|
if (!xObjects) {
|
|
19798
20074
|
xObjects = new PdfDict();
|
|
19799
20075
|
resources.set("XObject", xObjects);
|
|
@@ -19827,7 +20103,7 @@ var FormFlattener = class {
|
|
|
19827
20103
|
* Per PDFBox: BBox must exist and have width/height > 0.
|
|
19828
20104
|
*/
|
|
19829
20105
|
isVisibleAppearance(appearance) {
|
|
19830
|
-
const bbox = appearance.getArray("BBox");
|
|
20106
|
+
const bbox = appearance.getArray("BBox", this.registry.resolve.bind(this.registry));
|
|
19831
20107
|
if (!bbox || bbox.length < 4) return false;
|
|
19832
20108
|
const [x1, y1, x2, y2] = bbox.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
|
|
19833
20109
|
const width = Math.abs((x2 ?? 0) - (x1 ?? 0));
|
|
@@ -19929,7 +20205,7 @@ var FormFlattener = class {
|
|
|
19929
20205
|
* Get the appearance stream's transformation matrix.
|
|
19930
20206
|
*/
|
|
19931
20207
|
getAppearanceMatrix(appearance) {
|
|
19932
|
-
const matrixArray = appearance.getArray("Matrix");
|
|
20208
|
+
const matrixArray = appearance.getArray("Matrix", this.registry.resolve.bind(this.registry));
|
|
19933
20209
|
if (!matrixArray || matrixArray.length < 6) return Matrix.identity();
|
|
19934
20210
|
const [a, b, c, d, e, f] = matrixArray.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
|
|
19935
20211
|
return new Matrix(a ?? 0, b ?? 0, c ?? 0, d ?? 0, e ?? 0, f ?? 0);
|
|
@@ -19938,7 +20214,7 @@ var FormFlattener = class {
|
|
|
19938
20214
|
* Get appearance BBox, with fallback.
|
|
19939
20215
|
*/
|
|
19940
20216
|
getAppearanceBBox(appearance) {
|
|
19941
|
-
const bbox = appearance.getArray("BBox");
|
|
20217
|
+
const bbox = appearance.getArray("BBox", this.registry.resolve.bind(this.registry));
|
|
19942
20218
|
if (!bbox || bbox.length < 4) return [
|
|
19943
20219
|
0,
|
|
19944
20220
|
0,
|
|
@@ -19957,14 +20233,7 @@ var FormFlattener = class {
|
|
|
19957
20233
|
* Remove specific annotations from page.
|
|
19958
20234
|
*/
|
|
19959
20235
|
removeAnnotations(page, toRemove) {
|
|
19960
|
-
const
|
|
19961
|
-
if (!annotsEntry) return;
|
|
19962
|
-
let annots = null;
|
|
19963
|
-
if (annotsEntry instanceof PdfArray) annots = annotsEntry;
|
|
19964
|
-
else if (annotsEntry instanceof PdfRef) {
|
|
19965
|
-
const resolved = this.registry.resolve(annotsEntry);
|
|
19966
|
-
if (resolved instanceof PdfArray) annots = resolved;
|
|
19967
|
-
}
|
|
20236
|
+
const annots = page.getArray("Annots", this.registry.resolve.bind(this.registry));
|
|
19968
20237
|
if (!annots) return;
|
|
19969
20238
|
const remaining = [];
|
|
19970
20239
|
for (let i = 0; i < annots.length; i++) {
|
|
@@ -20030,11 +20299,8 @@ var AcroForm = class AcroForm {
|
|
|
20030
20299
|
* @param pageTree Optional page tree for efficient page lookups during flattening
|
|
20031
20300
|
*/
|
|
20032
20301
|
static load(catalog, registry, pageTree) {
|
|
20033
|
-
|
|
20034
|
-
|
|
20035
|
-
let dict = null;
|
|
20036
|
-
if (acroFormEntry instanceof PdfRef) acroFormEntry = registry.resolve(acroFormEntry) ?? void 0;
|
|
20037
|
-
if (acroFormEntry instanceof PdfDict) dict = acroFormEntry;
|
|
20302
|
+
const resolve = registry.resolve.bind(registry);
|
|
20303
|
+
const dict = catalog.getDict("AcroForm", resolve);
|
|
20038
20304
|
if (!dict) return null;
|
|
20039
20305
|
return new AcroForm(dict, registry, pageTree ?? null);
|
|
20040
20306
|
}
|
|
@@ -20042,11 +20308,7 @@ var AcroForm = class AcroForm {
|
|
|
20042
20308
|
* Default resources dictionary (fonts, etc.).
|
|
20043
20309
|
*/
|
|
20044
20310
|
getDefaultResources() {
|
|
20045
|
-
|
|
20046
|
-
if (!dr) return null;
|
|
20047
|
-
if (dr instanceof PdfRef) dr = this.registry.resolve(dr) ?? void 0;
|
|
20048
|
-
if (dr instanceof PdfDict) return dr;
|
|
20049
|
-
return null;
|
|
20311
|
+
return this.dict.getDict("DR", this.registry.resolve.bind(this.registry)) ?? null;
|
|
20050
20312
|
}
|
|
20051
20313
|
/**
|
|
20052
20314
|
* Default appearance string.
|
|
@@ -20210,9 +20472,10 @@ var AcroForm = class AcroForm {
|
|
|
20210
20472
|
ensureExistingFontsLoaded() {
|
|
20211
20473
|
if (this.existingFontsCache !== null) return;
|
|
20212
20474
|
this.existingFontsCache = /* @__PURE__ */ new Map();
|
|
20213
|
-
const
|
|
20475
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
20476
|
+
const dr = this.dict.getDict("DR", resolve);
|
|
20214
20477
|
if (!dr) return;
|
|
20215
|
-
const fonts = dr.getDict("Font");
|
|
20478
|
+
const fonts = dr.getDict("Font", resolve);
|
|
20216
20479
|
if (!fonts) return;
|
|
20217
20480
|
for (const key$1 of fonts.keys()) {
|
|
20218
20481
|
const fontName = key$1.value;
|
|
@@ -20387,12 +20650,13 @@ var AcroForm = class AcroForm {
|
|
|
20387
20650
|
* @returns The font name used in the /DR dictionary
|
|
20388
20651
|
*/
|
|
20389
20652
|
addFontToResources(fontRef, name) {
|
|
20390
|
-
|
|
20653
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
20654
|
+
let dr = this.dict.getDict("DR", resolve);
|
|
20391
20655
|
if (!dr) {
|
|
20392
20656
|
dr = new PdfDict();
|
|
20393
20657
|
this.dict.set("DR", dr);
|
|
20394
20658
|
}
|
|
20395
|
-
let fontsDict = dr.getDict("Font");
|
|
20659
|
+
let fontsDict = dr.getDict("Font", resolve);
|
|
20396
20660
|
if (!fontsDict) {
|
|
20397
20661
|
fontsDict = new PdfDict();
|
|
20398
20662
|
dr.set("Font", fontsDict);
|
|
@@ -20476,371 +20740,8 @@ var AcroForm = class AcroForm {
|
|
|
20476
20740
|
}
|
|
20477
20741
|
};
|
|
20478
20742
|
|
|
20479
|
-
//#endregion
|
|
20480
|
-
//#region src/fonts/embedded-font.ts
|
|
20481
|
-
/**
|
|
20482
|
-
* EmbeddedFont represents a font that will be embedded into a PDF.
|
|
20483
|
-
*
|
|
20484
|
-
* Usage:
|
|
20485
|
-
* ```typescript
|
|
20486
|
-
* const fontBytes = await fs.readFile("NotoSans-Regular.ttf");
|
|
20487
|
-
* const font = EmbeddedFont.fromBytes(fontBytes);
|
|
20488
|
-
*
|
|
20489
|
-
* // Check if text can be encoded
|
|
20490
|
-
* if (font.canEncode("Hello ")) {
|
|
20491
|
-
* const codes = font.encodeText("Hello ");
|
|
20492
|
-
* const width = font.getTextWidth("Hello ", 12);
|
|
20493
|
-
* }
|
|
20494
|
-
* ```
|
|
20495
|
-
*/
|
|
20496
|
-
var EmbeddedFont = class EmbeddedFont extends PdfFont {
|
|
20497
|
-
subtype = "Type0";
|
|
20498
|
-
/** Underlying font program */
|
|
20499
|
-
fontProgram;
|
|
20500
|
-
/** Original font data */
|
|
20501
|
-
fontData;
|
|
20502
|
-
/** Track used glyphs for subsetting (GID -> code points that use it) */
|
|
20503
|
-
usedGlyphs = new Map([[0, /* @__PURE__ */ new Set()]]);
|
|
20504
|
-
/** Track used code points for ToUnicode (codePoint -> GID) */
|
|
20505
|
-
usedCodePoints = /* @__PURE__ */ new Map();
|
|
20506
|
-
/** Subset tag (generated during save) */
|
|
20507
|
-
_subsetTag = null;
|
|
20508
|
-
/** Whether this font is used in a form field (prevents subsetting) */
|
|
20509
|
-
_usedInForm = false;
|
|
20510
|
-
/** Cached descriptor */
|
|
20511
|
-
_descriptor = null;
|
|
20512
|
-
constructor(fontProgram, fontData) {
|
|
20513
|
-
super();
|
|
20514
|
-
this.fontProgram = fontProgram;
|
|
20515
|
-
this.fontData = fontData;
|
|
20516
|
-
}
|
|
20517
|
-
/**
|
|
20518
|
-
* Create an EmbeddedFont from raw font bytes.
|
|
20519
|
-
*
|
|
20520
|
-
* @param data - TTF, OTF, or Type1 font data
|
|
20521
|
-
* @param options - Embedding options
|
|
20522
|
-
* @returns EmbeddedFont instance
|
|
20523
|
-
* @throws {Error} if font format is not recognized
|
|
20524
|
-
*/
|
|
20525
|
-
static fromBytes(data, _options) {
|
|
20526
|
-
return new EmbeddedFont(parseFontProgram(data), data);
|
|
20527
|
-
}
|
|
20528
|
-
/**
|
|
20529
|
-
* Create an EmbeddedFont from an already-parsed TrueType font.
|
|
20530
|
-
*/
|
|
20531
|
-
static fromTrueTypeFont(font, data) {
|
|
20532
|
-
return new EmbeddedFont(new TrueTypeFontProgram(font, data), data);
|
|
20533
|
-
}
|
|
20534
|
-
/**
|
|
20535
|
-
* Get the base font name.
|
|
20536
|
-
* During save, this will include a subset tag prefix (e.g., "ABCDEF+FontName").
|
|
20537
|
-
*/
|
|
20538
|
-
get baseFontName() {
|
|
20539
|
-
const name = this.fontProgram.postScriptName ?? "Unknown";
|
|
20540
|
-
return this._subsetTag ? `${this._subsetTag}+${name}` : name;
|
|
20541
|
-
}
|
|
20542
|
-
/**
|
|
20543
|
-
* Get the font descriptor.
|
|
20544
|
-
*/
|
|
20545
|
-
get descriptor() {
|
|
20546
|
-
if (!this._descriptor) this._descriptor = this.buildDescriptor();
|
|
20547
|
-
return this._descriptor;
|
|
20548
|
-
}
|
|
20549
|
-
/**
|
|
20550
|
-
* Get the underlying font program.
|
|
20551
|
-
*/
|
|
20552
|
-
get program() {
|
|
20553
|
-
return this.fontProgram;
|
|
20554
|
-
}
|
|
20555
|
-
/**
|
|
20556
|
-
* Get the original font data.
|
|
20557
|
-
*/
|
|
20558
|
-
get data() {
|
|
20559
|
-
return this.fontData;
|
|
20560
|
-
}
|
|
20561
|
-
/**
|
|
20562
|
-
* Get the subset tag (only available after save).
|
|
20563
|
-
*/
|
|
20564
|
-
get subsetTag() {
|
|
20565
|
-
return this._subsetTag;
|
|
20566
|
-
}
|
|
20567
|
-
/**
|
|
20568
|
-
* Set the subset tag (called during save).
|
|
20569
|
-
*/
|
|
20570
|
-
setSubsetTag(tag) {
|
|
20571
|
-
this._subsetTag = tag;
|
|
20572
|
-
}
|
|
20573
|
-
/**
|
|
20574
|
-
* Get all used glyph IDs.
|
|
20575
|
-
*/
|
|
20576
|
-
getUsedGlyphIds() {
|
|
20577
|
-
return [...this.usedGlyphs.keys()].sort((a, b) => a - b);
|
|
20578
|
-
}
|
|
20579
|
-
/**
|
|
20580
|
-
* Get mapping from code point to GID.
|
|
20581
|
-
*/
|
|
20582
|
-
getCodePointToGidMap() {
|
|
20583
|
-
return new Map(this.usedCodePoints);
|
|
20584
|
-
}
|
|
20585
|
-
/**
|
|
20586
|
-
* Get mapping from GID to Unicode code point.
|
|
20587
|
-
*
|
|
20588
|
-
* This is used for building the /W widths array and ToUnicode CMap.
|
|
20589
|
-
* Since the content stream contains GIDs (with CIDToGIDMap /Identity),
|
|
20590
|
-
* the /W array must be keyed by GID, and ToUnicode must map GID → Unicode.
|
|
20591
|
-
*
|
|
20592
|
-
* If multiple code points map to the same GID, returns the first one found.
|
|
20593
|
-
*/
|
|
20594
|
-
getGidToCodePointMap() {
|
|
20595
|
-
const result = /* @__PURE__ */ new Map();
|
|
20596
|
-
for (const [gid, codePoints] of this.usedGlyphs) if (codePoints.size > 0) {
|
|
20597
|
-
const firstCodePoint = codePoints.values().next().value;
|
|
20598
|
-
if (firstCodePoint !== void 0) result.set(gid, firstCodePoint);
|
|
20599
|
-
}
|
|
20600
|
-
return result;
|
|
20601
|
-
}
|
|
20602
|
-
/**
|
|
20603
|
-
* Iterate over text, tracking glyph usage and returning codePoint/GID pairs.
|
|
20604
|
-
* This is the shared implementation for encodeText and encodeTextToGids.
|
|
20605
|
-
*/
|
|
20606
|
-
trackAndEncode(text) {
|
|
20607
|
-
const result = [];
|
|
20608
|
-
for (const char of text) {
|
|
20609
|
-
const codePoint = char.codePointAt(0);
|
|
20610
|
-
if (codePoint === void 0) continue;
|
|
20611
|
-
const gid = this.fontProgram.getGlyphId(codePoint);
|
|
20612
|
-
if (!this.usedGlyphs.has(gid)) this.usedGlyphs.set(gid, /* @__PURE__ */ new Set());
|
|
20613
|
-
this.usedGlyphs.get(gid).add(codePoint);
|
|
20614
|
-
this.usedCodePoints.set(codePoint, gid);
|
|
20615
|
-
result.push({
|
|
20616
|
-
codePoint,
|
|
20617
|
-
gid
|
|
20618
|
-
});
|
|
20619
|
-
}
|
|
20620
|
-
return result;
|
|
20621
|
-
}
|
|
20622
|
-
/**
|
|
20623
|
-
* Encode text to character codes.
|
|
20624
|
-
*
|
|
20625
|
-
* Returns Unicode code points, which is intuitive for users.
|
|
20626
|
-
* The conversion to glyph IDs happens internally when writing to the PDF.
|
|
20627
|
-
*
|
|
20628
|
-
* Also tracks glyph usage for subsetting.
|
|
20629
|
-
*/
|
|
20630
|
-
encodeText(text) {
|
|
20631
|
-
return this.trackAndEncode(text).map((e) => e.codePoint);
|
|
20632
|
-
}
|
|
20633
|
-
/**
|
|
20634
|
-
* Encode text to glyph IDs for PDF content stream.
|
|
20635
|
-
*
|
|
20636
|
-
* This is an internal method used when writing to the PDF.
|
|
20637
|
-
* With CIDToGIDMap /Identity, the content stream must contain GIDs.
|
|
20638
|
-
*
|
|
20639
|
-
* @internal
|
|
20640
|
-
*/
|
|
20641
|
-
encodeTextToGids(text) {
|
|
20642
|
-
return this.trackAndEncode(text).map((e) => e.gid);
|
|
20643
|
-
}
|
|
20644
|
-
/**
|
|
20645
|
-
* Convert a code point to its glyph ID.
|
|
20646
|
-
*
|
|
20647
|
-
* @internal
|
|
20648
|
-
*/
|
|
20649
|
-
codePointToGid(codePoint) {
|
|
20650
|
-
return this.fontProgram.getGlyphId(codePoint);
|
|
20651
|
-
}
|
|
20652
|
-
/**
|
|
20653
|
-
* Get width of a character in glyph units (1000 = 1 em).
|
|
20654
|
-
*
|
|
20655
|
-
* Takes a Unicode code point (user-friendly API).
|
|
20656
|
-
*/
|
|
20657
|
-
getWidth(code) {
|
|
20658
|
-
const gid = this.fontProgram.getGlyphId(code);
|
|
20659
|
-
const width = this.fontProgram.getAdvanceWidth(gid);
|
|
20660
|
-
return Math.round(width * 1e3 / this.fontProgram.unitsPerEm);
|
|
20661
|
-
}
|
|
20662
|
-
/**
|
|
20663
|
-
* Decode character code to Unicode string.
|
|
20664
|
-
*
|
|
20665
|
-
* For embedded fonts with Identity-H encoding, the code is the code point,
|
|
20666
|
-
* so this just converts the code point back to a string.
|
|
20667
|
-
*/
|
|
20668
|
-
toUnicode(code) {
|
|
20669
|
-
return String.fromCodePoint(code);
|
|
20670
|
-
}
|
|
20671
|
-
/**
|
|
20672
|
-
* Check if the font can encode the given text.
|
|
20673
|
-
* Returns true if all characters have glyphs in the font.
|
|
20674
|
-
*/
|
|
20675
|
-
canEncode(text) {
|
|
20676
|
-
for (const char of text) {
|
|
20677
|
-
const codePoint = char.codePointAt(0);
|
|
20678
|
-
if (codePoint === void 0) continue;
|
|
20679
|
-
if (!this.fontProgram.hasGlyph(codePoint)) return false;
|
|
20680
|
-
}
|
|
20681
|
-
return true;
|
|
20682
|
-
}
|
|
20683
|
-
/**
|
|
20684
|
-
* Get the characters that cannot be encoded.
|
|
20685
|
-
*/
|
|
20686
|
-
getUnencodableCharacters(text) {
|
|
20687
|
-
const unencodable = [];
|
|
20688
|
-
for (const char of text) {
|
|
20689
|
-
const codePoint = char.codePointAt(0);
|
|
20690
|
-
if (codePoint === void 0) continue;
|
|
20691
|
-
if (!this.fontProgram.hasGlyph(codePoint)) unencodable.push(char);
|
|
20692
|
-
}
|
|
20693
|
-
return unencodable;
|
|
20694
|
-
}
|
|
20695
|
-
/**
|
|
20696
|
-
* Reset glyph usage tracking.
|
|
20697
|
-
* Call this before re-encoding if you want a fresh subset.
|
|
20698
|
-
*/
|
|
20699
|
-
resetUsage() {
|
|
20700
|
-
this.usedGlyphs.clear();
|
|
20701
|
-
this.usedGlyphs.set(0, /* @__PURE__ */ new Set());
|
|
20702
|
-
this.usedCodePoints.clear();
|
|
20703
|
-
this._subsetTag = null;
|
|
20704
|
-
}
|
|
20705
|
-
/**
|
|
20706
|
-
* Mark this font as used in a form field.
|
|
20707
|
-
*
|
|
20708
|
-
* Fonts used in form fields cannot be subsetted because users may type
|
|
20709
|
-
* any character at runtime. This method is called automatically when
|
|
20710
|
-
* an EmbeddedFont is used in form field appearances.
|
|
20711
|
-
*/
|
|
20712
|
-
markUsedInForm() {
|
|
20713
|
-
this._usedInForm = true;
|
|
20714
|
-
}
|
|
20715
|
-
/**
|
|
20716
|
-
* Check if this font is used in a form field.
|
|
20717
|
-
*/
|
|
20718
|
-
get usedInForm() {
|
|
20719
|
-
return this._usedInForm;
|
|
20720
|
-
}
|
|
20721
|
-
/**
|
|
20722
|
-
* Check if this font can be subsetted.
|
|
20723
|
-
*
|
|
20724
|
-
* Returns false if the font is used in a form field (since users can
|
|
20725
|
-
* type any character at runtime).
|
|
20726
|
-
*/
|
|
20727
|
-
canSubset() {
|
|
20728
|
-
return !this._usedInForm;
|
|
20729
|
-
}
|
|
20730
|
-
/**
|
|
20731
|
-
* Get width of text in points at a given font size.
|
|
20732
|
-
*
|
|
20733
|
-
* Alias for getTextWidth() to match Standard14Font API.
|
|
20734
|
-
*
|
|
20735
|
-
* @param text - The text to measure
|
|
20736
|
-
* @param size - Font size in points
|
|
20737
|
-
* @returns Width in points
|
|
20738
|
-
*/
|
|
20739
|
-
widthOfTextAtSize(text, size) {
|
|
20740
|
-
return this.getTextWidth(text, size);
|
|
20741
|
-
}
|
|
20742
|
-
/**
|
|
20743
|
-
* Get the height of the font at a given size.
|
|
20744
|
-
*
|
|
20745
|
-
* This returns the full height from descender to ascender.
|
|
20746
|
-
*
|
|
20747
|
-
* @param size - Font size in points
|
|
20748
|
-
* @returns Height in points
|
|
20749
|
-
*/
|
|
20750
|
-
heightAtSize(size) {
|
|
20751
|
-
const desc = this.descriptor;
|
|
20752
|
-
if (!desc) return size;
|
|
20753
|
-
return (desc.ascent - desc.descent) * size / 1e3;
|
|
20754
|
-
}
|
|
20755
|
-
/**
|
|
20756
|
-
* Calculate font size needed to achieve a specific text height.
|
|
20757
|
-
*
|
|
20758
|
-
* @param height - Desired height in points
|
|
20759
|
-
* @returns Font size in points
|
|
20760
|
-
*/
|
|
20761
|
-
sizeAtHeight(height) {
|
|
20762
|
-
const desc = this.descriptor;
|
|
20763
|
-
if (!desc) return height;
|
|
20764
|
-
const unitsHeight = desc.ascent - desc.descent;
|
|
20765
|
-
return height * 1e3 / unitsHeight;
|
|
20766
|
-
}
|
|
20767
|
-
/**
|
|
20768
|
-
* Calculate font size needed for text to fit a specific width.
|
|
20769
|
-
*
|
|
20770
|
-
* @param text - The text to measure
|
|
20771
|
-
* @param width - Desired width in points
|
|
20772
|
-
* @returns Font size in points
|
|
20773
|
-
*/
|
|
20774
|
-
sizeAtWidth(text, width) {
|
|
20775
|
-
if (text.length === 0) return 0;
|
|
20776
|
-
const codes = this.encodeText(text);
|
|
20777
|
-
let totalWidth = 0;
|
|
20778
|
-
for (const code of codes) totalWidth += this.getWidth(code);
|
|
20779
|
-
if (totalWidth === 0) return 0;
|
|
20780
|
-
return width * 1e3 / totalWidth;
|
|
20781
|
-
}
|
|
20782
|
-
/**
|
|
20783
|
-
* Build a FontDescriptor from the font program.
|
|
20784
|
-
*/
|
|
20785
|
-
buildDescriptor() {
|
|
20786
|
-
const program = this.fontProgram;
|
|
20787
|
-
const bbox = program.bbox;
|
|
20788
|
-
const scale = 1e3 / program.unitsPerEm;
|
|
20789
|
-
return new FontDescriptor({
|
|
20790
|
-
fontName: program.postScriptName ?? "Unknown",
|
|
20791
|
-
flags: this.computeFlags(),
|
|
20792
|
-
fontBBox: [
|
|
20793
|
-
Math.round(bbox[0] * scale),
|
|
20794
|
-
Math.round(bbox[1] * scale),
|
|
20795
|
-
Math.round(bbox[2] * scale),
|
|
20796
|
-
Math.round(bbox[3] * scale)
|
|
20797
|
-
],
|
|
20798
|
-
italicAngle: program.italicAngle,
|
|
20799
|
-
ascent: Math.round(program.ascent * scale),
|
|
20800
|
-
descent: Math.round(program.descent * scale),
|
|
20801
|
-
leading: 0,
|
|
20802
|
-
capHeight: Math.round(program.capHeight * scale),
|
|
20803
|
-
xHeight: Math.round(program.xHeight * scale),
|
|
20804
|
-
stemV: program.stemV,
|
|
20805
|
-
stemH: 0,
|
|
20806
|
-
avgWidth: 0,
|
|
20807
|
-
maxWidth: 0,
|
|
20808
|
-
missingWidth: this.getWidth(0)
|
|
20809
|
-
});
|
|
20810
|
-
}
|
|
20811
|
-
/**
|
|
20812
|
-
* Compute font flags for the descriptor.
|
|
20813
|
-
*/
|
|
20814
|
-
computeFlags() {
|
|
20815
|
-
let flags = 0;
|
|
20816
|
-
if (this.fontProgram.isFixedPitch) flags |= 1;
|
|
20817
|
-
flags |= 4;
|
|
20818
|
-
if (this.fontProgram.italicAngle !== 0) flags |= 64;
|
|
20819
|
-
return flags;
|
|
20820
|
-
}
|
|
20821
|
-
};
|
|
20822
|
-
|
|
20823
20743
|
//#endregion
|
|
20824
20744
|
//#region src/fonts/cid-font.ts
|
|
20825
|
-
/**
|
|
20826
|
-
* CIDFont - Descendant font for Type0 composite fonts.
|
|
20827
|
-
*
|
|
20828
|
-
* CIDFonts contain the actual glyph descriptions and metrics for
|
|
20829
|
-
* composite (Type0) fonts. They use CIDs (Character IDs) to identify
|
|
20830
|
-
* glyphs rather than character codes.
|
|
20831
|
-
*
|
|
20832
|
-
* Font structure:
|
|
20833
|
-
* <<
|
|
20834
|
-
* /Type /Font
|
|
20835
|
-
* /Subtype /CIDFontType2 (or /CIDFontType0)
|
|
20836
|
-
* /BaseFont /NotoSansCJK-Regular
|
|
20837
|
-
* /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>
|
|
20838
|
-
* /FontDescriptor 14 0 R
|
|
20839
|
-
* /W [1 [500 600] 100 200 500] % Complex width format
|
|
20840
|
-
* /DW 1000
|
|
20841
|
-
* /CIDToGIDMap /Identity
|
|
20842
|
-
* >>
|
|
20843
|
-
*/
|
|
20844
20745
|
const isCIDFontSubtype = (subtype) => {
|
|
20845
20746
|
return subtype === "CIDFontType0" || subtype === "CIDFontType2";
|
|
20846
20747
|
};
|
|
@@ -21005,7 +20906,7 @@ function parseCIDFont(dict, options = {}) {
|
|
|
21005
20906
|
ordering: "Identity",
|
|
21006
20907
|
supplement: 0
|
|
21007
20908
|
};
|
|
21008
|
-
const sysInfoDict = dict.getDict("CIDSystemInfo");
|
|
20909
|
+
const sysInfoDict = dict.getDict("CIDSystemInfo", options.resolver);
|
|
21009
20910
|
if (sysInfoDict) cidSystemInfo = {
|
|
21010
20911
|
registry: sysInfoDict.getString("Registry")?.asString() ?? "Adobe",
|
|
21011
20912
|
ordering: sysInfoDict.getString("Ordering")?.asString() ?? "Identity",
|
|
@@ -21013,30 +20914,23 @@ function parseCIDFont(dict, options = {}) {
|
|
|
21013
20914
|
};
|
|
21014
20915
|
const defaultWidth = dict.getNumber("DW")?.value ?? 1e3;
|
|
21015
20916
|
let widths = new CIDWidthMap();
|
|
21016
|
-
let w = dict.get("W");
|
|
20917
|
+
let w = dict.get("W", options.resolver);
|
|
21017
20918
|
let wArray = null;
|
|
21018
|
-
if (w instanceof PdfRef && options.resolveRef) w = options.resolveRef(w) ?? void 0;
|
|
21019
20919
|
if (w instanceof PdfArray) wArray = w;
|
|
21020
20920
|
if (wArray) widths = parseCIDWidths(wArray);
|
|
21021
20921
|
let descriptor = null;
|
|
21022
20922
|
let embeddedProgram = null;
|
|
21023
|
-
const
|
|
21024
|
-
if (
|
|
21025
|
-
|
|
21026
|
-
|
|
21027
|
-
descriptor = FontDescriptor.parse(descriptorDict);
|
|
21028
|
-
if (options.decodeStream) embeddedProgram = parseEmbeddedProgram(descriptorDict, {
|
|
21029
|
-
decodeStream: options.decodeStream,
|
|
21030
|
-
resolveRef: options.resolveRef
|
|
21031
|
-
});
|
|
21032
|
-
}
|
|
20923
|
+
const fontDescriptor = dict.getDict("FontDescriptor", options.resolver);
|
|
20924
|
+
if (fontDescriptor) {
|
|
20925
|
+
descriptor = FontDescriptor.parse(fontDescriptor);
|
|
20926
|
+
embeddedProgram = parseEmbeddedProgram(fontDescriptor, { resolver: options.resolver });
|
|
21033
20927
|
}
|
|
21034
20928
|
let cidToGidMap = "Identity";
|
|
21035
|
-
const cidToGidValue = dict.get("CIDToGIDMap");
|
|
20929
|
+
const cidToGidValue = dict.get("CIDToGIDMap", options.resolver);
|
|
21036
20930
|
if (cidToGidValue) {
|
|
21037
|
-
if (cidToGidValue
|
|
21038
|
-
if (cidToGidValue
|
|
21039
|
-
const mapData =
|
|
20931
|
+
if (cidToGidValue instanceof PdfName && cidToGidValue.value === "Identity") cidToGidMap = "Identity";
|
|
20932
|
+
if (cidToGidValue instanceof PdfStream) {
|
|
20933
|
+
const mapData = cidToGidValue.getDecodedData();
|
|
21040
20934
|
if (mapData && mapData.length >= 2) {
|
|
21041
20935
|
const numEntries = mapData.length / 2;
|
|
21042
20936
|
cidToGidMap = new Uint16Array(numEntries);
|
|
@@ -21318,24 +21212,6 @@ function bytesToLatin1$1(data) {
|
|
|
21318
21212
|
//#endregion
|
|
21319
21213
|
//#region src/fonts/composite-font.ts
|
|
21320
21214
|
/**
|
|
21321
|
-
* CompositeFont - Type0 composite font for CJK and Unicode text.
|
|
21322
|
-
*
|
|
21323
|
-
* Composite fonts (Type0) combine:
|
|
21324
|
-
* - A CMap (character code to CID mapping)
|
|
21325
|
-
* - One or more CIDFonts (the actual glyph data)
|
|
21326
|
-
* - Optional ToUnicode map (for text extraction)
|
|
21327
|
-
*
|
|
21328
|
-
* Font structure:
|
|
21329
|
-
* <<
|
|
21330
|
-
* /Type /Font
|
|
21331
|
-
* /Subtype /Type0
|
|
21332
|
-
* /BaseFont /NotoSansCJK-Regular
|
|
21333
|
-
* /Encoding /Identity-H (or stream)
|
|
21334
|
-
* /DescendantFonts [12 0 R]
|
|
21335
|
-
* /ToUnicode 13 0 R
|
|
21336
|
-
* >>
|
|
21337
|
-
*/
|
|
21338
|
-
/**
|
|
21339
21215
|
* CompositeFont handles Type0 composite fonts (CJK, Unicode).
|
|
21340
21216
|
*/
|
|
21341
21217
|
var CompositeFont = class extends PdfFont {
|
|
@@ -21410,40 +21286,28 @@ var CompositeFont = class extends PdfFont {
|
|
|
21410
21286
|
* Parse CMap from encoding value.
|
|
21411
21287
|
*/
|
|
21412
21288
|
function parseCMapFromEncoding(encodingValue, options) {
|
|
21413
|
-
|
|
21414
|
-
|
|
21415
|
-
if (
|
|
21416
|
-
if (
|
|
21417
|
-
const data =
|
|
21289
|
+
let encoding = encodingValue;
|
|
21290
|
+
if (encoding instanceof PdfRef && options.resolver) encoding = options.resolver(encoding) ?? void 0;
|
|
21291
|
+
if (encoding instanceof PdfName && encoding.value) return CMap.getPredefined(encoding.value) ?? CMap.identityH();
|
|
21292
|
+
if (encoding instanceof PdfStream) {
|
|
21293
|
+
const data = encoding.getDecodedData();
|
|
21418
21294
|
return data ? parseCMap(data) : CMap.identityH();
|
|
21419
21295
|
}
|
|
21420
|
-
if (enc.type === "ref" && options.resolveRef && options.decodeStream) {
|
|
21421
|
-
const resolved = options.resolveRef(encodingValue);
|
|
21422
|
-
if (resolved && resolved.type === "stream") {
|
|
21423
|
-
const data = options.decodeStream(resolved);
|
|
21424
|
-
return data ? parseCMap(data) : CMap.identityH();
|
|
21425
|
-
}
|
|
21426
|
-
}
|
|
21427
21296
|
return CMap.identityH();
|
|
21428
21297
|
}
|
|
21429
21298
|
/**
|
|
21430
21299
|
* Parse a CompositeFont from a PDF font dictionary.
|
|
21431
21300
|
*/
|
|
21432
21301
|
function parseCompositeFont(dict, options = {}) {
|
|
21433
|
-
const baseFontName = dict.getName("BaseFont")?.value ?? "Unknown";
|
|
21434
|
-
const cmap = parseCMapFromEncoding(dict.get("Encoding"), options);
|
|
21302
|
+
const baseFontName = dict.getName("BaseFont", options.resolver)?.value ?? "Unknown";
|
|
21303
|
+
const cmap = parseCMapFromEncoding(dict.get("Encoding", options.resolver), options);
|
|
21435
21304
|
let cidFont;
|
|
21436
|
-
let descendants = dict.get("DescendantFonts");
|
|
21305
|
+
let descendants = dict.get("DescendantFonts", options.resolver);
|
|
21437
21306
|
let descendantsArray = null;
|
|
21438
|
-
if (descendants instanceof PdfRef && options.resolveRef) descendants = options.resolveRef(descendants) ?? void 0;
|
|
21439
21307
|
if (descendants instanceof PdfArray) descendantsArray = descendants;
|
|
21440
21308
|
if (descendantsArray && descendantsArray.length > 0) {
|
|
21441
|
-
const firstDescendant = descendantsArray.at(0);
|
|
21442
|
-
if (firstDescendant
|
|
21443
|
-
const cidFontDict = options.resolveRef(firstDescendant);
|
|
21444
|
-
if (cidFontDict?.type === "dict") cidFont = parseCIDFont(cidFontDict, options);
|
|
21445
|
-
else cidFont = createDefaultCIDFont(baseFontName);
|
|
21446
|
-
} else if (firstDescendant?.type === "dict") cidFont = parseCIDFont(firstDescendant, options);
|
|
21309
|
+
const firstDescendant = descendantsArray.at(0, options.resolver);
|
|
21310
|
+
if (firstDescendant instanceof PdfDict) cidFont = parseCIDFont(firstDescendant, options);
|
|
21447
21311
|
else cidFont = createDefaultCIDFont(baseFontName);
|
|
21448
21312
|
} else cidFont = createDefaultCIDFont(baseFontName);
|
|
21449
21313
|
return new CompositeFont({
|
|
@@ -21474,7 +21338,7 @@ function createDefaultCIDFont(baseFontName) {
|
|
|
21474
21338
|
* @returns A SimpleFont or CompositeFont instance
|
|
21475
21339
|
*/
|
|
21476
21340
|
function parseFont(dict, options = {}) {
|
|
21477
|
-
switch (dict.getName("Subtype")?.value) {
|
|
21341
|
+
switch (dict.getName("Subtype", options.resolver)?.value) {
|
|
21478
21342
|
case "Type0": return parseCompositeFont(dict, options);
|
|
21479
21343
|
case "TrueType":
|
|
21480
21344
|
case "Type1":
|
|
@@ -24300,8 +24164,8 @@ var PDFPage = class PDFPage {
|
|
|
24300
24164
|
* Page rotation in degrees (0, 90, 180, or 270).
|
|
24301
24165
|
*/
|
|
24302
24166
|
get rotation() {
|
|
24303
|
-
const rotate = this.dict.
|
|
24304
|
-
if (rotate
|
|
24167
|
+
const rotate = this.dict.getNumber("Rotate", this.ctx.resolve.bind(this.ctx));
|
|
24168
|
+
if (rotate) {
|
|
24305
24169
|
const value = rotate.value % 360;
|
|
24306
24170
|
if (value === 90 || value === -270) return 90;
|
|
24307
24171
|
if (value === 180 || value === -180) return 180;
|
|
@@ -24321,14 +24185,15 @@ var PDFPage = class PDFPage {
|
|
|
24321
24185
|
/**
|
|
24322
24186
|
* Get the page's Resources dictionary.
|
|
24323
24187
|
*
|
|
24324
|
-
*
|
|
24188
|
+
* If Resources is a reference, it's dereferenced.
|
|
24189
|
+
* If Resources doesn't exist or is inherited from a parent,
|
|
24190
|
+
* a new empty dict is created on this page.
|
|
24325
24191
|
*/
|
|
24326
24192
|
getResources() {
|
|
24327
|
-
let resources = this.dict.get("Resources");
|
|
24328
|
-
if (
|
|
24329
|
-
|
|
24330
|
-
|
|
24331
|
-
}
|
|
24193
|
+
let resources = this.dict.get("Resources", this.ctx.resolve.bind(this.ctx));
|
|
24194
|
+
if (resources instanceof PdfDict) return resources;
|
|
24195
|
+
resources = new PdfDict();
|
|
24196
|
+
this.dict.set("Resources", resources);
|
|
24332
24197
|
return resources;
|
|
24333
24198
|
}
|
|
24334
24199
|
/**
|
|
@@ -24458,7 +24323,6 @@ var PDFPage = class PDFPage {
|
|
|
24458
24323
|
* ```
|
|
24459
24324
|
*/
|
|
24460
24325
|
drawField(field, options) {
|
|
24461
|
-
if (!this.ctx) throw new Error("Cannot draw field on page without context");
|
|
24462
24326
|
if (!(field instanceof TerminalField)) throw new Error(`Cannot draw non-terminal field "${field.name}"`);
|
|
24463
24327
|
if (field instanceof SignatureField) throw new Error("Signature fields cannot be drawn with drawField. Use form.createSignatureField() which creates the widget automatically.");
|
|
24464
24328
|
if (field instanceof RadioField) {
|
|
@@ -24543,7 +24407,6 @@ var PDFPage = class PDFPage {
|
|
|
24543
24407
|
* Generate appearance stream for a widget.
|
|
24544
24408
|
*/
|
|
24545
24409
|
generateWidgetAppearance(field, widget, options) {
|
|
24546
|
-
if (!this.ctx) return;
|
|
24547
24410
|
const catalogDict = this.ctx.catalog.getDict();
|
|
24548
24411
|
const acroForm = AcroForm.load(catalogDict, this.ctx.registry);
|
|
24549
24412
|
if (!acroForm) return;
|
|
@@ -25008,13 +24871,9 @@ var PDFPage = class PDFPage {
|
|
|
25008
24871
|
for (let i = 0; i < annotsArray.length; i++) {
|
|
25009
24872
|
const entry = annotsArray.at(i);
|
|
25010
24873
|
if (!entry) continue;
|
|
25011
|
-
|
|
25012
|
-
|
|
25013
|
-
|
|
25014
|
-
annotRef = entry;
|
|
25015
|
-
const resolved = this.ctx.resolve(entry);
|
|
25016
|
-
if (resolved instanceof PdfDict) annotDict = resolved;
|
|
25017
|
-
} else if (entry instanceof PdfDict) annotDict = entry;
|
|
24874
|
+
const resolved = entry instanceof PdfRef ? this.ctx.resolve(entry) : entry;
|
|
24875
|
+
const annotRef = entry instanceof PdfRef ? entry : null;
|
|
24876
|
+
const annotDict = resolved instanceof PdfDict ? resolved : null;
|
|
25018
24877
|
if (!annotDict) continue;
|
|
25019
24878
|
if (isWidgetAnnotation(annotDict)) continue;
|
|
25020
24879
|
if (isPopupAnnotation(annotDict)) continue;
|
|
@@ -25036,13 +24895,9 @@ var PDFPage = class PDFPage {
|
|
|
25036
24895
|
for (let i = 0; i < annotsArray.length; i++) {
|
|
25037
24896
|
let entry = annotsArray.at(i);
|
|
25038
24897
|
if (!entry) continue;
|
|
25039
|
-
|
|
25040
|
-
|
|
25041
|
-
|
|
25042
|
-
annotRef = entry;
|
|
25043
|
-
entry = this.ctx.resolve(entry) ?? void 0;
|
|
25044
|
-
}
|
|
25045
|
-
if (entry instanceof PdfDict) annotDict = entry;
|
|
24898
|
+
const resolved = entry instanceof PdfRef ? this.ctx.resolve(entry) : entry;
|
|
24899
|
+
const annotRef = entry instanceof PdfRef ? entry : null;
|
|
24900
|
+
const annotDict = resolved instanceof PdfDict ? resolved : null;
|
|
25046
24901
|
if (!annotDict || !isPopupAnnotation(annotDict)) continue;
|
|
25047
24902
|
popups.push(new PDFPopupAnnotation(annotDict, annotRef, this.ctx.registry));
|
|
25048
24903
|
}
|
|
@@ -25193,7 +25048,6 @@ var PDFPage = class PDFPage {
|
|
|
25193
25048
|
* Add a text markup annotation (internal helper).
|
|
25194
25049
|
*/
|
|
25195
25050
|
addTextMarkupAnnotation(subtype, options) {
|
|
25196
|
-
if (!this.ctx) throw new Error("Cannot add annotation to page without context");
|
|
25197
25051
|
let annotDict;
|
|
25198
25052
|
switch (subtype) {
|
|
25199
25053
|
case "Highlight":
|
|
@@ -25242,7 +25096,6 @@ var PDFPage = class PDFPage {
|
|
|
25242
25096
|
* ```
|
|
25243
25097
|
*/
|
|
25244
25098
|
addLinkAnnotation(options) {
|
|
25245
|
-
if (!this.ctx) throw new Error("Cannot add annotation to page without context");
|
|
25246
25099
|
const destination = options.destination;
|
|
25247
25100
|
if (destination) {
|
|
25248
25101
|
const destinationPage = destination.page;
|
|
@@ -25262,7 +25115,6 @@ var PDFPage = class PDFPage {
|
|
|
25262
25115
|
* @returns The created annotation
|
|
25263
25116
|
*/
|
|
25264
25117
|
addTextAnnotation(options) {
|
|
25265
|
-
if (!this.ctx) throw new Error("Cannot add annotation to page without context");
|
|
25266
25118
|
const annotDict = PDFTextAnnotation.create(options);
|
|
25267
25119
|
const annotRef = this.ctx.register(annotDict);
|
|
25268
25120
|
this.addAnnotationRef(annotRef);
|
|
@@ -25275,7 +25127,6 @@ var PDFPage = class PDFPage {
|
|
|
25275
25127
|
* @returns The created annotation
|
|
25276
25128
|
*/
|
|
25277
25129
|
addLineAnnotation(options) {
|
|
25278
|
-
if (!this.ctx) throw new Error("Cannot add annotation to page without context");
|
|
25279
25130
|
const annotDict = PDFLineAnnotation.create(options);
|
|
25280
25131
|
const annotRef = this.ctx.register(annotDict);
|
|
25281
25132
|
this.addAnnotationRef(annotRef);
|
|
@@ -25288,7 +25139,6 @@ var PDFPage = class PDFPage {
|
|
|
25288
25139
|
* @returns The created annotation
|
|
25289
25140
|
*/
|
|
25290
25141
|
addSquareAnnotation(options) {
|
|
25291
|
-
if (!this.ctx) throw new Error("Cannot add annotation to page without context");
|
|
25292
25142
|
const annotDict = PDFSquareAnnotation.create(options);
|
|
25293
25143
|
const annotRef = this.ctx.register(annotDict);
|
|
25294
25144
|
this.addAnnotationRef(annotRef);
|
|
@@ -25301,7 +25151,6 @@ var PDFPage = class PDFPage {
|
|
|
25301
25151
|
* @returns The created annotation
|
|
25302
25152
|
*/
|
|
25303
25153
|
addCircleAnnotation(options) {
|
|
25304
|
-
if (!this.ctx) throw new Error("Cannot add annotation to page without context");
|
|
25305
25154
|
const annotDict = PDFCircleAnnotation.create(options);
|
|
25306
25155
|
const annotRef = this.ctx.register(annotDict);
|
|
25307
25156
|
this.addAnnotationRef(annotRef);
|
|
@@ -25314,7 +25163,6 @@ var PDFPage = class PDFPage {
|
|
|
25314
25163
|
* @returns The created annotation
|
|
25315
25164
|
*/
|
|
25316
25165
|
addStampAnnotation(options) {
|
|
25317
|
-
if (!this.ctx) throw new Error("Cannot add annotation to page without context");
|
|
25318
25166
|
const annotDict = PDFStampAnnotation.create(options);
|
|
25319
25167
|
const annotRef = this.ctx.register(annotDict);
|
|
25320
25168
|
this.addAnnotationRef(annotRef);
|
|
@@ -25327,7 +25175,6 @@ var PDFPage = class PDFPage {
|
|
|
25327
25175
|
* @returns The created annotation
|
|
25328
25176
|
*/
|
|
25329
25177
|
addInkAnnotation(options) {
|
|
25330
|
-
if (!this.ctx) throw new Error("Cannot add annotation to page without context");
|
|
25331
25178
|
const annotDict = PDFInkAnnotation.create(options);
|
|
25332
25179
|
const annotRef = this.ctx.register(annotDict);
|
|
25333
25180
|
this.addAnnotationRef(annotRef);
|
|
@@ -25347,7 +25194,6 @@ var PDFPage = class PDFPage {
|
|
|
25347
25194
|
* ```
|
|
25348
25195
|
*/
|
|
25349
25196
|
removeAnnotation(annotation) {
|
|
25350
|
-
if (!this.ctx) return;
|
|
25351
25197
|
const annots = this.dict.getArray("Annots");
|
|
25352
25198
|
if (!annots) return;
|
|
25353
25199
|
const removeMatchingEntry = (predicate) => {
|
|
@@ -25409,7 +25255,6 @@ var PDFPage = class PDFPage {
|
|
|
25409
25255
|
* ```
|
|
25410
25256
|
*/
|
|
25411
25257
|
flattenAnnotations(options) {
|
|
25412
|
-
if (!this.ctx) return 0;
|
|
25413
25258
|
const count = new AnnotationFlattener(this.ctx.registry).flattenPage(this.dict, options);
|
|
25414
25259
|
this.invalidateAnnotationCache();
|
|
25415
25260
|
return count;
|
|
@@ -25501,16 +25346,24 @@ var PDFPage = class PDFPage {
|
|
|
25501
25346
|
prependContent(content) {
|
|
25502
25347
|
const existingContents = this.dict.get("Contents");
|
|
25503
25348
|
const newContent = this.createContentStream(`${content}\n`);
|
|
25504
|
-
if (!existingContents)
|
|
25505
|
-
|
|
25349
|
+
if (!existingContents) {
|
|
25350
|
+
this.dict.set("Contents", newContent);
|
|
25351
|
+
return;
|
|
25352
|
+
}
|
|
25353
|
+
if (existingContents instanceof PdfRef) {
|
|
25506
25354
|
this.dict.set("Contents", new PdfArray([newContent, existingContents]));
|
|
25507
25355
|
this._contentWrapped = true;
|
|
25508
|
-
|
|
25356
|
+
return;
|
|
25357
|
+
}
|
|
25358
|
+
if (existingContents instanceof PdfStream) {
|
|
25509
25359
|
this.dict.set("Contents", new PdfArray([newContent, existingContents]));
|
|
25510
25360
|
this._contentWrapped = true;
|
|
25511
|
-
|
|
25361
|
+
return;
|
|
25362
|
+
}
|
|
25363
|
+
if (existingContents instanceof PdfArray) {
|
|
25512
25364
|
existingContents.insert(0, newContent);
|
|
25513
25365
|
this._contentWrapped = true;
|
|
25366
|
+
return;
|
|
25514
25367
|
}
|
|
25515
25368
|
}
|
|
25516
25369
|
/** Track whether we've already wrapped the original content in q/Q */
|
|
@@ -25533,19 +25386,25 @@ var PDFPage = class PDFPage {
|
|
|
25533
25386
|
this._contentWrapped = true;
|
|
25534
25387
|
const qStream = this.createContentStream("q\n");
|
|
25535
25388
|
const QStream = this.createContentStream("\nQ");
|
|
25536
|
-
if (existingContents instanceof PdfRef)
|
|
25537
|
-
|
|
25538
|
-
|
|
25539
|
-
|
|
25540
|
-
|
|
25541
|
-
|
|
25542
|
-
|
|
25543
|
-
|
|
25544
|
-
|
|
25545
|
-
|
|
25546
|
-
|
|
25547
|
-
|
|
25548
|
-
|
|
25389
|
+
if (existingContents instanceof PdfRef) {
|
|
25390
|
+
this.dict.set("Contents", new PdfArray([
|
|
25391
|
+
qStream,
|
|
25392
|
+
existingContents,
|
|
25393
|
+
QStream,
|
|
25394
|
+
newContent
|
|
25395
|
+
]));
|
|
25396
|
+
return;
|
|
25397
|
+
}
|
|
25398
|
+
if (existingContents instanceof PdfStream) {
|
|
25399
|
+
this.dict.set("Contents", new PdfArray([
|
|
25400
|
+
qStream,
|
|
25401
|
+
existingContents,
|
|
25402
|
+
QStream,
|
|
25403
|
+
newContent
|
|
25404
|
+
]));
|
|
25405
|
+
return;
|
|
25406
|
+
}
|
|
25407
|
+
if (existingContents instanceof PdfArray) {
|
|
25549
25408
|
const newArray = new PdfArray([qStream]);
|
|
25550
25409
|
for (let i = 0; i < existingContents.length; i++) {
|
|
25551
25410
|
const item = existingContents.at(i);
|
|
@@ -25554,18 +25413,20 @@ var PDFPage = class PDFPage {
|
|
|
25554
25413
|
newArray.push(QStream);
|
|
25555
25414
|
newArray.push(newContent);
|
|
25556
25415
|
this.dict.set("Contents", newArray);
|
|
25416
|
+
return;
|
|
25557
25417
|
}
|
|
25558
|
-
} else {
|
|
25559
|
-
const contents = this.dict.get("Contents");
|
|
25560
|
-
if (contents instanceof PdfArray) contents.push(newContent);
|
|
25561
|
-
else if (contents !== void 0) this.dict.set("Contents", new PdfArray([contents, newContent]));
|
|
25562
25418
|
}
|
|
25419
|
+
if (existingContents instanceof PdfArray) {
|
|
25420
|
+
existingContents.push(newContent);
|
|
25421
|
+
return;
|
|
25422
|
+
}
|
|
25423
|
+
if (existingContents !== void 0) this.dict.set("Contents", new PdfArray([existingContents, newContent]));
|
|
25563
25424
|
}
|
|
25564
25425
|
/**
|
|
25565
25426
|
* Get a box (MediaBox, CropBox, etc.) from the page dictionary.
|
|
25566
25427
|
*/
|
|
25567
25428
|
getBox(name) {
|
|
25568
|
-
const box = this.dict.get(name);
|
|
25429
|
+
const box = this.dict.get(name, this.ctx.resolve.bind(this.ctx));
|
|
25569
25430
|
if (!(box instanceof PdfArray) || box.length < 4) return null;
|
|
25570
25431
|
const x1 = box.at(0);
|
|
25571
25432
|
const y1 = box.at(1);
|
|
@@ -25602,7 +25463,7 @@ var PDFPage = class PDFPage {
|
|
|
25602
25463
|
*/
|
|
25603
25464
|
addFontResource(font) {
|
|
25604
25465
|
const resources = this.getResources();
|
|
25605
|
-
let fonts = resources.get("Font");
|
|
25466
|
+
let fonts = resources.get("Font", this.ctx.resolve.bind(this.ctx));
|
|
25606
25467
|
if (!(fonts instanceof PdfDict)) {
|
|
25607
25468
|
fonts = new PdfDict();
|
|
25608
25469
|
resources.set("Font", fonts);
|
|
@@ -25610,7 +25471,7 @@ var PDFPage = class PDFPage {
|
|
|
25610
25471
|
if (typeof font === "string") {
|
|
25611
25472
|
if (!isStandard14Font(font)) throw new Error(`Unknown Standard 14 font: ${font}`);
|
|
25612
25473
|
for (const [existingName, value] of fonts) if (value instanceof PdfDict) {
|
|
25613
|
-
const baseFont = value.get("BaseFont");
|
|
25474
|
+
const baseFont = value.get("BaseFont", this.ctx.resolve.bind(this.ctx));
|
|
25614
25475
|
if (baseFont instanceof PdfName && baseFont.value === font) return existingName.value;
|
|
25615
25476
|
}
|
|
25616
25477
|
const fontDict = PdfDict.of({
|
|
@@ -25623,7 +25484,6 @@ var PDFPage = class PDFPage {
|
|
|
25623
25484
|
return fontName;
|
|
25624
25485
|
}
|
|
25625
25486
|
if (font instanceof EmbeddedFont) {
|
|
25626
|
-
if (!this.ctx) throw new Error("Cannot use embedded fonts without document context");
|
|
25627
25487
|
const fontRef = this.ctx.getFontRef(font);
|
|
25628
25488
|
for (const [existingName, value] of fonts) if (value instanceof PdfRef && value.objectNumber === fontRef.objectNumber && value.generation === fontRef.generation) return existingName.value;
|
|
25629
25489
|
const fontName = this.generateUniqueName(fonts, "F");
|
|
@@ -25704,21 +25564,14 @@ var PDFPage = class PDFPage {
|
|
|
25704
25564
|
* Get the concatenated content stream bytes.
|
|
25705
25565
|
*/
|
|
25706
25566
|
getContentBytes() {
|
|
25707
|
-
const contents = this.dict.get("Contents");
|
|
25567
|
+
const contents = this.dict.get("Contents", this.ctx.resolve.bind(this.ctx));
|
|
25708
25568
|
if (!contents) return new Uint8Array(0);
|
|
25709
|
-
if (contents instanceof PdfRef && this.ctx) {
|
|
25710
|
-
const stream = this.ctx.resolve(contents);
|
|
25711
|
-
if (stream instanceof PdfStream) return stream.getDecodedData();
|
|
25712
|
-
}
|
|
25713
25569
|
if (contents instanceof PdfStream) return contents.getDecodedData();
|
|
25714
25570
|
if (contents instanceof PdfArray) {
|
|
25715
25571
|
const chunks = [];
|
|
25716
25572
|
for (let i = 0; i < contents.length; i++) {
|
|
25717
|
-
const item = contents.at(i);
|
|
25718
|
-
if (item instanceof
|
|
25719
|
-
const stream = this.ctx.resolve(item);
|
|
25720
|
-
if (stream instanceof PdfStream) chunks.push(stream.getDecodedData());
|
|
25721
|
-
} else if (item instanceof PdfStream) chunks.push(item.getDecodedData());
|
|
25573
|
+
const item = contents.at(i, this.ctx.resolve.bind(this.ctx));
|
|
25574
|
+
if (item instanceof PdfStream) chunks.push(item.getDecodedData());
|
|
25722
25575
|
}
|
|
25723
25576
|
return this.concatenateChunks(chunks);
|
|
25724
25577
|
}
|
|
@@ -25747,20 +25600,13 @@ var PDFPage = class PDFPage {
|
|
|
25747
25600
|
* This method checks the page first, then walks up the Parent chain.
|
|
25748
25601
|
*/
|
|
25749
25602
|
resolveInheritedResources() {
|
|
25750
|
-
if (!this.ctx) return null;
|
|
25751
25603
|
let currentDict = this.dict;
|
|
25752
25604
|
while (currentDict) {
|
|
25753
|
-
const
|
|
25754
|
-
if (
|
|
25755
|
-
|
|
25756
|
-
|
|
25757
|
-
|
|
25758
|
-
const parentEntry = currentDict.get("Parent");
|
|
25759
|
-
if (parentEntry instanceof PdfRef) {
|
|
25760
|
-
const parent = this.ctx.resolve(parentEntry);
|
|
25761
|
-
if (parent instanceof PdfDict) currentDict = parent;
|
|
25762
|
-
else break;
|
|
25763
|
-
} else break;
|
|
25605
|
+
const resources = currentDict.get("Resources", this.ctx.resolve.bind(this.ctx));
|
|
25606
|
+
if (resources instanceof PdfDict) return resources;
|
|
25607
|
+
const parent = currentDict.get("Parent", this.ctx.resolve.bind(this.ctx));
|
|
25608
|
+
if (parent instanceof PdfDict) currentDict = parent;
|
|
25609
|
+
else break;
|
|
25764
25610
|
}
|
|
25765
25611
|
return null;
|
|
25766
25612
|
}
|
|
@@ -25770,85 +25616,22 @@ var PDFPage = class PDFPage {
|
|
|
25770
25616
|
createFontResolver() {
|
|
25771
25617
|
const resourcesDict = this.resolveInheritedResources();
|
|
25772
25618
|
if (!resourcesDict) return () => null;
|
|
25773
|
-
|
|
25774
|
-
|
|
25775
|
-
if (fontEntry instanceof PdfRef && this.ctx) {
|
|
25776
|
-
const resolved = this.ctx.resolve(fontEntry);
|
|
25777
|
-
if (resolved instanceof PdfDict) fontDict = resolved;
|
|
25778
|
-
} else if (fontEntry instanceof PdfDict) fontDict = fontEntry;
|
|
25779
|
-
if (!fontDict) return () => null;
|
|
25619
|
+
const font = resourcesDict.getDict("Font", this.ctx.resolve.bind(this.ctx));
|
|
25620
|
+
if (!font) return () => null;
|
|
25780
25621
|
const fontCache = /* @__PURE__ */ new Map();
|
|
25781
|
-
for (const [
|
|
25782
|
-
const name =
|
|
25783
|
-
|
|
25784
|
-
|
|
25785
|
-
|
|
25786
|
-
if (resolved instanceof PdfDict) fontDictEntry = resolved;
|
|
25787
|
-
} else if (fontEntry$1 instanceof PdfDict) fontDictEntry = fontEntry$1;
|
|
25788
|
-
if (!fontDictEntry) continue;
|
|
25622
|
+
for (const [key$1, entry] of font) {
|
|
25623
|
+
const name = key$1.value;
|
|
25624
|
+
const resolved = entry instanceof PdfRef ? this.ctx.resolve(entry) : entry;
|
|
25625
|
+
let entryDict = resolved instanceof PdfDict ? resolved : null;
|
|
25626
|
+
if (!entryDict) continue;
|
|
25789
25627
|
let toUnicodeMap = null;
|
|
25790
|
-
const
|
|
25791
|
-
|
|
25792
|
-
|
|
25793
|
-
|
|
25794
|
-
|
|
25795
|
-
|
|
25796
|
-
|
|
25797
|
-
if (toUnicodeStream) try {
|
|
25798
|
-
toUnicodeMap = parseToUnicode(toUnicodeStream.getDecodedData());
|
|
25799
|
-
} catch {}
|
|
25800
|
-
}
|
|
25801
|
-
const resolvedRefs = /* @__PURE__ */ new Map();
|
|
25802
|
-
const decodedStreams = /* @__PURE__ */ new Map();
|
|
25803
|
-
const preResolveValue = (value) => {
|
|
25804
|
-
if (!this.ctx) return;
|
|
25805
|
-
if (value instanceof PdfRef) {
|
|
25806
|
-
const key$1 = `${value.objectNumber} ${value.generation} R`;
|
|
25807
|
-
if (resolvedRefs.has(key$1)) return;
|
|
25808
|
-
const resolved = this.ctx.resolve(value);
|
|
25809
|
-
if (resolved instanceof PdfDict || resolved instanceof PdfArray || resolved instanceof PdfStream) {
|
|
25810
|
-
resolvedRefs.set(key$1, resolved);
|
|
25811
|
-
if (resolved instanceof PdfStream) try {
|
|
25812
|
-
const decoded = resolved.getDecodedData();
|
|
25813
|
-
decodedStreams.set(key$1, decoded);
|
|
25814
|
-
} catch {}
|
|
25815
|
-
preResolveValue(resolved);
|
|
25816
|
-
}
|
|
25817
|
-
} else if (value instanceof PdfDict) for (const [, v] of value) preResolveValue(v);
|
|
25818
|
-
else if (value instanceof PdfArray) for (let i = 0; i < value.length; i++) preResolveValue(value.at(i));
|
|
25819
|
-
};
|
|
25820
|
-
preResolveValue(fontDictEntry.get("DescendantFonts"));
|
|
25821
|
-
preResolveValue(fontDictEntry.get("FontDescriptor"));
|
|
25822
|
-
preResolveValue(fontDictEntry.get("Encoding"));
|
|
25823
|
-
preResolveValue(fontDictEntry.get("Widths"));
|
|
25824
|
-
const pdfFont = parseFont(fontDictEntry, {
|
|
25825
|
-
resolveRef: (ref) => {
|
|
25826
|
-
if (ref instanceof PdfRef && this.ctx) {
|
|
25827
|
-
const key$1 = `${ref.objectNumber} ${ref.generation} R`;
|
|
25828
|
-
const preResolved = resolvedRefs.get(key$1);
|
|
25829
|
-
if (preResolved) return preResolved;
|
|
25830
|
-
const obj = this.ctx.getObject(ref);
|
|
25831
|
-
if (obj instanceof PdfDict || obj instanceof PdfArray || obj instanceof PdfStream) return obj;
|
|
25832
|
-
}
|
|
25833
|
-
return null;
|
|
25834
|
-
},
|
|
25835
|
-
decodeStream: (stream) => {
|
|
25836
|
-
if (stream instanceof PdfRef) {
|
|
25837
|
-
const key$1 = `${stream.objectNumber} ${stream.generation} R`;
|
|
25838
|
-
const decoded = decodedStreams.get(key$1);
|
|
25839
|
-
if (decoded) return decoded;
|
|
25840
|
-
const preResolved = resolvedRefs.get(key$1);
|
|
25841
|
-
if (preResolved instanceof PdfStream) return preResolved.data;
|
|
25842
|
-
}
|
|
25843
|
-
if (stream instanceof PdfStream) {
|
|
25844
|
-
for (const [key$1, resolved] of resolvedRefs) if (resolved === stream) {
|
|
25845
|
-
const decoded = decodedStreams.get(key$1);
|
|
25846
|
-
if (decoded) return decoded;
|
|
25847
|
-
}
|
|
25848
|
-
return stream.data;
|
|
25849
|
-
}
|
|
25850
|
-
return null;
|
|
25851
|
-
},
|
|
25628
|
+
const toUnicode = entryDict.get("ToUnicode", this.ctx.resolve.bind(this.ctx));
|
|
25629
|
+
const toUnicodeStream = toUnicode instanceof PdfStream ? toUnicode : null;
|
|
25630
|
+
if (toUnicodeStream) try {
|
|
25631
|
+
toUnicodeMap = parseToUnicode(toUnicodeStream.getDecodedData());
|
|
25632
|
+
} catch {}
|
|
25633
|
+
const pdfFont = parseFont(entryDict, {
|
|
25634
|
+
resolver: this.ctx.resolve.bind(this.ctx),
|
|
25852
25635
|
toUnicodeMap
|
|
25853
25636
|
});
|
|
25854
25637
|
fontCache.set(name, pdfFont);
|
|
@@ -25949,9 +25732,9 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
|
|
|
25949
25732
|
* Get the URI if this is an external link.
|
|
25950
25733
|
*/
|
|
25951
25734
|
get uri() {
|
|
25952
|
-
const action = this.dict.getDict("A");
|
|
25735
|
+
const action = this.dict.getDict("A", this.registry.resolve.bind(this.registry));
|
|
25953
25736
|
if (action) {
|
|
25954
|
-
if (action.getName("S")?.value === "URI") return action.getString("URI")?.asString() ?? null;
|
|
25737
|
+
if (action.getName("S", this.registry.resolve.bind(this.registry))?.value === "URI") return action.getString("URI", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
25955
25738
|
}
|
|
25956
25739
|
return null;
|
|
25957
25740
|
}
|
|
@@ -25959,12 +25742,12 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
|
|
|
25959
25742
|
* Get the destination if this is an internal link.
|
|
25960
25743
|
*/
|
|
25961
25744
|
get destination() {
|
|
25962
|
-
const dest = this.dict.get("Dest");
|
|
25745
|
+
const dest = this.dict.get("Dest", this.registry.resolve.bind(this.registry));
|
|
25963
25746
|
if (dest) return this.parseDestination(dest);
|
|
25964
|
-
const action = this.dict.getDict("A");
|
|
25747
|
+
const action = this.dict.getDict("A", this.registry.resolve.bind(this.registry));
|
|
25965
25748
|
if (action) {
|
|
25966
|
-
if (action.getName("S")?.value === "GoTo") {
|
|
25967
|
-
const d = action.get("D");
|
|
25749
|
+
if (action.getName("S", this.registry.resolve.bind(this.registry))?.value === "GoTo") {
|
|
25750
|
+
const d = action.get("D", this.registry.resolve.bind(this.registry));
|
|
25968
25751
|
if (d) return this.parseDestination(d);
|
|
25969
25752
|
}
|
|
25970
25753
|
}
|
|
@@ -25984,12 +25767,12 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
|
|
|
25984
25767
|
type: "goto",
|
|
25985
25768
|
destination: dest
|
|
25986
25769
|
};
|
|
25987
|
-
const action = this.dict.getDict("A");
|
|
25770
|
+
const action = this.dict.getDict("A", this.registry.resolve.bind(this.registry));
|
|
25988
25771
|
if (action) {
|
|
25989
|
-
const actionType = action.getName("S")?.value;
|
|
25772
|
+
const actionType = action.getName("S", this.registry.resolve.bind(this.registry))?.value;
|
|
25990
25773
|
if (actionType === "GoToR") {
|
|
25991
|
-
const file = action.getString("F")?.asString() ?? "";
|
|
25992
|
-
const d = action.get("D");
|
|
25774
|
+
const file = action.getString("F", this.registry.resolve.bind(this.registry))?.asString() ?? "";
|
|
25775
|
+
const d = action.get("D", this.registry.resolve.bind(this.registry));
|
|
25993
25776
|
return {
|
|
25994
25777
|
type: "gotoRemote",
|
|
25995
25778
|
file,
|
|
@@ -26004,7 +25787,7 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
|
|
|
26004
25787
|
* Highlight mode when the link is clicked.
|
|
26005
25788
|
*/
|
|
26006
25789
|
get highlightMode() {
|
|
26007
|
-
switch (this.dict.getName("H")?.value) {
|
|
25790
|
+
switch (this.dict.getName("H", this.registry.resolve.bind(this.registry))?.value) {
|
|
26008
25791
|
case "N": return "None";
|
|
26009
25792
|
case "I": return "Invert";
|
|
26010
25793
|
case "O": return "Outline";
|
|
@@ -26193,7 +25976,7 @@ var PDFUnknownAnnotation = class extends PDFAnnotation {};
|
|
|
26193
25976
|
* @returns The appropriate annotation class instance
|
|
26194
25977
|
*/
|
|
26195
25978
|
function createAnnotation(dict, ref, registry) {
|
|
26196
|
-
const subtypeName = dict.getName("Subtype")?.value;
|
|
25979
|
+
const subtypeName = dict.getName("Subtype", registry.resolve.bind(registry))?.value;
|
|
26197
25980
|
switch (isAnnotationSubtype(subtypeName) ? subtypeName : "Text") {
|
|
26198
25981
|
case "Text": return new PDFTextAnnotation(dict, ref, registry);
|
|
26199
25982
|
case "Link": return new PDFLinkAnnotation(dict, ref, registry);
|
|
@@ -26219,14 +26002,14 @@ function createAnnotation(dict, ref, registry) {
|
|
|
26219
26002
|
/**
|
|
26220
26003
|
* Check if an annotation is a Widget (form field).
|
|
26221
26004
|
*/
|
|
26222
|
-
function isWidgetAnnotation(dict) {
|
|
26223
|
-
return dict.getName("Subtype")?.value === "Widget";
|
|
26005
|
+
function isWidgetAnnotation(dict, registry) {
|
|
26006
|
+
return dict.getName("Subtype", registry?.resolve.bind(registry))?.value === "Widget";
|
|
26224
26007
|
}
|
|
26225
26008
|
/**
|
|
26226
26009
|
* Check if an annotation is a Popup.
|
|
26227
26010
|
*/
|
|
26228
|
-
function isPopupAnnotation(dict) {
|
|
26229
|
-
return dict.getName("Subtype")?.value === "Popup";
|
|
26011
|
+
function isPopupAnnotation(dict, registry) {
|
|
26012
|
+
return dict.getName("Subtype", registry?.resolve.bind(registry))?.value === "Popup";
|
|
26230
26013
|
}
|
|
26231
26014
|
|
|
26232
26015
|
//#endregion
|
|
@@ -26274,19 +26057,14 @@ var AnnotationFlattener = class {
|
|
|
26274
26057
|
* @returns Number of annotations flattened
|
|
26275
26058
|
*/
|
|
26276
26059
|
flattenPage(pageDict, options = {}) {
|
|
26277
|
-
let
|
|
26278
|
-
if (!annotsEntry) return 0;
|
|
26279
|
-
if (annotsEntry instanceof PdfRef) annotsEntry = this.registry.resolve(annotsEntry) ?? void 0;
|
|
26280
|
-
let annots = annotsEntry instanceof PdfArray ? annotsEntry : null;
|
|
26060
|
+
let annots = pageDict.getArray("Annots", this.registry.resolve.bind(this.registry));
|
|
26281
26061
|
if (!annots || annots.length === 0) return 0;
|
|
26282
|
-
let resources = pageDict.get("Resources");
|
|
26283
|
-
if (resources instanceof PdfRef) resources = this.registry.resolve(resources) ?? void 0;
|
|
26062
|
+
let resources = pageDict.get("Resources", this.registry.resolve.bind(this.registry));
|
|
26284
26063
|
if (!(resources instanceof PdfDict)) {
|
|
26285
26064
|
resources = new PdfDict();
|
|
26286
26065
|
pageDict.set("Resources", resources);
|
|
26287
26066
|
}
|
|
26288
|
-
let xObjects = resources.get("XObject");
|
|
26289
|
-
if (xObjects instanceof PdfRef) xObjects = this.registry.resolve(xObjects) ?? void 0;
|
|
26067
|
+
let xObjects = resources.get("XObject", this.registry.resolve.bind(this.registry));
|
|
26290
26068
|
if (!(xObjects instanceof PdfDict)) {
|
|
26291
26069
|
xObjects = new PdfDict();
|
|
26292
26070
|
resources.set("XObject", xObjects);
|
|
@@ -26296,19 +26074,20 @@ var AnnotationFlattener = class {
|
|
|
26296
26074
|
let xObjectIndex = 0;
|
|
26297
26075
|
let flattenedCount = 0;
|
|
26298
26076
|
for (let i = 0; i < annots.length; i++) {
|
|
26299
|
-
|
|
26077
|
+
let entry = annots.at(i);
|
|
26300
26078
|
if (!entry) continue;
|
|
26301
26079
|
let annotDict = null;
|
|
26302
26080
|
let annotRef = null;
|
|
26303
26081
|
if (entry instanceof PdfRef) {
|
|
26304
26082
|
annotRef = entry;
|
|
26305
|
-
|
|
26306
|
-
|
|
26307
|
-
|
|
26083
|
+
entry = this.registry.resolve(entry) ?? void 0;
|
|
26084
|
+
}
|
|
26085
|
+
if (entry instanceof PdfDict) annotDict = entry;
|
|
26308
26086
|
if (!annotDict) continue;
|
|
26309
26087
|
if (isWidgetAnnotation(annotDict)) continue;
|
|
26310
26088
|
if (isPopupAnnotation(annotDict)) continue;
|
|
26311
|
-
const
|
|
26089
|
+
const subtypeName = annotDict.getName("Subtype")?.value;
|
|
26090
|
+
const subtype = isAnnotationSubtype(subtypeName) ? subtypeName : null;
|
|
26312
26091
|
if (!subtype) continue;
|
|
26313
26092
|
if (subtype === "Link") {
|
|
26314
26093
|
if (options.removeLinks) {
|
|
@@ -26417,9 +26196,7 @@ var AnnotationFlattener = class {
|
|
|
26417
26196
|
* Get annotation rectangle as [x1, y1, x2, y2].
|
|
26418
26197
|
*/
|
|
26419
26198
|
getAnnotationRect(annotDict) {
|
|
26420
|
-
|
|
26421
|
-
if (rectArray instanceof PdfRef) rectArray = this.registry.resolve(rectArray) ?? void 0;
|
|
26422
|
-
let rect = rectArray instanceof PdfArray ? rectArray : null;
|
|
26199
|
+
const rect = annotDict.getArray("Rect", this.registry.resolve.bind(this.registry));
|
|
26423
26200
|
if (!rect || rect.length < 4) return [
|
|
26424
26201
|
0,
|
|
26425
26202
|
0,
|
|
@@ -26481,7 +26258,7 @@ var AnnotationFlattener = class {
|
|
|
26481
26258
|
* Get appearance BBox, with fallback.
|
|
26482
26259
|
*/
|
|
26483
26260
|
getAppearanceBBox(appearance) {
|
|
26484
|
-
const bbox = appearance.getArray("BBox");
|
|
26261
|
+
const bbox = appearance.getArray("BBox", this.registry.resolve.bind(this.registry));
|
|
26485
26262
|
if (!bbox || bbox.length < 4) return [
|
|
26486
26263
|
0,
|
|
26487
26264
|
0,
|
|
@@ -26500,7 +26277,7 @@ var AnnotationFlattener = class {
|
|
|
26500
26277
|
* Get the appearance stream's transformation matrix.
|
|
26501
26278
|
*/
|
|
26502
26279
|
getAppearanceMatrix(appearance) {
|
|
26503
|
-
const matrixArray = appearance.getArray("Matrix");
|
|
26280
|
+
const matrixArray = appearance.getArray("Matrix", this.registry.resolve.bind(this.registry));
|
|
26504
26281
|
if (!matrixArray || matrixArray.length < 6) return Matrix.identity();
|
|
26505
26282
|
const [a, b, c, d, e, f] = matrixArray.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
|
|
26506
26283
|
return new Matrix(a ?? 0, b ?? 0, c ?? 0, d ?? 0, e ?? 0, f ?? 0);
|
|
@@ -26509,7 +26286,7 @@ var AnnotationFlattener = class {
|
|
|
26509
26286
|
* Check if appearance stream has valid dimensions.
|
|
26510
26287
|
*/
|
|
26511
26288
|
isVisibleAppearance(appearance) {
|
|
26512
|
-
const bbox = appearance.getArray("BBox");
|
|
26289
|
+
const bbox = appearance.getArray("BBox", this.registry.resolve.bind(this.registry));
|
|
26513
26290
|
if (!bbox || bbox.length < 4) return false;
|
|
26514
26291
|
const [x1, y1, x2, y2] = bbox.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
|
|
26515
26292
|
const width = Math.abs((x2 ?? 0) - (x1 ?? 0));
|
|
@@ -26525,6 +26302,8 @@ var AnnotationFlattener = class {
|
|
|
26525
26302
|
}
|
|
26526
26303
|
/**
|
|
26527
26304
|
* Wrap existing page content in q...Q and append new content.
|
|
26305
|
+
*
|
|
26306
|
+
* @todo Consider using PDFPage API for this.
|
|
26528
26307
|
*/
|
|
26529
26308
|
wrapAndAppendContent(page, newContent) {
|
|
26530
26309
|
const existing = page.get("Contents");
|
|
@@ -26573,7 +26352,8 @@ var AnnotationFlattener = class {
|
|
|
26573
26352
|
if (annotsEntry instanceof PdfRef) {
|
|
26574
26353
|
const resolved = this.registry.resolve(annotsEntry);
|
|
26575
26354
|
annots = resolved instanceof PdfArray ? resolved : void 0;
|
|
26576
|
-
}
|
|
26355
|
+
}
|
|
26356
|
+
if (annotsEntry instanceof PdfArray) annots = annotsEntry;
|
|
26577
26357
|
if (!annots) return;
|
|
26578
26358
|
const indicesToRemove = [];
|
|
26579
26359
|
for (let i = 0; i < annots.length; i++) {
|
|
@@ -27755,17 +27535,10 @@ function parseDefaultConfig(dDict, resolve) {
|
|
|
27755
27535
|
function hasLayers(ctx) {
|
|
27756
27536
|
const catalog = ctx.catalog.getDict();
|
|
27757
27537
|
if (!catalog) return false;
|
|
27758
|
-
|
|
27759
|
-
|
|
27760
|
-
let ocPropsDict = null;
|
|
27761
|
-
if (ocProperties instanceof PdfRef) ocProperties = ctx.resolve(ocProperties) ?? void 0;
|
|
27762
|
-
if (ocProperties instanceof PdfDict) ocPropsDict = ocProperties;
|
|
27538
|
+
const resolve = ctx.resolve.bind(ctx);
|
|
27539
|
+
const ocPropsDict = catalog.getDict("OCProperties", resolve);
|
|
27763
27540
|
if (!ocPropsDict) return false;
|
|
27764
|
-
|
|
27765
|
-
if (!ocgs) return false;
|
|
27766
|
-
let ocgsArray = null;
|
|
27767
|
-
if (ocgs instanceof PdfRef) ocgs = ctx.resolve(ocgs) ?? void 0;
|
|
27768
|
-
if (ocgs instanceof PdfArray) ocgsArray = ocgs;
|
|
27541
|
+
const ocgsArray = ocPropsDict.getArray("OCGs", resolve);
|
|
27769
27542
|
if (!ocgsArray || ocgsArray.length === 0) return false;
|
|
27770
27543
|
return true;
|
|
27771
27544
|
}
|
|
@@ -27778,19 +27551,12 @@ function hasLayers(ctx) {
|
|
|
27778
27551
|
function getLayers(ctx) {
|
|
27779
27552
|
const catalog = ctx.catalog.getDict();
|
|
27780
27553
|
if (!catalog) return [];
|
|
27781
|
-
|
|
27782
|
-
|
|
27783
|
-
let ocPropsDict = null;
|
|
27784
|
-
if (ocProperties instanceof PdfRef) ocProperties = ctx.resolve(ocProperties) ?? void 0;
|
|
27785
|
-
if (ocProperties instanceof PdfDict) ocPropsDict = ocProperties;
|
|
27554
|
+
const resolve = ctx.resolve.bind(ctx);
|
|
27555
|
+
const ocPropsDict = catalog.getDict("OCProperties", resolve);
|
|
27786
27556
|
if (!ocPropsDict) return [];
|
|
27787
|
-
|
|
27788
|
-
if (!ocgs) return [];
|
|
27789
|
-
let ocgsArray = null;
|
|
27790
|
-
if (ocgs instanceof PdfRef) ocgs = ctx.resolve(ocgs) ?? void 0;
|
|
27791
|
-
if (ocgs instanceof PdfArray) ocgsArray = ocgs;
|
|
27557
|
+
const ocgsArray = ocPropsDict.getArray("OCGs", resolve);
|
|
27792
27558
|
if (!ocgsArray) return [];
|
|
27793
|
-
const defaultConfig = parseDefaultConfig(ocPropsDict.get("D"),
|
|
27559
|
+
const defaultConfig = parseDefaultConfig(ocPropsDict.get("D"), resolve);
|
|
27794
27560
|
const layers = [];
|
|
27795
27561
|
for (const item of ocgsArray) {
|
|
27796
27562
|
if (!(item instanceof PdfRef)) continue;
|
|
@@ -30954,7 +30720,7 @@ var DocumentParser = class {
|
|
|
30954
30720
|
if (type?.value === "Page") {
|
|
30955
30721
|
if (currentRef) pages.push(currentRef);
|
|
30956
30722
|
} else if (type?.value === "Pages") {
|
|
30957
|
-
const kids = nodeOrRef.getArray("Kids");
|
|
30723
|
+
const kids = nodeOrRef.getArray("Kids", getObject);
|
|
30958
30724
|
if (kids) for (let i = 0; i < kids.length; i++) {
|
|
30959
30725
|
const kid = kids.at(i);
|
|
30960
30726
|
if (kid instanceof PdfRef) walkNode(kid);
|
|
@@ -31743,12 +31509,7 @@ function decodeFilename(str) {
|
|
|
31743
31509
|
* @returns The stream if found, null if external reference or missing
|
|
31744
31510
|
*/
|
|
31745
31511
|
function getEmbeddedFileStream(fileSpec, resolver) {
|
|
31746
|
-
const
|
|
31747
|
-
let ef = null;
|
|
31748
|
-
if (efEntry instanceof PdfRef) {
|
|
31749
|
-
const resolved = resolver(efEntry);
|
|
31750
|
-
if (resolved instanceof PdfDict) ef = resolved;
|
|
31751
|
-
} else if (efEntry instanceof PdfDict) ef = efEntry;
|
|
31512
|
+
const ef = fileSpec.getDict("EF", resolver);
|
|
31752
31513
|
if (!ef) return null;
|
|
31753
31514
|
const streamRef = ef.getRef("F") ?? ef.getRef("UF");
|
|
31754
31515
|
if (!streamRef) return null;
|
|
@@ -31775,12 +31536,7 @@ function parseFileSpec(fileSpec, name, resolver) {
|
|
|
31775
31536
|
if (desc) info.description = desc.asString();
|
|
31776
31537
|
const subtype = stream.getName("Subtype");
|
|
31777
31538
|
if (subtype) info.mimeType = subtype.value.replaceAll("#2F", "/").replaceAll("#20", " ");
|
|
31778
|
-
const
|
|
31779
|
-
let params = null;
|
|
31780
|
-
if (paramsEntry instanceof PdfRef) {
|
|
31781
|
-
const resolved = resolver(paramsEntry);
|
|
31782
|
-
if (resolved instanceof PdfDict) params = resolved;
|
|
31783
|
-
} else if (paramsEntry instanceof PdfDict) params = paramsEntry;
|
|
31539
|
+
const params = stream.getDict("Params", resolver);
|
|
31784
31540
|
if (params) {
|
|
31785
31541
|
const size = params.getNumber("Size");
|
|
31786
31542
|
if (size) info.size = size.value;
|
|
@@ -31838,22 +31594,6 @@ function createFileSpec(filename, embeddedFileRef, options = {}) {
|
|
|
31838
31594
|
//#endregion
|
|
31839
31595
|
//#region src/document/name-tree.ts
|
|
31840
31596
|
/**
|
|
31841
|
-
* PDF Name Tree implementation.
|
|
31842
|
-
*
|
|
31843
|
-
* Name trees are sorted key-value structures used for:
|
|
31844
|
-
* - /EmbeddedFiles (attachments)
|
|
31845
|
-
* - /Dests (named destinations)
|
|
31846
|
-
* - /JavaScript (document-level scripts)
|
|
31847
|
-
* - /AP (appearance streams)
|
|
31848
|
-
*
|
|
31849
|
-
* Structure:
|
|
31850
|
-
* - Leaf nodes have /Names: [key1, value1, key2, value2, ...]
|
|
31851
|
-
* - Intermediate nodes have /Kids: [ref1, ref2, ...]
|
|
31852
|
-
* - Intermediate nodes have /Limits: [minKey, maxKey] for binary search
|
|
31853
|
-
*
|
|
31854
|
-
* @see PDF 1.7 spec section 7.9.6
|
|
31855
|
-
*/
|
|
31856
|
-
/**
|
|
31857
31597
|
* Maximum depth for tree traversal (prevents infinite loops on malformed PDFs).
|
|
31858
31598
|
*/
|
|
31859
31599
|
const MAX_DEPTH = 10;
|
|
@@ -31907,12 +31647,7 @@ var NameTree = class {
|
|
|
31907
31647
|
let found = false;
|
|
31908
31648
|
while (lo$1 <= hi$1) {
|
|
31909
31649
|
const mid = lo$1 + hi$1 >>> 1;
|
|
31910
|
-
const
|
|
31911
|
-
if (!(kidRef instanceof PdfRef)) {
|
|
31912
|
-
lo$1 = mid + 1;
|
|
31913
|
-
continue;
|
|
31914
|
-
}
|
|
31915
|
-
const kid = this.resolver(kidRef);
|
|
31650
|
+
const kid = kids.at(mid, this.resolver);
|
|
31916
31651
|
if (!(kid instanceof PdfDict)) {
|
|
31917
31652
|
lo$1 = mid + 1;
|
|
31918
31653
|
continue;
|
|
@@ -31955,16 +31690,10 @@ var NameTree = class {
|
|
|
31955
31690
|
else if (cmp > 0) lo = mid + 1;
|
|
31956
31691
|
else {
|
|
31957
31692
|
const valueIndex = keyIndex + 1;
|
|
31958
|
-
|
|
31959
|
-
if (value instanceof PdfRef) return this.resolver(value);
|
|
31960
|
-
return value ?? null;
|
|
31693
|
+
return names.at(valueIndex, this.resolver) ?? null;
|
|
31961
31694
|
}
|
|
31962
31695
|
}
|
|
31963
|
-
for (let i = 0; i < names.length; i += 2) if (extractKey(names.at(i)) === key$1)
|
|
31964
|
-
const value = names.at(i + 1);
|
|
31965
|
-
if (value instanceof PdfRef) return this.resolver(value);
|
|
31966
|
-
return value ?? null;
|
|
31967
|
-
}
|
|
31696
|
+
for (let i = 0; i < names.length; i += 2) if (extractKey(names.at(i)) === key$1) return names.at(i + 1, this.resolver) ?? null;
|
|
31968
31697
|
return null;
|
|
31969
31698
|
}
|
|
31970
31699
|
/**
|
|
@@ -31991,15 +31720,17 @@ var NameTree = class {
|
|
|
31991
31720
|
}
|
|
31992
31721
|
if (node.has("Kids")) {
|
|
31993
31722
|
const kids = node.getArray("Kids");
|
|
31994
|
-
if (kids) for (
|
|
31995
|
-
|
|
31996
|
-
|
|
31997
|
-
|
|
31998
|
-
|
|
31999
|
-
|
|
31723
|
+
if (kids) for (let i = 0; i < kids.length; i++) {
|
|
31724
|
+
const kidRef = kids.at(i);
|
|
31725
|
+
if (kidRef instanceof PdfRef) {
|
|
31726
|
+
const refKey$1 = `${kidRef.objectNumber}:${kidRef.generation}`;
|
|
31727
|
+
if (visited.has(refKey$1)) {
|
|
31728
|
+
console.warn(`NameTree: circular reference detected at ${refKey$1}`);
|
|
31729
|
+
continue;
|
|
31730
|
+
}
|
|
31731
|
+
visited.add(refKey$1);
|
|
32000
31732
|
}
|
|
32001
|
-
|
|
32002
|
-
const kid = this.resolver(kidRef);
|
|
31733
|
+
const kid = kids.at(i, this.resolver);
|
|
32003
31734
|
if (kid instanceof PdfDict) queue.push({
|
|
32004
31735
|
node: kid,
|
|
32005
31736
|
depth: depth + 1
|
|
@@ -32010,9 +31741,8 @@ var NameTree = class {
|
|
|
32010
31741
|
if (names) for (let i = 0; i < names.length; i += 2) {
|
|
32011
31742
|
const key$1 = extractKey(names.at(i));
|
|
32012
31743
|
if (key$1 === null) continue;
|
|
32013
|
-
|
|
32014
|
-
if (value
|
|
32015
|
-
if (value !== null && value !== void 0) yield [key$1, value];
|
|
31744
|
+
const value = names.at(i + 1, this.resolver);
|
|
31745
|
+
if (value !== void 0) yield [key$1, value];
|
|
32016
31746
|
}
|
|
32017
31747
|
}
|
|
32018
31748
|
}
|
|
@@ -32279,9 +32009,7 @@ var PDFCatalog = class {
|
|
|
32279
32009
|
* Get the /Names dictionary.
|
|
32280
32010
|
*/
|
|
32281
32011
|
getNames() {
|
|
32282
|
-
|
|
32283
|
-
if (namesEntry instanceof PdfRef) namesEntry = this.registry.resolve(namesEntry) ?? void 0;
|
|
32284
|
-
return namesEntry instanceof PdfDict ? namesEntry : null;
|
|
32012
|
+
return this.dict.getDict("Names", this.registry.resolve.bind(this.registry)) ?? null;
|
|
32285
32013
|
}
|
|
32286
32014
|
/**
|
|
32287
32015
|
* Get or create the /Names dictionary.
|
|
@@ -32305,12 +32033,7 @@ var PDFCatalog = class {
|
|
|
32305
32033
|
this._embeddedFilesTree = null;
|
|
32306
32034
|
return null;
|
|
32307
32035
|
}
|
|
32308
|
-
const
|
|
32309
|
-
let embeddedFiles = null;
|
|
32310
|
-
if (embeddedFilesEntry instanceof PdfRef) {
|
|
32311
|
-
const resolved = this.registry.resolve(embeddedFilesEntry);
|
|
32312
|
-
if (resolved instanceof PdfDict) embeddedFiles = resolved;
|
|
32313
|
-
} else if (embeddedFilesEntry instanceof PdfDict) embeddedFiles = embeddedFilesEntry;
|
|
32036
|
+
const embeddedFiles = names.getDict("EmbeddedFiles", this.registry.resolve.bind(this.registry));
|
|
32314
32037
|
if (!embeddedFiles) {
|
|
32315
32038
|
this._embeddedFilesTree = null;
|
|
32316
32039
|
return null;
|
|
@@ -32406,12 +32129,6 @@ var PDFContext = class {
|
|
|
32406
32129
|
return this.registry.resolve(ref);
|
|
32407
32130
|
}
|
|
32408
32131
|
/**
|
|
32409
|
-
* Get an object by reference (sync, only if already loaded).
|
|
32410
|
-
*/
|
|
32411
|
-
getObject(ref) {
|
|
32412
|
-
return this.registry.getObject(ref);
|
|
32413
|
-
}
|
|
32414
|
-
/**
|
|
32415
32132
|
* Get the reference for an object.
|
|
32416
32133
|
*/
|
|
32417
32134
|
getRef(obj) {
|
|
@@ -35010,14 +34727,7 @@ var PDFForm = class PDFForm {
|
|
|
35010
34727
|
for (const pageRef of pageRefs) {
|
|
35011
34728
|
const pageDict = this._ctx.registry.resolve(pageRef);
|
|
35012
34729
|
if (!(pageDict instanceof PdfDict)) continue;
|
|
35013
|
-
const
|
|
35014
|
-
if (!annotsEntry) continue;
|
|
35015
|
-
let annots = null;
|
|
35016
|
-
if (annotsEntry instanceof PdfArray) annots = annotsEntry;
|
|
35017
|
-
else if (annotsEntry instanceof PdfRef) {
|
|
35018
|
-
const resolved = this._ctx.registry.resolve(annotsEntry);
|
|
35019
|
-
if (resolved instanceof PdfArray) annots = resolved;
|
|
35020
|
-
}
|
|
34730
|
+
const annots = pageDict.getArray("Annots", this._ctx.registry.resolve.bind(this._ctx.registry));
|
|
35021
34731
|
if (!annots) continue;
|
|
35022
34732
|
for (let i = annots.length - 1; i >= 0; i--) {
|
|
35023
34733
|
const item = annots.at(i);
|
|
@@ -35978,49 +35688,28 @@ var DSSBuilder = class DSSBuilder {
|
|
|
35978
35688
|
*/
|
|
35979
35689
|
static async fromCatalog(catalog, registry, options) {
|
|
35980
35690
|
const builder = new DSSBuilder(registry, options);
|
|
35981
|
-
const
|
|
35982
|
-
|
|
35983
|
-
|
|
35984
|
-
if (dssVal instanceof PdfDict) dss = dssVal;
|
|
35985
|
-
else if (dssVal instanceof PdfRef) {
|
|
35986
|
-
const resolved = registry.resolve(dssVal);
|
|
35987
|
-
if (!(resolved instanceof PdfDict)) return builder;
|
|
35988
|
-
dss = resolved;
|
|
35989
|
-
} else return builder;
|
|
35691
|
+
const resolve = registry.resolve.bind(registry);
|
|
35692
|
+
const dss = catalog.getDict("DSS", resolve);
|
|
35693
|
+
if (!dss) return builder;
|
|
35990
35694
|
await builder.loadExistingData(dss, "Certs", builder.certMap, builder.existingCertRefs);
|
|
35991
35695
|
await builder.loadExistingData(dss, "OCSPs", builder.ocspMap, builder.existingOcspRefs);
|
|
35992
35696
|
await builder.loadExistingData(dss, "CRLs", builder.crlMap, builder.existingCrlRefs);
|
|
35993
|
-
const
|
|
35994
|
-
if (
|
|
35995
|
-
|
|
35996
|
-
|
|
35997
|
-
|
|
35998
|
-
const
|
|
35999
|
-
|
|
36000
|
-
|
|
36001
|
-
|
|
36002
|
-
|
|
36003
|
-
|
|
36004
|
-
|
|
36005
|
-
|
|
36006
|
-
|
|
36007
|
-
|
|
36008
|
-
|
|
36009
|
-
if (!(resolved instanceof PdfDict)) continue;
|
|
36010
|
-
entry = resolved;
|
|
36011
|
-
} else continue;
|
|
36012
|
-
const certHashes = await builder.extractRefHashes(entry, "Cert", builder.certMap);
|
|
36013
|
-
const ocspHashes = await builder.extractRefHashes(entry, "OCSP", builder.ocspMap);
|
|
36014
|
-
const crlHashes = await builder.extractRefHashes(entry, "CRL", builder.crlMap);
|
|
36015
|
-
let timestamp;
|
|
36016
|
-
if (entry.get("TU") instanceof PdfString) timestamp = /* @__PURE__ */ new Date();
|
|
36017
|
-
builder.vriEntries.set(key$1.value.toUpperCase(), {
|
|
36018
|
-
certHashes,
|
|
36019
|
-
ocspHashes,
|
|
36020
|
-
crlHashes,
|
|
36021
|
-
timestamp
|
|
36022
|
-
});
|
|
36023
|
-
}
|
|
35697
|
+
const vri = dss.getDict("VRI", resolve);
|
|
35698
|
+
if (vri) for (const key$1 of vri.keys()) {
|
|
35699
|
+
const entryVal = vri.get(key$1, resolve);
|
|
35700
|
+
const entry = entryVal instanceof PdfDict ? entryVal : null;
|
|
35701
|
+
if (entry) {
|
|
35702
|
+
const certHashes = await builder.extractRefHashes(entry, "Cert", builder.certMap);
|
|
35703
|
+
const ocspHashes = await builder.extractRefHashes(entry, "OCSP", builder.ocspMap);
|
|
35704
|
+
const crlHashes = await builder.extractRefHashes(entry, "CRL", builder.crlMap);
|
|
35705
|
+
let timestamp;
|
|
35706
|
+
if (entry.getString("TU", resolve)) timestamp = /* @__PURE__ */ new Date();
|
|
35707
|
+
builder.vriEntries.set(key$1.value.toUpperCase(), {
|
|
35708
|
+
certHashes,
|
|
35709
|
+
ocspHashes,
|
|
35710
|
+
crlHashes,
|
|
35711
|
+
timestamp
|
|
35712
|
+
});
|
|
36024
35713
|
}
|
|
36025
35714
|
}
|
|
36026
35715
|
return builder;
|
|
@@ -36101,11 +35790,8 @@ var DSSBuilder = class DSSBuilder {
|
|
|
36101
35790
|
* Load existing data from DSS array.
|
|
36102
35791
|
*/
|
|
36103
35792
|
async loadExistingData(dss, key$1, dataMap, refMap) {
|
|
36104
|
-
|
|
36105
|
-
|
|
36106
|
-
let array;
|
|
36107
|
-
if (arrayVal instanceof PdfRef) arrayVal = this.registry.resolve(arrayVal) ?? void 0;
|
|
36108
|
-
if (arrayVal instanceof PdfArray) array = arrayVal;
|
|
35793
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
35794
|
+
const array = dss.getArray(key$1, resolve);
|
|
36109
35795
|
if (!array) return;
|
|
36110
35796
|
for (const item of array) if (item instanceof PdfRef) {
|
|
36111
35797
|
const stream = this.registry.resolve(item);
|
|
@@ -36125,10 +35811,8 @@ var DSSBuilder = class DSSBuilder {
|
|
|
36125
35811
|
*/
|
|
36126
35812
|
async extractRefHashes(entry, key$1, dataMap) {
|
|
36127
35813
|
const hashes = [];
|
|
36128
|
-
|
|
36129
|
-
|
|
36130
|
-
if (arrayVal instanceof PdfRef) arrayVal = this.registry.resolve(arrayVal) ?? void 0;
|
|
36131
|
-
const array = arrayVal instanceof PdfArray ? arrayVal : null;
|
|
35814
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
35815
|
+
const array = entry.getArray(key$1, resolve);
|
|
36132
35816
|
if (!array) return hashes;
|
|
36133
35817
|
for (const item of array) if (item instanceof PdfRef) {
|
|
36134
35818
|
const stream = this.registry.resolve(item);
|
|
@@ -38356,12 +38040,8 @@ var PDF = class PDF {
|
|
|
38356
38040
|
*/
|
|
38357
38041
|
getOrCreateViewerPreferences() {
|
|
38358
38042
|
const catalog = this.ctx.catalog.getDict();
|
|
38359
|
-
const existing = catalog.
|
|
38360
|
-
if (existing
|
|
38361
|
-
if (existing instanceof PdfRef) {
|
|
38362
|
-
const resolved = this.ctx.registry.getObject(existing);
|
|
38363
|
-
if (resolved instanceof PdfDict) return resolved;
|
|
38364
|
-
}
|
|
38043
|
+
const existing = catalog.getDict("ViewerPreferences", this.ctx.resolve.bind(this.ctx));
|
|
38044
|
+
if (existing) return existing;
|
|
38365
38045
|
const prefs = new PdfDict();
|
|
38366
38046
|
catalog.set("ViewerPreferences", prefs);
|
|
38367
38047
|
return prefs;
|
|
@@ -38412,24 +38092,9 @@ var PDF = class PDF {
|
|
|
38412
38092
|
if (!ref) return null;
|
|
38413
38093
|
const dict = this.ctx.resolve(ref);
|
|
38414
38094
|
if (!(dict instanceof PdfDict)) return null;
|
|
38415
|
-
this.ensurePageResourcesResolved(dict);
|
|
38416
38095
|
return new PDFPage(ref, dict, index, this.ctx);
|
|
38417
38096
|
}
|
|
38418
38097
|
/**
|
|
38419
|
-
* Ensure page resources are resolved (not a reference).
|
|
38420
|
-
*
|
|
38421
|
-
* Pages may have Resources as a PdfRef pointing to a shared resources dict.
|
|
38422
|
-
* The sync getResources() method on PDFPage needs the actual dict, not a ref.
|
|
38423
|
-
* This resolves the reference and replaces it in the page dict.
|
|
38424
|
-
*/
|
|
38425
|
-
ensurePageResourcesResolved(pageDict) {
|
|
38426
|
-
const resources = pageDict.get("Resources");
|
|
38427
|
-
if (resources instanceof PdfRef) {
|
|
38428
|
-
const resolved = this.ctx.resolve(resources);
|
|
38429
|
-
if (resolved instanceof PdfDict) pageDict.set("Resources", resolved.clone());
|
|
38430
|
-
}
|
|
38431
|
-
}
|
|
38432
|
-
/**
|
|
38433
38098
|
* Add a new blank page.
|
|
38434
38099
|
*
|
|
38435
38100
|
* @param options - Page size, rotation, and insertion position
|
|
@@ -38614,14 +38279,12 @@ var PDF = class PDF {
|
|
|
38614
38279
|
if (!srcPage) throw new RangeError(`Page index ${pageIndex} out of bounds`);
|
|
38615
38280
|
const contentData = this.getPageContentData(source, srcPage);
|
|
38616
38281
|
const copier = new ObjectCopier(source, this, { includeAnnotations: false });
|
|
38617
|
-
|
|
38618
|
-
let resources
|
|
38619
|
-
if (srcResources
|
|
38620
|
-
if (srcResources instanceof PdfDict) {
|
|
38282
|
+
const srcResources = srcPage.dict.getDict("Resources", source.getObject.bind(source));
|
|
38283
|
+
let resources;
|
|
38284
|
+
if (srcResources) {
|
|
38621
38285
|
const copied = await copier.copyObject(srcResources);
|
|
38622
|
-
|
|
38623
|
-
}
|
|
38624
|
-
if (!resources) resources = new PdfDict();
|
|
38286
|
+
resources = copied instanceof PdfDict ? copied : new PdfDict();
|
|
38287
|
+
} else resources = new PdfDict();
|
|
38625
38288
|
const mediaBox = srcPage.getMediaBox();
|
|
38626
38289
|
const formXObject = PdfStream.fromDict({
|
|
38627
38290
|
Type: PdfName.of("XObject"),
|
|
@@ -38641,13 +38304,9 @@ var PDF = class PDF {
|
|
|
38641
38304
|
* Get the concatenated content stream data from a page.
|
|
38642
38305
|
*/
|
|
38643
38306
|
getPageContentData(source, page) {
|
|
38644
|
-
const contents = page.dict.get("Contents");
|
|
38307
|
+
const contents = page.dict.get("Contents", source.getObject.bind(source));
|
|
38645
38308
|
if (!contents) return new Uint8Array(0);
|
|
38646
|
-
if (contents instanceof
|
|
38647
|
-
const stream = source.getObject(contents);
|
|
38648
|
-
if (stream instanceof PdfStream) return stream.getDecodedData();
|
|
38649
|
-
return new Uint8Array(0);
|
|
38650
|
-
}
|
|
38309
|
+
if (contents instanceof PdfStream) return contents.getDecodedData();
|
|
38651
38310
|
if (contents instanceof PdfArray) {
|
|
38652
38311
|
const chunks = [];
|
|
38653
38312
|
for (let i = 0; i < contents.length; i++) {
|
|
@@ -38669,7 +38328,6 @@ var PDF = class PDF {
|
|
|
38669
38328
|
}
|
|
38670
38329
|
return result;
|
|
38671
38330
|
}
|
|
38672
|
-
if (contents instanceof PdfStream) return contents.getDecodedData();
|
|
38673
38331
|
return new Uint8Array(0);
|
|
38674
38332
|
}
|
|
38675
38333
|
/**
|