@libpdf/core 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +4 -11
- package/dist/index.mjs +1189 -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.1";
|
|
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.
|
|
@@ -3484,14 +3487,14 @@ var PDFAnnotation = class {
|
|
|
3484
3487
|
* Annotation subtype (e.g., "Text", "Highlight", "Link").
|
|
3485
3488
|
*/
|
|
3486
3489
|
get type() {
|
|
3487
|
-
const subtype = this.dict.getName("Subtype")?.value;
|
|
3490
|
+
const subtype = this.dict.getName("Subtype", this.registry.resolve.bind(this.registry))?.value;
|
|
3488
3491
|
return isAnnotationSubtype(subtype) ? subtype : "Text";
|
|
3489
3492
|
}
|
|
3490
3493
|
/**
|
|
3491
3494
|
* Annotation rectangle in page coordinates.
|
|
3492
3495
|
*/
|
|
3493
3496
|
get rect() {
|
|
3494
|
-
const arr = this.dict.getArray("Rect");
|
|
3497
|
+
const arr = this.dict.getArray("Rect", this.registry.resolve.bind(this.registry));
|
|
3495
3498
|
if (!arr || arr.length < 4) return {
|
|
3496
3499
|
x: 0,
|
|
3497
3500
|
y: 0,
|
|
@@ -3510,7 +3513,7 @@ var PDFAnnotation = class {
|
|
|
3510
3513
|
* Set the annotation rectangle.
|
|
3511
3514
|
*/
|
|
3512
3515
|
setRect(rect) {
|
|
3513
|
-
const arr = this.dict.getArray("Rect");
|
|
3516
|
+
const arr = this.dict.getArray("Rect", this.registry.resolve.bind(this.registry));
|
|
3514
3517
|
if (arr && arr.length >= 4) {
|
|
3515
3518
|
arr.set(0, PdfNumber.of(rect.x));
|
|
3516
3519
|
arr.set(1, PdfNumber.of(rect.y));
|
|
@@ -3528,7 +3531,7 @@ var PDFAnnotation = class {
|
|
|
3528
3531
|
* Text content or description of the annotation.
|
|
3529
3532
|
*/
|
|
3530
3533
|
get contents() {
|
|
3531
|
-
return this.dict.getString("Contents")?.asString() ?? null;
|
|
3534
|
+
return this.dict.getString("Contents", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3532
3535
|
}
|
|
3533
3536
|
/**
|
|
3534
3537
|
* Set the annotation contents.
|
|
@@ -3541,7 +3544,7 @@ var PDFAnnotation = class {
|
|
|
3541
3544
|
* Annotation name (unique identifier within page).
|
|
3542
3545
|
*/
|
|
3543
3546
|
get name() {
|
|
3544
|
-
return this.dict.getString("NM")?.asString() ?? null;
|
|
3547
|
+
return this.dict.getString("NM", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3545
3548
|
}
|
|
3546
3549
|
/**
|
|
3547
3550
|
* Set the annotation name.
|
|
@@ -3554,7 +3557,7 @@ var PDFAnnotation = class {
|
|
|
3554
3557
|
* Modification date.
|
|
3555
3558
|
*/
|
|
3556
3559
|
get modificationDate() {
|
|
3557
|
-
return this.dict.getString("M")?.asString() ?? null;
|
|
3560
|
+
return this.dict.getString("M", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3558
3561
|
}
|
|
3559
3562
|
/**
|
|
3560
3563
|
* Set the modification date (PDF date format).
|
|
@@ -3567,7 +3570,7 @@ var PDFAnnotation = class {
|
|
|
3567
3570
|
* Annotation flags.
|
|
3568
3571
|
*/
|
|
3569
3572
|
get flags() {
|
|
3570
|
-
return this.dict.getNumber("F")?.value ?? 0;
|
|
3573
|
+
return this.dict.getNumber("F", this.registry.resolve.bind(this.registry))?.value ?? 0;
|
|
3571
3574
|
}
|
|
3572
3575
|
/**
|
|
3573
3576
|
* Check if the annotation has a specific flag set.
|
|
@@ -3613,7 +3616,7 @@ var PDFAnnotation = class {
|
|
|
3613
3616
|
* Annotation color.
|
|
3614
3617
|
*/
|
|
3615
3618
|
get color() {
|
|
3616
|
-
return parseColorArray(this.dict.getArray("C"));
|
|
3619
|
+
return parseColorArray(this.dict.getArray("C", this.registry.resolve.bind(this.registry)));
|
|
3617
3620
|
}
|
|
3618
3621
|
/**
|
|
3619
3622
|
* Set the annotation color.
|
|
@@ -3627,13 +3630,13 @@ var PDFAnnotation = class {
|
|
|
3627
3630
|
* Get the border style.
|
|
3628
3631
|
*/
|
|
3629
3632
|
getBorderStyle() {
|
|
3630
|
-
const bs = this.dict.getDict("BS");
|
|
3633
|
+
const bs = this.dict.getDict("BS", this.registry.resolve.bind(this.registry));
|
|
3631
3634
|
if (!bs) return null;
|
|
3632
3635
|
const result = {
|
|
3633
|
-
width: bs.getNumber("W")?.value ?? 1,
|
|
3634
|
-
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"
|
|
3635
3638
|
};
|
|
3636
|
-
const dashArr = bs.getArray("D");
|
|
3639
|
+
const dashArr = bs.getArray("D", this.registry.resolve.bind(this.registry));
|
|
3637
3640
|
if (dashArr) {
|
|
3638
3641
|
result.dashArray = [];
|
|
3639
3642
|
for (let i = 0; i < dashArr.length; i++) {
|
|
@@ -3658,9 +3661,8 @@ var PDFAnnotation = class {
|
|
|
3658
3661
|
* Check if the annotation has a normal appearance stream.
|
|
3659
3662
|
*/
|
|
3660
3663
|
hasNormalAppearance() {
|
|
3661
|
-
|
|
3662
|
-
if (ap
|
|
3663
|
-
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");
|
|
3664
3666
|
return false;
|
|
3665
3667
|
}
|
|
3666
3668
|
/**
|
|
@@ -3703,12 +3705,9 @@ var PDFAnnotation = class {
|
|
|
3703
3705
|
* Get an appearance stream by type.
|
|
3704
3706
|
*/
|
|
3705
3707
|
getAppearance(type) {
|
|
3706
|
-
let ap = this.dict.
|
|
3707
|
-
if (ap
|
|
3708
|
-
|
|
3709
|
-
let entry = ap.get(type);
|
|
3710
|
-
if (!entry) return null;
|
|
3711
|
-
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));
|
|
3712
3711
|
if (entry instanceof PdfStream) return entry;
|
|
3713
3712
|
return null;
|
|
3714
3713
|
}
|
|
@@ -3716,8 +3715,7 @@ var PDFAnnotation = class {
|
|
|
3716
3715
|
* Set an appearance stream by type.
|
|
3717
3716
|
*/
|
|
3718
3717
|
setAppearance(type, stream) {
|
|
3719
|
-
let ap = this.dict.
|
|
3720
|
-
if (ap instanceof PdfRef) ap = this.registry.resolve(ap) ?? void 0;
|
|
3718
|
+
let ap = this.dict.getDict("AP", this.registry.resolve.bind(this.registry));
|
|
3721
3719
|
if (ap instanceof PdfDict) {
|
|
3722
3720
|
const streamRef = this.registry.register(stream);
|
|
3723
3721
|
ap.set(type, streamRef);
|
|
@@ -3829,7 +3827,7 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
|
|
|
3829
3827
|
* Text label for the annotation (often the author name).
|
|
3830
3828
|
*/
|
|
3831
3829
|
get title() {
|
|
3832
|
-
return this.dict.getString("T")?.asString() ?? null;
|
|
3830
|
+
return this.dict.getString("T", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3833
3831
|
}
|
|
3834
3832
|
/**
|
|
3835
3833
|
* Set the title/author.
|
|
@@ -3843,7 +3841,7 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
|
|
|
3843
3841
|
* Range 0-1, where 0 is fully transparent and 1 is fully opaque.
|
|
3844
3842
|
*/
|
|
3845
3843
|
get opacity() {
|
|
3846
|
-
return this.dict.getNumber("CA")?.value ?? 1;
|
|
3844
|
+
return this.dict.getNumber("CA", this.registry.resolve.bind(this.registry))?.value ?? 1;
|
|
3847
3845
|
}
|
|
3848
3846
|
/**
|
|
3849
3847
|
* Set the opacity.
|
|
@@ -3857,7 +3855,7 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
|
|
|
3857
3855
|
* Creation date (CreationDate).
|
|
3858
3856
|
*/
|
|
3859
3857
|
get creationDate() {
|
|
3860
|
-
return this.dict.getString("CreationDate")?.asString() ?? null;
|
|
3858
|
+
return this.dict.getString("CreationDate", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3861
3859
|
}
|
|
3862
3860
|
/**
|
|
3863
3861
|
* Set the creation date.
|
|
@@ -3870,7 +3868,7 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
|
|
|
3870
3868
|
* Subject - the subject of the annotation.
|
|
3871
3869
|
*/
|
|
3872
3870
|
get subject() {
|
|
3873
|
-
return this.dict.getString("Subj")?.asString() ?? null;
|
|
3871
|
+
return this.dict.getString("Subj", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
3874
3872
|
}
|
|
3875
3873
|
/**
|
|
3876
3874
|
* Set the subject.
|
|
@@ -3935,7 +3933,7 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
|
|
|
3935
3933
|
* Intent (IT) - the intent of the markup annotation.
|
|
3936
3934
|
*/
|
|
3937
3935
|
get intent() {
|
|
3938
|
-
return this.dict.getName("IT")?.value ?? null;
|
|
3936
|
+
return this.dict.getName("IT", this.registry.resolve.bind(this.registry))?.value ?? null;
|
|
3939
3937
|
}
|
|
3940
3938
|
};
|
|
3941
3939
|
|
|
@@ -3958,7 +3956,7 @@ var PDFCaretAnnotation = class extends PDFMarkupAnnotation {
|
|
|
3958
3956
|
* "P" = paragraph symbol, "None" = no symbol.
|
|
3959
3957
|
*/
|
|
3960
3958
|
get symbol() {
|
|
3961
|
-
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";
|
|
3962
3960
|
return "None";
|
|
3963
3961
|
}
|
|
3964
3962
|
/**
|
|
@@ -3980,7 +3978,7 @@ var PDFFileAttachmentAnnotation = class extends PDFMarkupAnnotation {
|
|
|
3980
3978
|
* Icon to display.
|
|
3981
3979
|
*/
|
|
3982
3980
|
get icon() {
|
|
3983
|
-
const name = this.dict.getName("Name");
|
|
3981
|
+
const name = this.dict.getName("Name", this.registry.resolve.bind(this.registry));
|
|
3984
3982
|
if (!name) return "PushPin";
|
|
3985
3983
|
if (isFileAttachmentIcon(name.value)) return name.value;
|
|
3986
3984
|
return "PushPin";
|
|
@@ -4003,11 +4001,7 @@ var PDFFileAttachmentAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4003
4001
|
* Get the file specification dictionary.
|
|
4004
4002
|
*/
|
|
4005
4003
|
getFileSpec() {
|
|
4006
|
-
|
|
4007
|
-
if (!fsRef) return this.dict.getDict("FS") ?? null;
|
|
4008
|
-
const resolved = this.registry.resolve(fsRef);
|
|
4009
|
-
if (resolved && resolved.type === "dict") return resolved;
|
|
4010
|
-
return null;
|
|
4004
|
+
return this.dict.getDict("FS", this.registry.resolve.bind(this.registry)) ?? null;
|
|
4011
4005
|
}
|
|
4012
4006
|
/**
|
|
4013
4007
|
* Get the file name from the file specification.
|
|
@@ -4015,9 +4009,9 @@ var PDFFileAttachmentAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4015
4009
|
getFileName() {
|
|
4016
4010
|
const fs = this.getFileSpec();
|
|
4017
4011
|
if (!fs) return null;
|
|
4018
|
-
const uf = fs.getString("UF");
|
|
4012
|
+
const uf = fs.getString("UF", this.registry.resolve.bind(this.registry));
|
|
4019
4013
|
if (uf) return uf.asString();
|
|
4020
|
-
const f = fs.getString("F");
|
|
4014
|
+
const f = fs.getString("F", this.registry.resolve.bind(this.registry));
|
|
4021
4015
|
if (f) return f.asString();
|
|
4022
4016
|
return null;
|
|
4023
4017
|
}
|
|
@@ -4042,7 +4036,7 @@ var PDFFreeTextAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4042
4036
|
* Contains font and color operators.
|
|
4043
4037
|
*/
|
|
4044
4038
|
get defaultAppearance() {
|
|
4045
|
-
return this.dict.getString("DA")?.asString() ?? null;
|
|
4039
|
+
return this.dict.getString("DA", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
4046
4040
|
}
|
|
4047
4041
|
/**
|
|
4048
4042
|
* Set the default appearance.
|
|
@@ -4055,7 +4049,7 @@ var PDFFreeTextAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4055
4049
|
* Text justification: 0=left, 1=center, 2=right.
|
|
4056
4050
|
*/
|
|
4057
4051
|
get justification() {
|
|
4058
|
-
switch (this.dict.getNumber("Q")?.value ?? 0) {
|
|
4052
|
+
switch (this.dict.getNumber("Q", this.registry.resolve.bind(this.registry))?.value ?? 0) {
|
|
4059
4053
|
case 1: return "center";
|
|
4060
4054
|
case 2: return "right";
|
|
4061
4055
|
default: return "left";
|
|
@@ -4076,7 +4070,7 @@ var PDFFreeTextAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4076
4070
|
* Contains CSS-style formatting.
|
|
4077
4071
|
*/
|
|
4078
4072
|
get defaultStyle() {
|
|
4079
|
-
return this.dict.getString("DS")?.asString() ?? null;
|
|
4073
|
+
return this.dict.getString("DS", this.registry.resolve.bind(this.registry))?.asString() ?? null;
|
|
4080
4074
|
}
|
|
4081
4075
|
/**
|
|
4082
4076
|
* Set the default style.
|
|
@@ -4090,7 +4084,7 @@ var PDFFreeTextAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4090
4084
|
* Can be "FreeText", "FreeTextCallout", or "FreeTextTypeWriter".
|
|
4091
4085
|
*/
|
|
4092
4086
|
get freeTextIntent() {
|
|
4093
|
-
return this.dict.getName("IT")?.value ?? null;
|
|
4087
|
+
return this.dict.getName("IT", this.registry.resolve.bind(this.registry))?.value ?? null;
|
|
4094
4088
|
}
|
|
4095
4089
|
/**
|
|
4096
4090
|
* Set the intent.
|
|
@@ -4167,7 +4161,7 @@ var PDFInkAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4167
4161
|
* Each path is an array of points.
|
|
4168
4162
|
*/
|
|
4169
4163
|
get inkPaths() {
|
|
4170
|
-
const inkList = this.dict.getArray("InkList");
|
|
4164
|
+
const inkList = this.dict.getArray("InkList", this.registry.resolve.bind(this.registry));
|
|
4171
4165
|
if (!inkList) return [];
|
|
4172
4166
|
const paths = [];
|
|
4173
4167
|
for (let i = 0; i < inkList.length; i++) {
|
|
@@ -4272,7 +4266,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4272
4266
|
* Get the line endpoints.
|
|
4273
4267
|
*/
|
|
4274
4268
|
get lineEndpoints() {
|
|
4275
|
-
const l = this.dict.getArray("L");
|
|
4269
|
+
const l = this.dict.getArray("L", this.registry.resolve.bind(this.registry));
|
|
4276
4270
|
if (!l || l.length < 4) return {
|
|
4277
4271
|
start: {
|
|
4278
4272
|
x: 0,
|
|
@@ -4299,7 +4293,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4299
4293
|
* Set the line endpoints.
|
|
4300
4294
|
*/
|
|
4301
4295
|
setLineEndpoints(start, end) {
|
|
4302
|
-
const arr = this.dict.getArray("L");
|
|
4296
|
+
const arr = this.dict.getArray("L", this.registry.resolve.bind(this.registry));
|
|
4303
4297
|
if (arr && arr.length >= 4) {
|
|
4304
4298
|
arr.set(0, PdfNumber.of(start.x));
|
|
4305
4299
|
arr.set(1, PdfNumber.of(start.y));
|
|
@@ -4329,7 +4323,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4329
4323
|
* Line ending styles [start, end].
|
|
4330
4324
|
*/
|
|
4331
4325
|
get lineEndingStyles() {
|
|
4332
|
-
const le = this.dict.getArray("LE");
|
|
4326
|
+
const le = this.dict.getArray("LE", this.registry.resolve.bind(this.registry));
|
|
4333
4327
|
if (!le || le.length < 2) return ["None", "None"];
|
|
4334
4328
|
const [startStyle, endStyle] = le.toArray().map((item) => item instanceof PdfName ? item.value : "None");
|
|
4335
4329
|
return [startStyle ?? "None", endStyle ?? "None"];
|
|
@@ -4345,7 +4339,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4345
4339
|
* Interior color (fill color for closed arrow heads).
|
|
4346
4340
|
*/
|
|
4347
4341
|
get interiorColor() {
|
|
4348
|
-
return parseColorArray(this.dict.getArray("IC"));
|
|
4342
|
+
return parseColorArray(this.dict.getArray("IC", this.registry.resolve.bind(this.registry)));
|
|
4349
4343
|
}
|
|
4350
4344
|
/**
|
|
4351
4345
|
* Set the interior color.
|
|
@@ -4359,19 +4353,19 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
|
|
|
4359
4353
|
* Line leader length (for dimension lines).
|
|
4360
4354
|
*/
|
|
4361
4355
|
get leaderLength() {
|
|
4362
|
-
return this.dict.getNumber("LL")?.value ?? 0;
|
|
4356
|
+
return this.dict.getNumber("LL", this.registry.resolve.bind(this.registry))?.value ?? 0;
|
|
4363
4357
|
}
|
|
4364
4358
|
/**
|
|
4365
4359
|
* Line leader line extension.
|
|
4366
4360
|
*/
|
|
4367
4361
|
get leaderExtension() {
|
|
4368
|
-
return this.dict.getNumber("LLE")?.value ?? 0;
|
|
4362
|
+
return this.dict.getNumber("LLE", this.registry.resolve.bind(this.registry))?.value ?? 0;
|
|
4369
4363
|
}
|
|
4370
4364
|
/**
|
|
4371
4365
|
* Caption flag - whether to show caption with the line.
|
|
4372
4366
|
*/
|
|
4373
4367
|
get hasCaption() {
|
|
4374
|
-
return this.dict.getBool("Cap")?.value ?? false;
|
|
4368
|
+
return this.dict.getBool("Cap", this.registry.resolve.bind(this.registry))?.value ?? false;
|
|
4375
4369
|
}
|
|
4376
4370
|
/**
|
|
4377
4371
|
* Line width from border style.
|
|
@@ -4878,240 +4872,6 @@ function rectsToQuadPoints(rects) {
|
|
|
4878
4872
|
return rects.map(rectToQuadPoints);
|
|
4879
4873
|
}
|
|
4880
4874
|
|
|
4881
|
-
//#endregion
|
|
4882
|
-
//#region src/helpers/unicode.ts
|
|
4883
|
-
/**
|
|
4884
|
-
* Unicode utilities for PDF text handling.
|
|
4885
|
-
*
|
|
4886
|
-
* Provides mappings between Unicode code points and PostScript glyph names.
|
|
4887
|
-
*/
|
|
4888
|
-
/**
|
|
4889
|
-
* Map Unicode code point to PostScript glyph name.
|
|
4890
|
-
* Returns undefined if no mapping exists.
|
|
4891
|
-
*/
|
|
4892
|
-
function unicodeToGlyphName(unicode) {
|
|
4893
|
-
return UNICODE_TO_GLYPH.get(unicode);
|
|
4894
|
-
}
|
|
4895
|
-
/**
|
|
4896
|
-
* Common Unicode to glyph name mappings.
|
|
4897
|
-
* Covers ASCII and common Latin-1 extended characters.
|
|
4898
|
-
*
|
|
4899
|
-
* For a complete mapping, see the Adobe Glyph List:
|
|
4900
|
-
* https://github.com/adobe-type-tools/agl-aglfn
|
|
4901
|
-
*/
|
|
4902
|
-
const UNICODE_TO_GLYPH = new Map([
|
|
4903
|
-
[32, "space"],
|
|
4904
|
-
[33, "exclam"],
|
|
4905
|
-
[34, "quotedbl"],
|
|
4906
|
-
[35, "numbersign"],
|
|
4907
|
-
[36, "dollar"],
|
|
4908
|
-
[37, "percent"],
|
|
4909
|
-
[38, "ampersand"],
|
|
4910
|
-
[39, "quotesingle"],
|
|
4911
|
-
[40, "parenleft"],
|
|
4912
|
-
[41, "parenright"],
|
|
4913
|
-
[42, "asterisk"],
|
|
4914
|
-
[43, "plus"],
|
|
4915
|
-
[44, "comma"],
|
|
4916
|
-
[45, "hyphen"],
|
|
4917
|
-
[46, "period"],
|
|
4918
|
-
[47, "slash"],
|
|
4919
|
-
[48, "zero"],
|
|
4920
|
-
[49, "one"],
|
|
4921
|
-
[50, "two"],
|
|
4922
|
-
[51, "three"],
|
|
4923
|
-
[52, "four"],
|
|
4924
|
-
[53, "five"],
|
|
4925
|
-
[54, "six"],
|
|
4926
|
-
[55, "seven"],
|
|
4927
|
-
[56, "eight"],
|
|
4928
|
-
[57, "nine"],
|
|
4929
|
-
[58, "colon"],
|
|
4930
|
-
[59, "semicolon"],
|
|
4931
|
-
[60, "less"],
|
|
4932
|
-
[61, "equal"],
|
|
4933
|
-
[62, "greater"],
|
|
4934
|
-
[63, "question"],
|
|
4935
|
-
[64, "at"],
|
|
4936
|
-
[65, "A"],
|
|
4937
|
-
[66, "B"],
|
|
4938
|
-
[67, "C"],
|
|
4939
|
-
[68, "D"],
|
|
4940
|
-
[69, "E"],
|
|
4941
|
-
[70, "F"],
|
|
4942
|
-
[71, "G"],
|
|
4943
|
-
[72, "H"],
|
|
4944
|
-
[73, "I"],
|
|
4945
|
-
[74, "J"],
|
|
4946
|
-
[75, "K"],
|
|
4947
|
-
[76, "L"],
|
|
4948
|
-
[77, "M"],
|
|
4949
|
-
[78, "N"],
|
|
4950
|
-
[79, "O"],
|
|
4951
|
-
[80, "P"],
|
|
4952
|
-
[81, "Q"],
|
|
4953
|
-
[82, "R"],
|
|
4954
|
-
[83, "S"],
|
|
4955
|
-
[84, "T"],
|
|
4956
|
-
[85, "U"],
|
|
4957
|
-
[86, "V"],
|
|
4958
|
-
[87, "W"],
|
|
4959
|
-
[88, "X"],
|
|
4960
|
-
[89, "Y"],
|
|
4961
|
-
[90, "Z"],
|
|
4962
|
-
[91, "bracketleft"],
|
|
4963
|
-
[92, "backslash"],
|
|
4964
|
-
[93, "bracketright"],
|
|
4965
|
-
[94, "asciicircum"],
|
|
4966
|
-
[95, "underscore"],
|
|
4967
|
-
[96, "grave"],
|
|
4968
|
-
[97, "a"],
|
|
4969
|
-
[98, "b"],
|
|
4970
|
-
[99, "c"],
|
|
4971
|
-
[100, "d"],
|
|
4972
|
-
[101, "e"],
|
|
4973
|
-
[102, "f"],
|
|
4974
|
-
[103, "g"],
|
|
4975
|
-
[104, "h"],
|
|
4976
|
-
[105, "i"],
|
|
4977
|
-
[106, "j"],
|
|
4978
|
-
[107, "k"],
|
|
4979
|
-
[108, "l"],
|
|
4980
|
-
[109, "m"],
|
|
4981
|
-
[110, "n"],
|
|
4982
|
-
[111, "o"],
|
|
4983
|
-
[112, "p"],
|
|
4984
|
-
[113, "q"],
|
|
4985
|
-
[114, "r"],
|
|
4986
|
-
[115, "s"],
|
|
4987
|
-
[116, "t"],
|
|
4988
|
-
[117, "u"],
|
|
4989
|
-
[118, "v"],
|
|
4990
|
-
[119, "w"],
|
|
4991
|
-
[120, "x"],
|
|
4992
|
-
[121, "y"],
|
|
4993
|
-
[122, "z"],
|
|
4994
|
-
[123, "braceleft"],
|
|
4995
|
-
[124, "bar"],
|
|
4996
|
-
[125, "braceright"],
|
|
4997
|
-
[126, "asciitilde"],
|
|
4998
|
-
[160, "nbspace"],
|
|
4999
|
-
[161, "exclamdown"],
|
|
5000
|
-
[162, "cent"],
|
|
5001
|
-
[163, "sterling"],
|
|
5002
|
-
[164, "currency"],
|
|
5003
|
-
[165, "yen"],
|
|
5004
|
-
[166, "brokenbar"],
|
|
5005
|
-
[167, "section"],
|
|
5006
|
-
[168, "dieresis"],
|
|
5007
|
-
[169, "copyright"],
|
|
5008
|
-
[170, "ordfeminine"],
|
|
5009
|
-
[171, "guillemotleft"],
|
|
5010
|
-
[172, "logicalnot"],
|
|
5011
|
-
[173, "softhyphen"],
|
|
5012
|
-
[174, "registered"],
|
|
5013
|
-
[175, "macron"],
|
|
5014
|
-
[176, "degree"],
|
|
5015
|
-
[177, "plusminus"],
|
|
5016
|
-
[178, "twosuperior"],
|
|
5017
|
-
[179, "threesuperior"],
|
|
5018
|
-
[180, "acute"],
|
|
5019
|
-
[181, "mu"],
|
|
5020
|
-
[182, "paragraph"],
|
|
5021
|
-
[183, "periodcentered"],
|
|
5022
|
-
[184, "cedilla"],
|
|
5023
|
-
[185, "onesuperior"],
|
|
5024
|
-
[186, "ordmasculine"],
|
|
5025
|
-
[187, "guillemotright"],
|
|
5026
|
-
[188, "onequarter"],
|
|
5027
|
-
[189, "onehalf"],
|
|
5028
|
-
[190, "threequarters"],
|
|
5029
|
-
[191, "questiondown"],
|
|
5030
|
-
[192, "Agrave"],
|
|
5031
|
-
[193, "Aacute"],
|
|
5032
|
-
[194, "Acircumflex"],
|
|
5033
|
-
[195, "Atilde"],
|
|
5034
|
-
[196, "Adieresis"],
|
|
5035
|
-
[197, "Aring"],
|
|
5036
|
-
[198, "AE"],
|
|
5037
|
-
[199, "Ccedilla"],
|
|
5038
|
-
[200, "Egrave"],
|
|
5039
|
-
[201, "Eacute"],
|
|
5040
|
-
[202, "Ecircumflex"],
|
|
5041
|
-
[203, "Edieresis"],
|
|
5042
|
-
[204, "Igrave"],
|
|
5043
|
-
[205, "Iacute"],
|
|
5044
|
-
[206, "Icircumflex"],
|
|
5045
|
-
[207, "Idieresis"],
|
|
5046
|
-
[208, "Eth"],
|
|
5047
|
-
[209, "Ntilde"],
|
|
5048
|
-
[210, "Ograve"],
|
|
5049
|
-
[211, "Oacute"],
|
|
5050
|
-
[212, "Ocircumflex"],
|
|
5051
|
-
[213, "Otilde"],
|
|
5052
|
-
[214, "Odieresis"],
|
|
5053
|
-
[215, "multiply"],
|
|
5054
|
-
[216, "Oslash"],
|
|
5055
|
-
[217, "Ugrave"],
|
|
5056
|
-
[218, "Uacute"],
|
|
5057
|
-
[219, "Ucircumflex"],
|
|
5058
|
-
[220, "Udieresis"],
|
|
5059
|
-
[221, "Yacute"],
|
|
5060
|
-
[222, "Thorn"],
|
|
5061
|
-
[223, "germandbls"],
|
|
5062
|
-
[224, "agrave"],
|
|
5063
|
-
[225, "aacute"],
|
|
5064
|
-
[226, "acircumflex"],
|
|
5065
|
-
[227, "atilde"],
|
|
5066
|
-
[228, "adieresis"],
|
|
5067
|
-
[229, "aring"],
|
|
5068
|
-
[230, "ae"],
|
|
5069
|
-
[231, "ccedilla"],
|
|
5070
|
-
[232, "egrave"],
|
|
5071
|
-
[233, "eacute"],
|
|
5072
|
-
[234, "ecircumflex"],
|
|
5073
|
-
[235, "edieresis"],
|
|
5074
|
-
[236, "igrave"],
|
|
5075
|
-
[237, "iacute"],
|
|
5076
|
-
[238, "icircumflex"],
|
|
5077
|
-
[239, "idieresis"],
|
|
5078
|
-
[240, "eth"],
|
|
5079
|
-
[241, "ntilde"],
|
|
5080
|
-
[242, "ograve"],
|
|
5081
|
-
[243, "oacute"],
|
|
5082
|
-
[244, "ocircumflex"],
|
|
5083
|
-
[245, "otilde"],
|
|
5084
|
-
[246, "odieresis"],
|
|
5085
|
-
[247, "divide"],
|
|
5086
|
-
[248, "oslash"],
|
|
5087
|
-
[249, "ugrave"],
|
|
5088
|
-
[250, "uacute"],
|
|
5089
|
-
[251, "ucircumflex"],
|
|
5090
|
-
[252, "udieresis"],
|
|
5091
|
-
[253, "yacute"],
|
|
5092
|
-
[254, "thorn"],
|
|
5093
|
-
[255, "ydieresis"],
|
|
5094
|
-
[8211, "endash"],
|
|
5095
|
-
[8212, "emdash"],
|
|
5096
|
-
[8216, "quoteleft"],
|
|
5097
|
-
[8217, "quoteright"],
|
|
5098
|
-
[8218, "quotesinglbase"],
|
|
5099
|
-
[8220, "quotedblleft"],
|
|
5100
|
-
[8221, "quotedblright"],
|
|
5101
|
-
[8222, "quotedblbase"],
|
|
5102
|
-
[8224, "dagger"],
|
|
5103
|
-
[8225, "daggerdbl"],
|
|
5104
|
-
[8226, "bullet"],
|
|
5105
|
-
[8230, "ellipsis"],
|
|
5106
|
-
[8240, "perthousand"],
|
|
5107
|
-
[8249, "guilsinglleft"],
|
|
5108
|
-
[8250, "guilsinglright"],
|
|
5109
|
-
[8364, "Euro"],
|
|
5110
|
-
[8482, "trademark"],
|
|
5111
|
-
[64257, "fi"],
|
|
5112
|
-
[64258, "fl"]
|
|
5113
|
-
]);
|
|
5114
|
-
|
|
5115
4875
|
//#endregion
|
|
5116
4876
|
//#region src/io/scanner.ts
|
|
5117
4877
|
/**
|
|
@@ -10961,9 +10721,9 @@ function parseEmbeddedProgram(descriptor, options) {
|
|
|
10961
10721
|
* Try to parse a TrueType font from /FontFile2.
|
|
10962
10722
|
*/
|
|
10963
10723
|
function tryParseFontFile2(descriptor, options) {
|
|
10964
|
-
const fontFile2 =
|
|
10965
|
-
if (!fontFile2) return null;
|
|
10966
|
-
const data =
|
|
10724
|
+
const fontFile2 = descriptor.get("FontFile2", options.resolver);
|
|
10725
|
+
if (!(fontFile2 instanceof PdfStream)) return null;
|
|
10726
|
+
const data = fontFile2.getDecodedData();
|
|
10967
10727
|
if (!data || data.length === 0) return null;
|
|
10968
10728
|
try {
|
|
10969
10729
|
return new TrueTypeFontProgram(parseTTF(data, { isEmbedded: true }), data);
|
|
@@ -10976,10 +10736,10 @@ function tryParseFontFile2(descriptor, options) {
|
|
|
10976
10736
|
* Try to parse a CFF or OpenType font from /FontFile3.
|
|
10977
10737
|
*/
|
|
10978
10738
|
function tryParseFontFile3(descriptor, options) {
|
|
10979
|
-
const fontFile3 =
|
|
10980
|
-
if (!fontFile3) return null;
|
|
10739
|
+
const fontFile3 = descriptor.get("FontFile3", options.resolver);
|
|
10740
|
+
if (!(fontFile3 instanceof PdfStream)) return null;
|
|
10981
10741
|
const subtype = getStreamSubtype(fontFile3);
|
|
10982
|
-
const data =
|
|
10742
|
+
const data = fontFile3.getDecodedData();
|
|
10983
10743
|
if (!data || data.length === 0) return null;
|
|
10984
10744
|
try {
|
|
10985
10745
|
if (subtype === "OpenType") return new TrueTypeFontProgram(parseTTF(data, { isEmbedded: true }), data);
|
|
@@ -11000,9 +10760,9 @@ function tryParseFontFile3(descriptor, options) {
|
|
|
11000
10760
|
* Try to parse a Type1 font from /FontFile.
|
|
11001
10761
|
*/
|
|
11002
10762
|
function tryParseFontFile(descriptor, options) {
|
|
11003
|
-
const fontFile =
|
|
11004
|
-
if (!fontFile) return null;
|
|
11005
|
-
const data =
|
|
10763
|
+
const fontFile = descriptor.get("FontFile", options.resolver);
|
|
10764
|
+
if (!(fontFile instanceof PdfStream)) return null;
|
|
10765
|
+
const data = fontFile.getDecodedData();
|
|
11006
10766
|
if (!data || data.length === 0) return null;
|
|
11007
10767
|
try {
|
|
11008
10768
|
return new Type1FontProgram(parsePfb(data), data);
|
|
@@ -11035,15 +10795,7 @@ function tryAutoDetectFontFile3(data) {
|
|
|
11035
10795
|
* Get the /Subtype from a stream dictionary.
|
|
11036
10796
|
*/
|
|
11037
10797
|
function getStreamSubtype(stream) {
|
|
11038
|
-
if (stream
|
|
11039
|
-
}
|
|
11040
|
-
/**
|
|
11041
|
-
* Resolve a value through indirect references.
|
|
11042
|
-
*/
|
|
11043
|
-
function resolveValue(value, options) {
|
|
11044
|
-
if (!value) return null;
|
|
11045
|
-
if (options.resolveRef && value instanceof PdfRef) return options.resolveRef(value);
|
|
11046
|
-
return value;
|
|
10798
|
+
if (stream) return stream.getName("Subtype")?.value;
|
|
11047
10799
|
}
|
|
11048
10800
|
/**
|
|
11049
10801
|
* Parse a font program directly from bytes.
|
|
@@ -11078,119 +10830,838 @@ function parseFontProgram(data) {
|
|
|
11078
10830
|
}
|
|
11079
10831
|
|
|
11080
10832
|
//#endregion
|
|
11081
|
-
//#region src/fonts/
|
|
10833
|
+
//#region src/fonts/font-descriptor.ts
|
|
11082
10834
|
/**
|
|
11083
|
-
*
|
|
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.
|
|
11084
10977
|
*
|
|
11085
|
-
*
|
|
11086
|
-
*
|
|
11087
|
-
*
|
|
10978
|
+
* Usage:
|
|
10979
|
+
* ```typescript
|
|
10980
|
+
* const fontBytes = await fs.readFile("NotoSans-Regular.ttf");
|
|
10981
|
+
* const font = EmbeddedFont.fromBytes(fontBytes);
|
|
11088
10982
|
*
|
|
11089
|
-
*
|
|
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
|
+
* ```
|
|
11090
10989
|
*/
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11096
|
-
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11100
|
-
|
|
11101
|
-
|
|
11102
|
-
|
|
11103
|
-
|
|
11104
|
-
|
|
11105
|
-
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11121
|
-
|
|
11122
|
-
|
|
11123
|
-
|
|
11124
|
-
|
|
11125
|
-
|
|
11126
|
-
|
|
11127
|
-
|
|
11128
|
-
|
|
11129
|
-
|
|
11130
|
-
|
|
11131
|
-
|
|
11132
|
-
|
|
11133
|
-
|
|
11134
|
-
|
|
11135
|
-
|
|
11136
|
-
|
|
11137
|
-
|
|
11138
|
-
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
|
|
11142
|
-
|
|
11143
|
-
|
|
11144
|
-
|
|
11145
|
-
|
|
11146
|
-
|
|
11147
|
-
|
|
11148
|
-
|
|
11149
|
-
|
|
11150
|
-
|
|
11151
|
-
|
|
11152
|
-
|
|
11153
|
-
|
|
11154
|
-
|
|
11155
|
-
|
|
11156
|
-
|
|
11157
|
-
|
|
11158
|
-
|
|
11159
|
-
|
|
11160
|
-
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
|
|
11164
|
-
|
|
11165
|
-
|
|
11166
|
-
|
|
11167
|
-
|
|
11168
|
-
|
|
11169
|
-
|
|
11170
|
-
|
|
11171
|
-
|
|
11172
|
-
|
|
11173
|
-
|
|
11174
|
-
|
|
11175
|
-
|
|
11176
|
-
|
|
11177
|
-
|
|
11178
|
-
|
|
11179
|
-
|
|
11180
|
-
|
|
11181
|
-
|
|
11182
|
-
|
|
11183
|
-
|
|
11184
|
-
|
|
11185
|
-
|
|
11186
|
-
|
|
11187
|
-
|
|
11188
|
-
|
|
11189
|
-
|
|
11190
|
-
|
|
11191
|
-
|
|
11192
|
-
|
|
11193
|
-
|
|
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
|
+
|
|
11551
|
+
//#endregion
|
|
11552
|
+
//#region src/fonts/encodings/glyph-list.ts
|
|
11553
|
+
/**
|
|
11554
|
+
* Glyph name to Unicode mapping.
|
|
11555
|
+
*
|
|
11556
|
+
* This is a subset of the Adobe Glyph List (AGL) covering the glyphs
|
|
11557
|
+
* used in standard PDF encodings. For the full list, see:
|
|
11558
|
+
* https://github.com/adobe-type-tools/agl-aglfn
|
|
11559
|
+
*
|
|
11560
|
+
* Reference: pdf.js glyphlist.js
|
|
11561
|
+
*/
|
|
11562
|
+
const GLYPH_TO_UNICODE = {
|
|
11563
|
+
space: 32,
|
|
11564
|
+
exclam: 33,
|
|
11565
|
+
quotedbl: 34,
|
|
11566
|
+
numbersign: 35,
|
|
11567
|
+
dollar: 36,
|
|
11568
|
+
percent: 37,
|
|
11569
|
+
ampersand: 38,
|
|
11570
|
+
quotesingle: 39,
|
|
11571
|
+
parenleft: 40,
|
|
11572
|
+
parenright: 41,
|
|
11573
|
+
asterisk: 42,
|
|
11574
|
+
plus: 43,
|
|
11575
|
+
comma: 44,
|
|
11576
|
+
hyphen: 45,
|
|
11577
|
+
period: 46,
|
|
11578
|
+
slash: 47,
|
|
11579
|
+
zero: 48,
|
|
11580
|
+
one: 49,
|
|
11581
|
+
two: 50,
|
|
11582
|
+
three: 51,
|
|
11583
|
+
four: 52,
|
|
11584
|
+
five: 53,
|
|
11585
|
+
six: 54,
|
|
11586
|
+
seven: 55,
|
|
11587
|
+
eight: 56,
|
|
11588
|
+
nine: 57,
|
|
11589
|
+
colon: 58,
|
|
11590
|
+
semicolon: 59,
|
|
11591
|
+
less: 60,
|
|
11592
|
+
equal: 61,
|
|
11593
|
+
greater: 62,
|
|
11594
|
+
question: 63,
|
|
11595
|
+
at: 64,
|
|
11596
|
+
A: 65,
|
|
11597
|
+
B: 66,
|
|
11598
|
+
C: 67,
|
|
11599
|
+
D: 68,
|
|
11600
|
+
E: 69,
|
|
11601
|
+
F: 70,
|
|
11602
|
+
G: 71,
|
|
11603
|
+
H: 72,
|
|
11604
|
+
I: 73,
|
|
11605
|
+
J: 74,
|
|
11606
|
+
K: 75,
|
|
11607
|
+
L: 76,
|
|
11608
|
+
M: 77,
|
|
11609
|
+
N: 78,
|
|
11610
|
+
O: 79,
|
|
11611
|
+
P: 80,
|
|
11612
|
+
Q: 81,
|
|
11613
|
+
R: 82,
|
|
11614
|
+
S: 83,
|
|
11615
|
+
T: 84,
|
|
11616
|
+
U: 85,
|
|
11617
|
+
V: 86,
|
|
11618
|
+
W: 87,
|
|
11619
|
+
X: 88,
|
|
11620
|
+
Y: 89,
|
|
11621
|
+
Z: 90,
|
|
11622
|
+
bracketleft: 91,
|
|
11623
|
+
backslash: 92,
|
|
11624
|
+
bracketright: 93,
|
|
11625
|
+
asciicircum: 94,
|
|
11626
|
+
underscore: 95,
|
|
11627
|
+
grave: 96,
|
|
11628
|
+
a: 97,
|
|
11629
|
+
b: 98,
|
|
11630
|
+
c: 99,
|
|
11631
|
+
d: 100,
|
|
11632
|
+
e: 101,
|
|
11633
|
+
f: 102,
|
|
11634
|
+
g: 103,
|
|
11635
|
+
h: 104,
|
|
11636
|
+
i: 105,
|
|
11637
|
+
j: 106,
|
|
11638
|
+
k: 107,
|
|
11639
|
+
l: 108,
|
|
11640
|
+
m: 109,
|
|
11641
|
+
n: 110,
|
|
11642
|
+
o: 111,
|
|
11643
|
+
p: 112,
|
|
11644
|
+
q: 113,
|
|
11645
|
+
r: 114,
|
|
11646
|
+
s: 115,
|
|
11647
|
+
t: 116,
|
|
11648
|
+
u: 117,
|
|
11649
|
+
v: 118,
|
|
11650
|
+
w: 119,
|
|
11651
|
+
x: 120,
|
|
11652
|
+
y: 121,
|
|
11653
|
+
z: 122,
|
|
11654
|
+
braceleft: 123,
|
|
11655
|
+
bar: 124,
|
|
11656
|
+
braceright: 125,
|
|
11657
|
+
asciitilde: 126,
|
|
11658
|
+
exclamdown: 161,
|
|
11659
|
+
cent: 162,
|
|
11660
|
+
sterling: 163,
|
|
11661
|
+
currency: 164,
|
|
11662
|
+
yen: 165,
|
|
11663
|
+
brokenbar: 166,
|
|
11664
|
+
section: 167,
|
|
11194
11665
|
dieresis: 168,
|
|
11195
11666
|
copyright: 169,
|
|
11196
11667
|
ordfeminine: 170,
|
|
@@ -13316,147 +13787,6 @@ var ZapfDingbatsEncoding = class ZapfDingbatsEncoding extends SimpleEncoding {
|
|
|
13316
13787
|
}
|
|
13317
13788
|
};
|
|
13318
13789
|
|
|
13319
|
-
//#endregion
|
|
13320
|
-
//#region src/fonts/font-descriptor.ts
|
|
13321
|
-
/**
|
|
13322
|
-
* Font flags as defined in PDF spec Table 123.
|
|
13323
|
-
*/
|
|
13324
|
-
const FontFlags = {
|
|
13325
|
-
FIXED_PITCH: 1,
|
|
13326
|
-
SERIF: 2,
|
|
13327
|
-
SYMBOLIC: 4,
|
|
13328
|
-
SCRIPT: 8,
|
|
13329
|
-
NONSYMBOLIC: 32,
|
|
13330
|
-
ITALIC: 64,
|
|
13331
|
-
ALL_CAP: 65536,
|
|
13332
|
-
SMALL_CAP: 1 << 17,
|
|
13333
|
-
FORCE_BOLD: 1 << 18
|
|
13334
|
-
};
|
|
13335
|
-
/**
|
|
13336
|
-
* FontDescriptor contains font metrics and flags.
|
|
13337
|
-
*/
|
|
13338
|
-
var FontDescriptor = class FontDescriptor {
|
|
13339
|
-
fontName;
|
|
13340
|
-
flags;
|
|
13341
|
-
fontBBox;
|
|
13342
|
-
italicAngle;
|
|
13343
|
-
ascent;
|
|
13344
|
-
descent;
|
|
13345
|
-
leading;
|
|
13346
|
-
capHeight;
|
|
13347
|
-
xHeight;
|
|
13348
|
-
stemV;
|
|
13349
|
-
stemH;
|
|
13350
|
-
avgWidth;
|
|
13351
|
-
maxWidth;
|
|
13352
|
-
missingWidth;
|
|
13353
|
-
constructor(data) {
|
|
13354
|
-
this.fontName = data.fontName;
|
|
13355
|
-
this.flags = data.flags;
|
|
13356
|
-
this.fontBBox = data.fontBBox;
|
|
13357
|
-
this.italicAngle = data.italicAngle;
|
|
13358
|
-
this.ascent = data.ascent;
|
|
13359
|
-
this.descent = data.descent;
|
|
13360
|
-
this.leading = data.leading;
|
|
13361
|
-
this.capHeight = data.capHeight;
|
|
13362
|
-
this.xHeight = data.xHeight;
|
|
13363
|
-
this.stemV = data.stemV;
|
|
13364
|
-
this.stemH = data.stemH;
|
|
13365
|
-
this.avgWidth = data.avgWidth;
|
|
13366
|
-
this.maxWidth = data.maxWidth;
|
|
13367
|
-
this.missingWidth = data.missingWidth;
|
|
13368
|
-
}
|
|
13369
|
-
/** Check if font is fixed-pitch (monospace) */
|
|
13370
|
-
get isFixedPitch() {
|
|
13371
|
-
return (this.flags & FontFlags.FIXED_PITCH) !== 0;
|
|
13372
|
-
}
|
|
13373
|
-
/** Check if font is serif */
|
|
13374
|
-
get isSerif() {
|
|
13375
|
-
return (this.flags & FontFlags.SERIF) !== 0;
|
|
13376
|
-
}
|
|
13377
|
-
/** Check if font is symbolic (uses custom encoding) */
|
|
13378
|
-
get isSymbolic() {
|
|
13379
|
-
return (this.flags & FontFlags.SYMBOLIC) !== 0;
|
|
13380
|
-
}
|
|
13381
|
-
/** Check if font is script (cursive) */
|
|
13382
|
-
get isScript() {
|
|
13383
|
-
return (this.flags & FontFlags.SCRIPT) !== 0;
|
|
13384
|
-
}
|
|
13385
|
-
/** Check if font is non-symbolic (uses standard encoding) */
|
|
13386
|
-
get isNonSymbolic() {
|
|
13387
|
-
return (this.flags & FontFlags.NONSYMBOLIC) !== 0;
|
|
13388
|
-
}
|
|
13389
|
-
/** Check if font is italic */
|
|
13390
|
-
get isItalic() {
|
|
13391
|
-
return (this.flags & FontFlags.ITALIC) !== 0;
|
|
13392
|
-
}
|
|
13393
|
-
/** Check if font is all caps */
|
|
13394
|
-
get isAllCap() {
|
|
13395
|
-
return (this.flags & FontFlags.ALL_CAP) !== 0;
|
|
13396
|
-
}
|
|
13397
|
-
/** Check if font is small caps */
|
|
13398
|
-
get isSmallCap() {
|
|
13399
|
-
return (this.flags & FontFlags.SMALL_CAP) !== 0;
|
|
13400
|
-
}
|
|
13401
|
-
/** Check if font should be bold */
|
|
13402
|
-
get isForceBold() {
|
|
13403
|
-
return (this.flags & FontFlags.FORCE_BOLD) !== 0;
|
|
13404
|
-
}
|
|
13405
|
-
/**
|
|
13406
|
-
* Parse FontDescriptor from a PDF dictionary.
|
|
13407
|
-
*/
|
|
13408
|
-
static parse(dict) {
|
|
13409
|
-
const bboxArray = dict.getArray("FontBBox");
|
|
13410
|
-
const fontBBox = [
|
|
13411
|
-
0,
|
|
13412
|
-
0,
|
|
13413
|
-
0,
|
|
13414
|
-
0
|
|
13415
|
-
];
|
|
13416
|
-
if (bboxArray && bboxArray.length >= 4) for (let i = 0; i < 4; i++) {
|
|
13417
|
-
const item = bboxArray.at(i);
|
|
13418
|
-
if (item && item.type === "number") fontBBox[i] = item.value;
|
|
13419
|
-
}
|
|
13420
|
-
return new FontDescriptor({
|
|
13421
|
-
fontName: dict.getName("FontName")?.value ?? "",
|
|
13422
|
-
flags: dict.getNumber("Flags")?.value ?? 0,
|
|
13423
|
-
fontBBox,
|
|
13424
|
-
italicAngle: dict.getNumber("ItalicAngle")?.value ?? 0,
|
|
13425
|
-
ascent: dict.getNumber("Ascent")?.value ?? 0,
|
|
13426
|
-
descent: dict.getNumber("Descent")?.value ?? 0,
|
|
13427
|
-
leading: dict.getNumber("Leading")?.value ?? 0,
|
|
13428
|
-
capHeight: dict.getNumber("CapHeight")?.value ?? 0,
|
|
13429
|
-
xHeight: dict.getNumber("XHeight")?.value ?? 0,
|
|
13430
|
-
stemV: dict.getNumber("StemV")?.value ?? 0,
|
|
13431
|
-
stemH: dict.getNumber("StemH")?.value ?? 0,
|
|
13432
|
-
avgWidth: dict.getNumber("AvgWidth")?.value ?? 0,
|
|
13433
|
-
maxWidth: dict.getNumber("MaxWidth")?.value ?? 0,
|
|
13434
|
-
missingWidth: dict.getNumber("MissingWidth")?.value ?? 0
|
|
13435
|
-
});
|
|
13436
|
-
}
|
|
13437
|
-
};
|
|
13438
|
-
|
|
13439
|
-
//#endregion
|
|
13440
|
-
//#region src/fonts/pdf-font.ts
|
|
13441
|
-
/**
|
|
13442
|
-
* Abstract base class for PDF fonts.
|
|
13443
|
-
*/
|
|
13444
|
-
var PdfFont = class {
|
|
13445
|
-
/**
|
|
13446
|
-
* Get width of text in points at a given font size.
|
|
13447
|
-
*
|
|
13448
|
-
* @param text - Unicode text to measure
|
|
13449
|
-
* @param fontSize - Font size in points
|
|
13450
|
-
* @returns Width in points
|
|
13451
|
-
*/
|
|
13452
|
-
getTextWidth(text, fontSize) {
|
|
13453
|
-
let totalWidth = 0;
|
|
13454
|
-
const codes = this.encodeText(text);
|
|
13455
|
-
for (const code of codes) totalWidth += this.getWidth(code);
|
|
13456
|
-
return totalWidth * fontSize / 1e3;
|
|
13457
|
-
}
|
|
13458
|
-
};
|
|
13459
|
-
|
|
13460
13790
|
//#endregion
|
|
13461
13791
|
//#region src/fonts/standard-14.ts
|
|
13462
13792
|
/**
|
|
@@ -16695,25 +17025,6 @@ const FONT_GLYPH_WIDTHS = {
|
|
|
16695
17025
|
|
|
16696
17026
|
//#endregion
|
|
16697
17027
|
//#region src/fonts/simple-font.ts
|
|
16698
|
-
/**
|
|
16699
|
-
* SimpleFont - Base class for single-byte encoded fonts.
|
|
16700
|
-
*
|
|
16701
|
-
* This handles TrueType, Type1, and Type3 fonts which use single-byte
|
|
16702
|
-
* character codes (0-255).
|
|
16703
|
-
*
|
|
16704
|
-
* Font structure:
|
|
16705
|
-
* <<
|
|
16706
|
-
* /Type /Font
|
|
16707
|
-
* /Subtype /TrueType (or /Type1, /Type3)
|
|
16708
|
-
* /BaseFont /Helvetica
|
|
16709
|
-
* /FirstChar 32
|
|
16710
|
-
* /LastChar 255
|
|
16711
|
-
* /Widths [278 278 355 ...]
|
|
16712
|
-
* /Encoding /WinAnsiEncoding (or dict with /Differences)
|
|
16713
|
-
* /FontDescriptor 10 0 R
|
|
16714
|
-
* /ToUnicode 11 0 R
|
|
16715
|
-
* >>
|
|
16716
|
-
*/
|
|
16717
17028
|
const isSimpleFontSubtype = (subtype) => {
|
|
16718
17029
|
return subtype === "TrueType" || subtype === "Type1" || subtype === "Type3" || subtype === "MMType1";
|
|
16719
17030
|
};
|
|
@@ -16850,34 +17161,25 @@ var SimpleFont = class extends PdfFont {
|
|
|
16850
17161
|
* Parse a SimpleFont from a PDF font dictionary.
|
|
16851
17162
|
*/
|
|
16852
17163
|
function parseSimpleFont(dict, options = {}) {
|
|
16853
|
-
const subtypeName = dict.getName("Subtype");
|
|
17164
|
+
const subtypeName = dict.getName("Subtype", options.resolver);
|
|
16854
17165
|
const subtype = isSimpleFontSubtype(subtypeName?.value) ? subtypeName.value : "TrueType";
|
|
16855
|
-
const baseFontName = dict.getName("BaseFont")?.value ?? "Unknown";
|
|
16856
|
-
const firstChar = dict.getNumber("FirstChar")?.value ?? 0;
|
|
16857
|
-
const lastChar = dict.getNumber("LastChar")?.value ?? 255;
|
|
16858
|
-
let
|
|
16859
|
-
let widthsArray = null;
|
|
16860
|
-
if (w instanceof PdfRef && options.resolveRef) w = options.resolveRef(w) ?? void 0;
|
|
16861
|
-
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);
|
|
16862
17170
|
const widths = [];
|
|
16863
17171
|
if (widthsArray) for (let i = 0; i < widthsArray.length; i++) {
|
|
16864
|
-
const item = widthsArray.at(i);
|
|
17172
|
+
const item = widthsArray.at(i, options.resolver);
|
|
16865
17173
|
if (item instanceof PdfNumber) widths.push(item.value);
|
|
16866
17174
|
else widths.push(0);
|
|
16867
17175
|
}
|
|
16868
|
-
const encoding = parseEncoding(dict, options.
|
|
17176
|
+
const encoding = parseEncoding(dict, options.resolver);
|
|
16869
17177
|
let descriptor = null;
|
|
16870
17178
|
let embeddedProgram = null;
|
|
16871
|
-
const
|
|
16872
|
-
if (
|
|
16873
|
-
|
|
16874
|
-
|
|
16875
|
-
descriptor = FontDescriptor.parse(descriptorDict);
|
|
16876
|
-
if (options.decodeStream) embeddedProgram = parseEmbeddedProgram(descriptorDict, {
|
|
16877
|
-
decodeStream: options.decodeStream,
|
|
16878
|
-
resolveRef: options.resolveRef
|
|
16879
|
-
});
|
|
16880
|
-
}
|
|
17179
|
+
const fontDescriptor = dict.getDict("FontDescriptor", options.resolver);
|
|
17180
|
+
if (fontDescriptor) {
|
|
17181
|
+
descriptor = FontDescriptor.parse(fontDescriptor);
|
|
17182
|
+
embeddedProgram = parseEmbeddedProgram(fontDescriptor, { resolver: options.resolver });
|
|
16881
17183
|
}
|
|
16882
17184
|
return new SimpleFont({
|
|
16883
17185
|
subtype,
|
|
@@ -16894,36 +17196,31 @@ function parseSimpleFont(dict, options = {}) {
|
|
|
16894
17196
|
/**
|
|
16895
17197
|
* Parse encoding from font dictionary.
|
|
16896
17198
|
*/
|
|
16897
|
-
function parseEncoding(dict,
|
|
16898
|
-
const encodingValue = dict.get("Encoding");
|
|
17199
|
+
function parseEncoding(dict, resolver) {
|
|
17200
|
+
const encodingValue = dict.get("Encoding", resolver);
|
|
16899
17201
|
if (!encodingValue) {
|
|
16900
|
-
const baseFontName = dict.getName("BaseFont")?.value ?? "";
|
|
17202
|
+
const baseFontName = dict.getName("BaseFont", resolver)?.value ?? "";
|
|
16901
17203
|
if (baseFontName === "Symbol") return SymbolEncoding.instance;
|
|
16902
17204
|
if (baseFontName === "ZapfDingbats") return ZapfDingbatsEncoding.instance;
|
|
16903
17205
|
return StandardEncoding.instance;
|
|
16904
17206
|
}
|
|
16905
|
-
if (encodingValue
|
|
16906
|
-
if (encodingValue
|
|
16907
|
-
if (encodingValue.type === "ref" && resolveRef) {
|
|
16908
|
-
const resolved = resolveRef(encodingValue);
|
|
16909
|
-
if (resolved && resolved.type === "dict") return parseEncodingDict(resolved);
|
|
16910
|
-
}
|
|
17207
|
+
if (encodingValue instanceof PdfName) return getEncodingByName(encodingValue.value);
|
|
17208
|
+
if (encodingValue instanceof PdfDict) return parseEncodingDict(encodingValue, resolver);
|
|
16911
17209
|
return WinAnsiEncoding.instance;
|
|
16912
17210
|
}
|
|
16913
17211
|
/**
|
|
16914
17212
|
* Parse encoding dictionary.
|
|
16915
17213
|
*/
|
|
16916
|
-
function parseEncodingDict(dict) {
|
|
16917
|
-
const baseEncodingName = dict.getName("BaseEncoding");
|
|
17214
|
+
function parseEncodingDict(dict, resolver) {
|
|
17215
|
+
const baseEncodingName = dict.getName("BaseEncoding", resolver);
|
|
16918
17216
|
const baseEncoding = baseEncodingName ? getEncodingByName(baseEncodingName.value) : WinAnsiEncoding.instance;
|
|
16919
|
-
const differencesArray = dict.getArray("Differences");
|
|
17217
|
+
const differencesArray = dict.getArray("Differences", resolver);
|
|
16920
17218
|
if (!differencesArray || differencesArray.length === 0) return baseEncoding;
|
|
16921
17219
|
const items = [];
|
|
16922
17220
|
for (let i = 0; i < differencesArray.length; i++) {
|
|
16923
17221
|
const item = differencesArray.at(i);
|
|
16924
17222
|
if (item) {
|
|
16925
|
-
if (item
|
|
16926
|
-
else if (item.type === "name") items.push(item.value);
|
|
17223
|
+
if (item instanceof PdfNumber || item instanceof PdfName) items.push(item.value);
|
|
16927
17224
|
}
|
|
16928
17225
|
}
|
|
16929
17226
|
return new DifferencesEncoding(baseEncoding, DifferencesEncoding.parseDifferencesArray(items));
|
|
@@ -16945,6 +17242,15 @@ function getEncodingByName(name) {
|
|
|
16945
17242
|
//#endregion
|
|
16946
17243
|
//#region src/document/forms/form-font.ts
|
|
16947
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
|
+
/**
|
|
16948
17254
|
* Existing font from PDF's default resources.
|
|
16949
17255
|
*
|
|
16950
17256
|
* This is a lightweight wrapper for fonts already present in the PDF,
|
|
@@ -17068,18 +17374,11 @@ function mapToStandardFont(name) {
|
|
|
17068
17374
|
function parseExistingFont(name, fontObj, registry) {
|
|
17069
17375
|
let ref = null;
|
|
17070
17376
|
let simpleFont = null;
|
|
17071
|
-
if (fontObj
|
|
17377
|
+
if (fontObj instanceof PdfRef) {
|
|
17072
17378
|
ref = fontObj;
|
|
17073
17379
|
const resolved = registry.getObject(fontObj);
|
|
17074
|
-
if (resolved
|
|
17075
|
-
|
|
17076
|
-
if (r instanceof PdfRef) {
|
|
17077
|
-
const obj = registry.getObject(r);
|
|
17078
|
-
if (obj instanceof PdfDict || obj instanceof PdfArray || obj instanceof PdfStream) return obj;
|
|
17079
|
-
}
|
|
17080
|
-
return null;
|
|
17081
|
-
};
|
|
17082
|
-
simpleFont = parseSimpleFont(resolved, { resolveRef });
|
|
17380
|
+
if (resolved instanceof PdfDict) try {
|
|
17381
|
+
simpleFont = parseSimpleFont(resolved, { resolver: registry.resolve.bind(registry) });
|
|
17083
17382
|
} catch (err) {
|
|
17084
17383
|
console.warn(err);
|
|
17085
17384
|
}
|
|
@@ -17090,7 +17389,7 @@ function parseExistingFont(name, fontObj, registry) {
|
|
|
17090
17389
|
* Check if a font is an EmbeddedFont.
|
|
17091
17390
|
*/
|
|
17092
17391
|
function isEmbeddedFont(font) {
|
|
17093
|
-
return
|
|
17392
|
+
return font instanceof EmbeddedFont;
|
|
17094
17393
|
}
|
|
17095
17394
|
/**
|
|
17096
17395
|
* Check if a font is an ExistingFont.
|
|
@@ -18348,11 +18647,11 @@ var WidgetAnnotation = class {
|
|
|
18348
18647
|
getOnValue() {
|
|
18349
18648
|
const ap = this.dict.getDict("AP");
|
|
18350
18649
|
if (!ap) return null;
|
|
18351
|
-
const
|
|
18650
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18651
|
+
const n = ap.get("N", resolve);
|
|
18352
18652
|
if (!n) return null;
|
|
18353
|
-
|
|
18354
|
-
|
|
18355
|
-
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;
|
|
18356
18655
|
}
|
|
18357
18656
|
return null;
|
|
18358
18657
|
}
|
|
@@ -18365,11 +18664,11 @@ var WidgetAnnotation = class {
|
|
|
18365
18664
|
hasAppearancesForStates(states) {
|
|
18366
18665
|
const ap = this.dict.getDict("AP");
|
|
18367
18666
|
if (!ap) return false;
|
|
18368
|
-
const
|
|
18667
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18668
|
+
const n = ap.get("N", resolve);
|
|
18369
18669
|
if (!n) return false;
|
|
18370
|
-
|
|
18371
|
-
|
|
18372
|
-
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;
|
|
18373
18672
|
return true;
|
|
18374
18673
|
}
|
|
18375
18674
|
return states.length === 0;
|
|
@@ -18390,15 +18689,13 @@ var WidgetAnnotation = class {
|
|
|
18390
18689
|
getNormalAppearance(state) {
|
|
18391
18690
|
const ap = this.dict.getDict("AP");
|
|
18392
18691
|
if (!ap) return null;
|
|
18393
|
-
|
|
18692
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18693
|
+
const n = ap.get("N", resolve);
|
|
18394
18694
|
if (!n) return null;
|
|
18395
|
-
if (n instanceof PdfRef) n = this.registry.resolve(n) ?? void 0;
|
|
18396
18695
|
if (n instanceof PdfStream) return n;
|
|
18397
18696
|
if (n instanceof PdfDict) {
|
|
18398
18697
|
const stateKey = state ?? this.appearanceState ?? "Off";
|
|
18399
|
-
|
|
18400
|
-
if (!stateEntry) return null;
|
|
18401
|
-
if (stateEntry instanceof PdfRef) stateEntry = this.registry.resolve(stateEntry) ?? void 0;
|
|
18698
|
+
const stateEntry = n.get(stateKey, resolve);
|
|
18402
18699
|
if (stateEntry instanceof PdfStream) return stateEntry;
|
|
18403
18700
|
return null;
|
|
18404
18701
|
}
|
|
@@ -18410,15 +18707,13 @@ var WidgetAnnotation = class {
|
|
|
18410
18707
|
getRolloverAppearance(state) {
|
|
18411
18708
|
const ap = this.dict.getDict("AP");
|
|
18412
18709
|
if (!ap) return null;
|
|
18413
|
-
|
|
18710
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18711
|
+
const r = ap.get("R", resolve);
|
|
18414
18712
|
if (!r) return null;
|
|
18415
|
-
if (r instanceof PdfRef) r = this.registry.resolve(r) ?? void 0;
|
|
18416
18713
|
if (r instanceof PdfStream) return r;
|
|
18417
18714
|
if (r instanceof PdfDict) {
|
|
18418
18715
|
const stateKey = state ?? this.appearanceState ?? "Off";
|
|
18419
|
-
|
|
18420
|
-
if (!stateEntry) return null;
|
|
18421
|
-
if (stateEntry instanceof PdfRef) stateEntry = this.registry.resolve(stateEntry) ?? void 0;
|
|
18716
|
+
const stateEntry = r.get(stateKey, resolve);
|
|
18422
18717
|
if (stateEntry instanceof PdfStream) return stateEntry;
|
|
18423
18718
|
return null;
|
|
18424
18719
|
}
|
|
@@ -18430,15 +18725,13 @@ var WidgetAnnotation = class {
|
|
|
18430
18725
|
getDownAppearance(state) {
|
|
18431
18726
|
const ap = this.dict.getDict("AP");
|
|
18432
18727
|
if (!ap) return null;
|
|
18433
|
-
|
|
18728
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18729
|
+
const d = ap.get("D", resolve);
|
|
18434
18730
|
if (!d) return null;
|
|
18435
|
-
if (d instanceof PdfRef) d = this.registry.resolve(d) ?? void 0;
|
|
18436
18731
|
if (d instanceof PdfStream) return d;
|
|
18437
18732
|
if (d instanceof PdfDict) {
|
|
18438
18733
|
const stateKey = state ?? this.appearanceState ?? "Off";
|
|
18439
|
-
|
|
18440
|
-
if (!stateEntry) return null;
|
|
18441
|
-
if (stateEntry instanceof PdfRef) stateEntry = this.registry.resolve(stateEntry) ?? void 0;
|
|
18734
|
+
const stateEntry = d.get(stateKey, resolve);
|
|
18442
18735
|
if (stateEntry instanceof PdfStream) return stateEntry;
|
|
18443
18736
|
return null;
|
|
18444
18737
|
}
|
|
@@ -18468,14 +18761,8 @@ var WidgetAnnotation = class {
|
|
|
18468
18761
|
* Get appearance characteristics (/MK dictionary).
|
|
18469
18762
|
*/
|
|
18470
18763
|
getAppearanceCharacteristics() {
|
|
18471
|
-
const
|
|
18472
|
-
|
|
18473
|
-
let mk = null;
|
|
18474
|
-
if (mkEntry instanceof PdfDict) mk = mkEntry;
|
|
18475
|
-
else if (mkEntry.type === "ref") {
|
|
18476
|
-
const resolved = this.registry.getObject(mkEntry);
|
|
18477
|
-
if (resolved instanceof PdfDict) mk = resolved;
|
|
18478
|
-
}
|
|
18764
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
18765
|
+
const mk = this.dict.getDict("MK", resolve);
|
|
18479
18766
|
if (!mk) return null;
|
|
18480
18767
|
return {
|
|
18481
18768
|
rotation: mk.getNumber("R")?.value ?? 0,
|
|
@@ -18614,11 +18901,8 @@ var FormField = class {
|
|
|
18614
18901
|
while (current) {
|
|
18615
18902
|
if (visited.has(current)) break;
|
|
18616
18903
|
visited.add(current);
|
|
18617
|
-
const value = current.get(key$1);
|
|
18618
|
-
if (value !== void 0)
|
|
18619
|
-
if (value instanceof PdfRef) return this.registry.getObject(value);
|
|
18620
|
-
return value;
|
|
18621
|
-
}
|
|
18904
|
+
const value = current.get(key$1, this.registry.resolve.bind(this.registry));
|
|
18905
|
+
if (value !== void 0) return value;
|
|
18622
18906
|
const parentRef = current.getRef("Parent");
|
|
18623
18907
|
if (!parentRef) break;
|
|
18624
18908
|
const obj = this.registry.getObject(parentRef);
|
|
@@ -18859,8 +19143,7 @@ var TerminalField = class extends FormField {
|
|
|
18859
19143
|
* This ensures getAppearanceCharacteristics() can work synchronously.
|
|
18860
19144
|
*/
|
|
18861
19145
|
resolveMK(dict) {
|
|
18862
|
-
|
|
18863
|
-
if (mkEntry instanceof PdfRef) this.registry.resolve(mkEntry);
|
|
19146
|
+
dict.getDict("MK", this.registry.resolve.bind(this.registry));
|
|
18864
19147
|
}
|
|
18865
19148
|
/**
|
|
18866
19149
|
* Add a widget to this field's /Kids array.
|
|
@@ -19210,12 +19493,6 @@ var ListBoxField = class extends TerminalField {
|
|
|
19210
19493
|
//#endregion
|
|
19211
19494
|
//#region src/document/forms/fields/other-fields.ts
|
|
19212
19495
|
/**
|
|
19213
|
-
* Other field types: Signature, Button, and Unknown.
|
|
19214
|
-
*
|
|
19215
|
-
* PDF Reference: Section 12.7.4.5 "Signature Fields"
|
|
19216
|
-
* PDF Reference: Section 12.7.4.2 "Button Fields"
|
|
19217
|
-
*/
|
|
19218
|
-
/**
|
|
19219
19496
|
* Signature field.
|
|
19220
19497
|
*/
|
|
19221
19498
|
var SignatureField = class extends TerminalField {
|
|
@@ -19230,13 +19507,7 @@ var SignatureField = class extends TerminalField {
|
|
|
19230
19507
|
* Get signature dictionary (if signed).
|
|
19231
19508
|
*/
|
|
19232
19509
|
getSignatureDict() {
|
|
19233
|
-
|
|
19234
|
-
if (!v) return null;
|
|
19235
|
-
if (v instanceof PdfRef) {
|
|
19236
|
-
const resolved = this.registry.getObject(v);
|
|
19237
|
-
return resolved instanceof PdfDict ? resolved : null;
|
|
19238
|
-
}
|
|
19239
|
-
return v instanceof PdfDict ? v : null;
|
|
19510
|
+
return this.dict.getDict("V", this.registry.resolve.bind(this.registry)) ?? null;
|
|
19240
19511
|
}
|
|
19241
19512
|
/**
|
|
19242
19513
|
* Signature fields don't have simple values.
|
|
@@ -19322,7 +19593,7 @@ var RadioField = class extends TerminalField {
|
|
|
19322
19593
|
* that are different from the widget appearance state names.
|
|
19323
19594
|
*/
|
|
19324
19595
|
getExportValues() {
|
|
19325
|
-
const opt = this.dict.getArray("Opt");
|
|
19596
|
+
const opt = this.dict.getArray("Opt", this.registry.resolve.bind(this.registry));
|
|
19326
19597
|
if (!opt) return this.getOptions();
|
|
19327
19598
|
const values = [];
|
|
19328
19599
|
for (let i = 0; i < opt.length; i++) {
|
|
@@ -19441,11 +19712,6 @@ var TextField = class extends TerminalField {
|
|
|
19441
19712
|
//#endregion
|
|
19442
19713
|
//#region src/document/forms/fields/factory.ts
|
|
19443
19714
|
/**
|
|
19444
|
-
* Form field factory function.
|
|
19445
|
-
*
|
|
19446
|
-
* Creates the appropriate field type based on /FT and /Ff values.
|
|
19447
|
-
*/
|
|
19448
|
-
/**
|
|
19449
19715
|
* Create a terminal FormField instance based on /FT and /Ff.
|
|
19450
19716
|
*
|
|
19451
19717
|
* This factory creates only terminal fields (value-holding fields with widgets).
|
|
@@ -19473,15 +19739,15 @@ function createFormField(dict, ref, registry, acroForm, name) {
|
|
|
19473
19739
|
function getInheritableFieldName(dict, key$1, registry) {
|
|
19474
19740
|
let current = dict;
|
|
19475
19741
|
const visited = /* @__PURE__ */ new Set();
|
|
19742
|
+
const resolve = registry.resolve.bind(registry);
|
|
19476
19743
|
while (current) {
|
|
19477
19744
|
if (visited.has(current)) break;
|
|
19478
19745
|
visited.add(current);
|
|
19479
|
-
const value = current.
|
|
19480
|
-
if (value
|
|
19481
|
-
const
|
|
19482
|
-
if (!
|
|
19483
|
-
|
|
19484
|
-
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;
|
|
19485
19751
|
}
|
|
19486
19752
|
return null;
|
|
19487
19753
|
}
|
|
@@ -19491,15 +19757,15 @@ function getInheritableFieldName(dict, key$1, registry) {
|
|
|
19491
19757
|
function getInheritableFieldNumber(dict, key$1, registry) {
|
|
19492
19758
|
let current = dict;
|
|
19493
19759
|
const visited = /* @__PURE__ */ new Set();
|
|
19760
|
+
const resolve = registry.resolve.bind(registry);
|
|
19494
19761
|
while (current) {
|
|
19495
19762
|
if (visited.has(current)) break;
|
|
19496
19763
|
visited.add(current);
|
|
19497
|
-
const value = current.
|
|
19498
|
-
if (value
|
|
19499
|
-
const
|
|
19500
|
-
if (!
|
|
19501
|
-
|
|
19502
|
-
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;
|
|
19503
19769
|
}
|
|
19504
19770
|
return 0;
|
|
19505
19771
|
}
|
|
@@ -19554,7 +19820,9 @@ var FieldTree = class FieldTree {
|
|
|
19554
19820
|
* @returns A fully-loaded FieldTree
|
|
19555
19821
|
*/
|
|
19556
19822
|
static load(acroForm, registry) {
|
|
19557
|
-
const
|
|
19823
|
+
const dict = acroForm.getDict();
|
|
19824
|
+
const resolve = registry.resolve.bind(registry);
|
|
19825
|
+
const fieldsArray = dict.getArray("Fields", resolve);
|
|
19558
19826
|
if (!fieldsArray) return new FieldTree([]);
|
|
19559
19827
|
const visited = /* @__PURE__ */ new Set();
|
|
19560
19828
|
const fields = [];
|
|
@@ -19580,7 +19848,7 @@ var FieldTree = class FieldTree {
|
|
|
19580
19848
|
if (item instanceof PdfRef) item = registry.resolve(item) ?? void 0;
|
|
19581
19849
|
if (item instanceof PdfDict) fieldDict = item;
|
|
19582
19850
|
if (!fieldDict) continue;
|
|
19583
|
-
const partialName = fieldDict.getString("T")?.asString() ?? "";
|
|
19851
|
+
const partialName = fieldDict.getString("T", resolve)?.asString() ?? "";
|
|
19584
19852
|
const fullName = parentName ? partialName ? `${parentName}.${partialName}` : parentName : partialName;
|
|
19585
19853
|
if (checkIsTerminalField(fieldDict, registry)) {
|
|
19586
19854
|
const field = createFormField(fieldDict, ref, registry, acroForm, fullName);
|
|
@@ -19593,7 +19861,7 @@ var FieldTree = class FieldTree {
|
|
|
19593
19861
|
nonTerminal.parent = parent;
|
|
19594
19862
|
fields.push(nonTerminal);
|
|
19595
19863
|
if (parent instanceof NonTerminalField) parent.addChild(nonTerminal);
|
|
19596
|
-
const kids = fieldDict.getArray("Kids");
|
|
19864
|
+
const kids = fieldDict.getArray("Kids", resolve);
|
|
19597
19865
|
if (kids) for (let i = 0; i < kids.length; i++) queue.push({
|
|
19598
19866
|
item: kids.at(i),
|
|
19599
19867
|
parentName: fullName,
|
|
@@ -19663,7 +19931,8 @@ var FieldTree = class FieldTree {
|
|
|
19663
19931
|
* - Its /Kids contain widgets (no /T) rather than child fields (have /T)
|
|
19664
19932
|
*/
|
|
19665
19933
|
function checkIsTerminalField(dict, registry) {
|
|
19666
|
-
const
|
|
19934
|
+
const resolve = registry.resolve.bind(registry);
|
|
19935
|
+
const kids = dict.getArray("Kids", resolve);
|
|
19667
19936
|
if (!kids || kids.length === 0) return true;
|
|
19668
19937
|
let firstKid = kids.at(0);
|
|
19669
19938
|
if (!firstKid) return true;
|
|
@@ -19773,7 +20042,7 @@ var FormFlattener = class {
|
|
|
19773
20042
|
for (const pageRef of pageRefs) {
|
|
19774
20043
|
const pageDict = this.registry.resolve(pageRef);
|
|
19775
20044
|
if (!(pageDict instanceof PdfDict)) continue;
|
|
19776
|
-
const annots = pageDict.getArray("Annots");
|
|
20045
|
+
const annots = pageDict.getArray("Annots", this.registry.resolve.bind(this.registry));
|
|
19777
20046
|
if (!annots) continue;
|
|
19778
20047
|
for (let i = 0; i < annots.length; i++) {
|
|
19779
20048
|
const annotRef = annots.at(i);
|
|
@@ -19794,12 +20063,13 @@ var FormFlattener = class {
|
|
|
19794
20063
|
flattenWidgetsOnPage(pageRef, widgets) {
|
|
19795
20064
|
const pageDict = this.registry.resolve(pageRef);
|
|
19796
20065
|
if (!(pageDict instanceof PdfDict)) return;
|
|
19797
|
-
|
|
20066
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
20067
|
+
let resources = pageDict.getDict("Resources", resolve);
|
|
19798
20068
|
if (!resources) {
|
|
19799
20069
|
resources = new PdfDict();
|
|
19800
20070
|
pageDict.set("Resources", resources);
|
|
19801
20071
|
}
|
|
19802
|
-
let xObjects = resources.getDict("XObject");
|
|
20072
|
+
let xObjects = resources.getDict("XObject", resolve);
|
|
19803
20073
|
if (!xObjects) {
|
|
19804
20074
|
xObjects = new PdfDict();
|
|
19805
20075
|
resources.set("XObject", xObjects);
|
|
@@ -19833,7 +20103,7 @@ var FormFlattener = class {
|
|
|
19833
20103
|
* Per PDFBox: BBox must exist and have width/height > 0.
|
|
19834
20104
|
*/
|
|
19835
20105
|
isVisibleAppearance(appearance) {
|
|
19836
|
-
const bbox = appearance.getArray("BBox");
|
|
20106
|
+
const bbox = appearance.getArray("BBox", this.registry.resolve.bind(this.registry));
|
|
19837
20107
|
if (!bbox || bbox.length < 4) return false;
|
|
19838
20108
|
const [x1, y1, x2, y2] = bbox.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
|
|
19839
20109
|
const width = Math.abs((x2 ?? 0) - (x1 ?? 0));
|
|
@@ -19935,7 +20205,7 @@ var FormFlattener = class {
|
|
|
19935
20205
|
* Get the appearance stream's transformation matrix.
|
|
19936
20206
|
*/
|
|
19937
20207
|
getAppearanceMatrix(appearance) {
|
|
19938
|
-
const matrixArray = appearance.getArray("Matrix");
|
|
20208
|
+
const matrixArray = appearance.getArray("Matrix", this.registry.resolve.bind(this.registry));
|
|
19939
20209
|
if (!matrixArray || matrixArray.length < 6) return Matrix.identity();
|
|
19940
20210
|
const [a, b, c, d, e, f] = matrixArray.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
|
|
19941
20211
|
return new Matrix(a ?? 0, b ?? 0, c ?? 0, d ?? 0, e ?? 0, f ?? 0);
|
|
@@ -19944,7 +20214,7 @@ var FormFlattener = class {
|
|
|
19944
20214
|
* Get appearance BBox, with fallback.
|
|
19945
20215
|
*/
|
|
19946
20216
|
getAppearanceBBox(appearance) {
|
|
19947
|
-
const bbox = appearance.getArray("BBox");
|
|
20217
|
+
const bbox = appearance.getArray("BBox", this.registry.resolve.bind(this.registry));
|
|
19948
20218
|
if (!bbox || bbox.length < 4) return [
|
|
19949
20219
|
0,
|
|
19950
20220
|
0,
|
|
@@ -19963,14 +20233,7 @@ var FormFlattener = class {
|
|
|
19963
20233
|
* Remove specific annotations from page.
|
|
19964
20234
|
*/
|
|
19965
20235
|
removeAnnotations(page, toRemove) {
|
|
19966
|
-
const
|
|
19967
|
-
if (!annotsEntry) return;
|
|
19968
|
-
let annots = null;
|
|
19969
|
-
if (annotsEntry instanceof PdfArray) annots = annotsEntry;
|
|
19970
|
-
else if (annotsEntry instanceof PdfRef) {
|
|
19971
|
-
const resolved = this.registry.resolve(annotsEntry);
|
|
19972
|
-
if (resolved instanceof PdfArray) annots = resolved;
|
|
19973
|
-
}
|
|
20236
|
+
const annots = page.getArray("Annots", this.registry.resolve.bind(this.registry));
|
|
19974
20237
|
if (!annots) return;
|
|
19975
20238
|
const remaining = [];
|
|
19976
20239
|
for (let i = 0; i < annots.length; i++) {
|
|
@@ -20036,11 +20299,8 @@ var AcroForm = class AcroForm {
|
|
|
20036
20299
|
* @param pageTree Optional page tree for efficient page lookups during flattening
|
|
20037
20300
|
*/
|
|
20038
20301
|
static load(catalog, registry, pageTree) {
|
|
20039
|
-
|
|
20040
|
-
|
|
20041
|
-
let dict = null;
|
|
20042
|
-
if (acroFormEntry instanceof PdfRef) acroFormEntry = registry.resolve(acroFormEntry) ?? void 0;
|
|
20043
|
-
if (acroFormEntry instanceof PdfDict) dict = acroFormEntry;
|
|
20302
|
+
const resolve = registry.resolve.bind(registry);
|
|
20303
|
+
const dict = catalog.getDict("AcroForm", resolve);
|
|
20044
20304
|
if (!dict) return null;
|
|
20045
20305
|
return new AcroForm(dict, registry, pageTree ?? null);
|
|
20046
20306
|
}
|
|
@@ -20048,11 +20308,7 @@ var AcroForm = class AcroForm {
|
|
|
20048
20308
|
* Default resources dictionary (fonts, etc.).
|
|
20049
20309
|
*/
|
|
20050
20310
|
getDefaultResources() {
|
|
20051
|
-
|
|
20052
|
-
if (!dr) return null;
|
|
20053
|
-
if (dr instanceof PdfRef) dr = this.registry.resolve(dr) ?? void 0;
|
|
20054
|
-
if (dr instanceof PdfDict) return dr;
|
|
20055
|
-
return null;
|
|
20311
|
+
return this.dict.getDict("DR", this.registry.resolve.bind(this.registry)) ?? null;
|
|
20056
20312
|
}
|
|
20057
20313
|
/**
|
|
20058
20314
|
* Default appearance string.
|
|
@@ -20216,9 +20472,10 @@ var AcroForm = class AcroForm {
|
|
|
20216
20472
|
ensureExistingFontsLoaded() {
|
|
20217
20473
|
if (this.existingFontsCache !== null) return;
|
|
20218
20474
|
this.existingFontsCache = /* @__PURE__ */ new Map();
|
|
20219
|
-
const
|
|
20475
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
20476
|
+
const dr = this.dict.getDict("DR", resolve);
|
|
20220
20477
|
if (!dr) return;
|
|
20221
|
-
const fonts = dr.getDict("Font");
|
|
20478
|
+
const fonts = dr.getDict("Font", resolve);
|
|
20222
20479
|
if (!fonts) return;
|
|
20223
20480
|
for (const key$1 of fonts.keys()) {
|
|
20224
20481
|
const fontName = key$1.value;
|
|
@@ -20393,12 +20650,13 @@ var AcroForm = class AcroForm {
|
|
|
20393
20650
|
* @returns The font name used in the /DR dictionary
|
|
20394
20651
|
*/
|
|
20395
20652
|
addFontToResources(fontRef, name) {
|
|
20396
|
-
|
|
20653
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
20654
|
+
let dr = this.dict.getDict("DR", resolve);
|
|
20397
20655
|
if (!dr) {
|
|
20398
20656
|
dr = new PdfDict();
|
|
20399
20657
|
this.dict.set("DR", dr);
|
|
20400
20658
|
}
|
|
20401
|
-
let fontsDict = dr.getDict("Font");
|
|
20659
|
+
let fontsDict = dr.getDict("Font", resolve);
|
|
20402
20660
|
if (!fontsDict) {
|
|
20403
20661
|
fontsDict = new PdfDict();
|
|
20404
20662
|
dr.set("Font", fontsDict);
|
|
@@ -20482,371 +20740,8 @@ var AcroForm = class AcroForm {
|
|
|
20482
20740
|
}
|
|
20483
20741
|
};
|
|
20484
20742
|
|
|
20485
|
-
//#endregion
|
|
20486
|
-
//#region src/fonts/embedded-font.ts
|
|
20487
|
-
/**
|
|
20488
|
-
* EmbeddedFont represents a font that will be embedded into a PDF.
|
|
20489
|
-
*
|
|
20490
|
-
* Usage:
|
|
20491
|
-
* ```typescript
|
|
20492
|
-
* const fontBytes = await fs.readFile("NotoSans-Regular.ttf");
|
|
20493
|
-
* const font = EmbeddedFont.fromBytes(fontBytes);
|
|
20494
|
-
*
|
|
20495
|
-
* // Check if text can be encoded
|
|
20496
|
-
* if (font.canEncode("Hello ")) {
|
|
20497
|
-
* const codes = font.encodeText("Hello ");
|
|
20498
|
-
* const width = font.getTextWidth("Hello ", 12);
|
|
20499
|
-
* }
|
|
20500
|
-
* ```
|
|
20501
|
-
*/
|
|
20502
|
-
var EmbeddedFont = class EmbeddedFont extends PdfFont {
|
|
20503
|
-
subtype = "Type0";
|
|
20504
|
-
/** Underlying font program */
|
|
20505
|
-
fontProgram;
|
|
20506
|
-
/** Original font data */
|
|
20507
|
-
fontData;
|
|
20508
|
-
/** Track used glyphs for subsetting (GID -> code points that use it) */
|
|
20509
|
-
usedGlyphs = new Map([[0, /* @__PURE__ */ new Set()]]);
|
|
20510
|
-
/** Track used code points for ToUnicode (codePoint -> GID) */
|
|
20511
|
-
usedCodePoints = /* @__PURE__ */ new Map();
|
|
20512
|
-
/** Subset tag (generated during save) */
|
|
20513
|
-
_subsetTag = null;
|
|
20514
|
-
/** Whether this font is used in a form field (prevents subsetting) */
|
|
20515
|
-
_usedInForm = false;
|
|
20516
|
-
/** Cached descriptor */
|
|
20517
|
-
_descriptor = null;
|
|
20518
|
-
constructor(fontProgram, fontData) {
|
|
20519
|
-
super();
|
|
20520
|
-
this.fontProgram = fontProgram;
|
|
20521
|
-
this.fontData = fontData;
|
|
20522
|
-
}
|
|
20523
|
-
/**
|
|
20524
|
-
* Create an EmbeddedFont from raw font bytes.
|
|
20525
|
-
*
|
|
20526
|
-
* @param data - TTF, OTF, or Type1 font data
|
|
20527
|
-
* @param options - Embedding options
|
|
20528
|
-
* @returns EmbeddedFont instance
|
|
20529
|
-
* @throws {Error} if font format is not recognized
|
|
20530
|
-
*/
|
|
20531
|
-
static fromBytes(data, _options) {
|
|
20532
|
-
return new EmbeddedFont(parseFontProgram(data), data);
|
|
20533
|
-
}
|
|
20534
|
-
/**
|
|
20535
|
-
* Create an EmbeddedFont from an already-parsed TrueType font.
|
|
20536
|
-
*/
|
|
20537
|
-
static fromTrueTypeFont(font, data) {
|
|
20538
|
-
return new EmbeddedFont(new TrueTypeFontProgram(font, data), data);
|
|
20539
|
-
}
|
|
20540
|
-
/**
|
|
20541
|
-
* Get the base font name.
|
|
20542
|
-
* During save, this will include a subset tag prefix (e.g., "ABCDEF+FontName").
|
|
20543
|
-
*/
|
|
20544
|
-
get baseFontName() {
|
|
20545
|
-
const name = this.fontProgram.postScriptName ?? "Unknown";
|
|
20546
|
-
return this._subsetTag ? `${this._subsetTag}+${name}` : name;
|
|
20547
|
-
}
|
|
20548
|
-
/**
|
|
20549
|
-
* Get the font descriptor.
|
|
20550
|
-
*/
|
|
20551
|
-
get descriptor() {
|
|
20552
|
-
if (!this._descriptor) this._descriptor = this.buildDescriptor();
|
|
20553
|
-
return this._descriptor;
|
|
20554
|
-
}
|
|
20555
|
-
/**
|
|
20556
|
-
* Get the underlying font program.
|
|
20557
|
-
*/
|
|
20558
|
-
get program() {
|
|
20559
|
-
return this.fontProgram;
|
|
20560
|
-
}
|
|
20561
|
-
/**
|
|
20562
|
-
* Get the original font data.
|
|
20563
|
-
*/
|
|
20564
|
-
get data() {
|
|
20565
|
-
return this.fontData;
|
|
20566
|
-
}
|
|
20567
|
-
/**
|
|
20568
|
-
* Get the subset tag (only available after save).
|
|
20569
|
-
*/
|
|
20570
|
-
get subsetTag() {
|
|
20571
|
-
return this._subsetTag;
|
|
20572
|
-
}
|
|
20573
|
-
/**
|
|
20574
|
-
* Set the subset tag (called during save).
|
|
20575
|
-
*/
|
|
20576
|
-
setSubsetTag(tag) {
|
|
20577
|
-
this._subsetTag = tag;
|
|
20578
|
-
}
|
|
20579
|
-
/**
|
|
20580
|
-
* Get all used glyph IDs.
|
|
20581
|
-
*/
|
|
20582
|
-
getUsedGlyphIds() {
|
|
20583
|
-
return [...this.usedGlyphs.keys()].sort((a, b) => a - b);
|
|
20584
|
-
}
|
|
20585
|
-
/**
|
|
20586
|
-
* Get mapping from code point to GID.
|
|
20587
|
-
*/
|
|
20588
|
-
getCodePointToGidMap() {
|
|
20589
|
-
return new Map(this.usedCodePoints);
|
|
20590
|
-
}
|
|
20591
|
-
/**
|
|
20592
|
-
* Get mapping from GID to Unicode code point.
|
|
20593
|
-
*
|
|
20594
|
-
* This is used for building the /W widths array and ToUnicode CMap.
|
|
20595
|
-
* Since the content stream contains GIDs (with CIDToGIDMap /Identity),
|
|
20596
|
-
* the /W array must be keyed by GID, and ToUnicode must map GID → Unicode.
|
|
20597
|
-
*
|
|
20598
|
-
* If multiple code points map to the same GID, returns the first one found.
|
|
20599
|
-
*/
|
|
20600
|
-
getGidToCodePointMap() {
|
|
20601
|
-
const result = /* @__PURE__ */ new Map();
|
|
20602
|
-
for (const [gid, codePoints] of this.usedGlyphs) if (codePoints.size > 0) {
|
|
20603
|
-
const firstCodePoint = codePoints.values().next().value;
|
|
20604
|
-
if (firstCodePoint !== void 0) result.set(gid, firstCodePoint);
|
|
20605
|
-
}
|
|
20606
|
-
return result;
|
|
20607
|
-
}
|
|
20608
|
-
/**
|
|
20609
|
-
* Iterate over text, tracking glyph usage and returning codePoint/GID pairs.
|
|
20610
|
-
* This is the shared implementation for encodeText and encodeTextToGids.
|
|
20611
|
-
*/
|
|
20612
|
-
trackAndEncode(text) {
|
|
20613
|
-
const result = [];
|
|
20614
|
-
for (const char of text) {
|
|
20615
|
-
const codePoint = char.codePointAt(0);
|
|
20616
|
-
if (codePoint === void 0) continue;
|
|
20617
|
-
const gid = this.fontProgram.getGlyphId(codePoint);
|
|
20618
|
-
if (!this.usedGlyphs.has(gid)) this.usedGlyphs.set(gid, /* @__PURE__ */ new Set());
|
|
20619
|
-
this.usedGlyphs.get(gid).add(codePoint);
|
|
20620
|
-
this.usedCodePoints.set(codePoint, gid);
|
|
20621
|
-
result.push({
|
|
20622
|
-
codePoint,
|
|
20623
|
-
gid
|
|
20624
|
-
});
|
|
20625
|
-
}
|
|
20626
|
-
return result;
|
|
20627
|
-
}
|
|
20628
|
-
/**
|
|
20629
|
-
* Encode text to character codes.
|
|
20630
|
-
*
|
|
20631
|
-
* Returns Unicode code points, which is intuitive for users.
|
|
20632
|
-
* The conversion to glyph IDs happens internally when writing to the PDF.
|
|
20633
|
-
*
|
|
20634
|
-
* Also tracks glyph usage for subsetting.
|
|
20635
|
-
*/
|
|
20636
|
-
encodeText(text) {
|
|
20637
|
-
return this.trackAndEncode(text).map((e) => e.codePoint);
|
|
20638
|
-
}
|
|
20639
|
-
/**
|
|
20640
|
-
* Encode text to glyph IDs for PDF content stream.
|
|
20641
|
-
*
|
|
20642
|
-
* This is an internal method used when writing to the PDF.
|
|
20643
|
-
* With CIDToGIDMap /Identity, the content stream must contain GIDs.
|
|
20644
|
-
*
|
|
20645
|
-
* @internal
|
|
20646
|
-
*/
|
|
20647
|
-
encodeTextToGids(text) {
|
|
20648
|
-
return this.trackAndEncode(text).map((e) => e.gid);
|
|
20649
|
-
}
|
|
20650
|
-
/**
|
|
20651
|
-
* Convert a code point to its glyph ID.
|
|
20652
|
-
*
|
|
20653
|
-
* @internal
|
|
20654
|
-
*/
|
|
20655
|
-
codePointToGid(codePoint) {
|
|
20656
|
-
return this.fontProgram.getGlyphId(codePoint);
|
|
20657
|
-
}
|
|
20658
|
-
/**
|
|
20659
|
-
* Get width of a character in glyph units (1000 = 1 em).
|
|
20660
|
-
*
|
|
20661
|
-
* Takes a Unicode code point (user-friendly API).
|
|
20662
|
-
*/
|
|
20663
|
-
getWidth(code) {
|
|
20664
|
-
const gid = this.fontProgram.getGlyphId(code);
|
|
20665
|
-
const width = this.fontProgram.getAdvanceWidth(gid);
|
|
20666
|
-
return Math.round(width * 1e3 / this.fontProgram.unitsPerEm);
|
|
20667
|
-
}
|
|
20668
|
-
/**
|
|
20669
|
-
* Decode character code to Unicode string.
|
|
20670
|
-
*
|
|
20671
|
-
* For embedded fonts with Identity-H encoding, the code is the code point,
|
|
20672
|
-
* so this just converts the code point back to a string.
|
|
20673
|
-
*/
|
|
20674
|
-
toUnicode(code) {
|
|
20675
|
-
return String.fromCodePoint(code);
|
|
20676
|
-
}
|
|
20677
|
-
/**
|
|
20678
|
-
* Check if the font can encode the given text.
|
|
20679
|
-
* Returns true if all characters have glyphs in the font.
|
|
20680
|
-
*/
|
|
20681
|
-
canEncode(text) {
|
|
20682
|
-
for (const char of text) {
|
|
20683
|
-
const codePoint = char.codePointAt(0);
|
|
20684
|
-
if (codePoint === void 0) continue;
|
|
20685
|
-
if (!this.fontProgram.hasGlyph(codePoint)) return false;
|
|
20686
|
-
}
|
|
20687
|
-
return true;
|
|
20688
|
-
}
|
|
20689
|
-
/**
|
|
20690
|
-
* Get the characters that cannot be encoded.
|
|
20691
|
-
*/
|
|
20692
|
-
getUnencodableCharacters(text) {
|
|
20693
|
-
const unencodable = [];
|
|
20694
|
-
for (const char of text) {
|
|
20695
|
-
const codePoint = char.codePointAt(0);
|
|
20696
|
-
if (codePoint === void 0) continue;
|
|
20697
|
-
if (!this.fontProgram.hasGlyph(codePoint)) unencodable.push(char);
|
|
20698
|
-
}
|
|
20699
|
-
return unencodable;
|
|
20700
|
-
}
|
|
20701
|
-
/**
|
|
20702
|
-
* Reset glyph usage tracking.
|
|
20703
|
-
* Call this before re-encoding if you want a fresh subset.
|
|
20704
|
-
*/
|
|
20705
|
-
resetUsage() {
|
|
20706
|
-
this.usedGlyphs.clear();
|
|
20707
|
-
this.usedGlyphs.set(0, /* @__PURE__ */ new Set());
|
|
20708
|
-
this.usedCodePoints.clear();
|
|
20709
|
-
this._subsetTag = null;
|
|
20710
|
-
}
|
|
20711
|
-
/**
|
|
20712
|
-
* Mark this font as used in a form field.
|
|
20713
|
-
*
|
|
20714
|
-
* Fonts used in form fields cannot be subsetted because users may type
|
|
20715
|
-
* any character at runtime. This method is called automatically when
|
|
20716
|
-
* an EmbeddedFont is used in form field appearances.
|
|
20717
|
-
*/
|
|
20718
|
-
markUsedInForm() {
|
|
20719
|
-
this._usedInForm = true;
|
|
20720
|
-
}
|
|
20721
|
-
/**
|
|
20722
|
-
* Check if this font is used in a form field.
|
|
20723
|
-
*/
|
|
20724
|
-
get usedInForm() {
|
|
20725
|
-
return this._usedInForm;
|
|
20726
|
-
}
|
|
20727
|
-
/**
|
|
20728
|
-
* Check if this font can be subsetted.
|
|
20729
|
-
*
|
|
20730
|
-
* Returns false if the font is used in a form field (since users can
|
|
20731
|
-
* type any character at runtime).
|
|
20732
|
-
*/
|
|
20733
|
-
canSubset() {
|
|
20734
|
-
return !this._usedInForm;
|
|
20735
|
-
}
|
|
20736
|
-
/**
|
|
20737
|
-
* Get width of text in points at a given font size.
|
|
20738
|
-
*
|
|
20739
|
-
* Alias for getTextWidth() to match Standard14Font API.
|
|
20740
|
-
*
|
|
20741
|
-
* @param text - The text to measure
|
|
20742
|
-
* @param size - Font size in points
|
|
20743
|
-
* @returns Width in points
|
|
20744
|
-
*/
|
|
20745
|
-
widthOfTextAtSize(text, size) {
|
|
20746
|
-
return this.getTextWidth(text, size);
|
|
20747
|
-
}
|
|
20748
|
-
/**
|
|
20749
|
-
* Get the height of the font at a given size.
|
|
20750
|
-
*
|
|
20751
|
-
* This returns the full height from descender to ascender.
|
|
20752
|
-
*
|
|
20753
|
-
* @param size - Font size in points
|
|
20754
|
-
* @returns Height in points
|
|
20755
|
-
*/
|
|
20756
|
-
heightAtSize(size) {
|
|
20757
|
-
const desc = this.descriptor;
|
|
20758
|
-
if (!desc) return size;
|
|
20759
|
-
return (desc.ascent - desc.descent) * size / 1e3;
|
|
20760
|
-
}
|
|
20761
|
-
/**
|
|
20762
|
-
* Calculate font size needed to achieve a specific text height.
|
|
20763
|
-
*
|
|
20764
|
-
* @param height - Desired height in points
|
|
20765
|
-
* @returns Font size in points
|
|
20766
|
-
*/
|
|
20767
|
-
sizeAtHeight(height) {
|
|
20768
|
-
const desc = this.descriptor;
|
|
20769
|
-
if (!desc) return height;
|
|
20770
|
-
const unitsHeight = desc.ascent - desc.descent;
|
|
20771
|
-
return height * 1e3 / unitsHeight;
|
|
20772
|
-
}
|
|
20773
|
-
/**
|
|
20774
|
-
* Calculate font size needed for text to fit a specific width.
|
|
20775
|
-
*
|
|
20776
|
-
* @param text - The text to measure
|
|
20777
|
-
* @param width - Desired width in points
|
|
20778
|
-
* @returns Font size in points
|
|
20779
|
-
*/
|
|
20780
|
-
sizeAtWidth(text, width) {
|
|
20781
|
-
if (text.length === 0) return 0;
|
|
20782
|
-
const codes = this.encodeText(text);
|
|
20783
|
-
let totalWidth = 0;
|
|
20784
|
-
for (const code of codes) totalWidth += this.getWidth(code);
|
|
20785
|
-
if (totalWidth === 0) return 0;
|
|
20786
|
-
return width * 1e3 / totalWidth;
|
|
20787
|
-
}
|
|
20788
|
-
/**
|
|
20789
|
-
* Build a FontDescriptor from the font program.
|
|
20790
|
-
*/
|
|
20791
|
-
buildDescriptor() {
|
|
20792
|
-
const program = this.fontProgram;
|
|
20793
|
-
const bbox = program.bbox;
|
|
20794
|
-
const scale = 1e3 / program.unitsPerEm;
|
|
20795
|
-
return new FontDescriptor({
|
|
20796
|
-
fontName: program.postScriptName ?? "Unknown",
|
|
20797
|
-
flags: this.computeFlags(),
|
|
20798
|
-
fontBBox: [
|
|
20799
|
-
Math.round(bbox[0] * scale),
|
|
20800
|
-
Math.round(bbox[1] * scale),
|
|
20801
|
-
Math.round(bbox[2] * scale),
|
|
20802
|
-
Math.round(bbox[3] * scale)
|
|
20803
|
-
],
|
|
20804
|
-
italicAngle: program.italicAngle,
|
|
20805
|
-
ascent: Math.round(program.ascent * scale),
|
|
20806
|
-
descent: Math.round(program.descent * scale),
|
|
20807
|
-
leading: 0,
|
|
20808
|
-
capHeight: Math.round(program.capHeight * scale),
|
|
20809
|
-
xHeight: Math.round(program.xHeight * scale),
|
|
20810
|
-
stemV: program.stemV,
|
|
20811
|
-
stemH: 0,
|
|
20812
|
-
avgWidth: 0,
|
|
20813
|
-
maxWidth: 0,
|
|
20814
|
-
missingWidth: this.getWidth(0)
|
|
20815
|
-
});
|
|
20816
|
-
}
|
|
20817
|
-
/**
|
|
20818
|
-
* Compute font flags for the descriptor.
|
|
20819
|
-
*/
|
|
20820
|
-
computeFlags() {
|
|
20821
|
-
let flags = 0;
|
|
20822
|
-
if (this.fontProgram.isFixedPitch) flags |= 1;
|
|
20823
|
-
flags |= 4;
|
|
20824
|
-
if (this.fontProgram.italicAngle !== 0) flags |= 64;
|
|
20825
|
-
return flags;
|
|
20826
|
-
}
|
|
20827
|
-
};
|
|
20828
|
-
|
|
20829
20743
|
//#endregion
|
|
20830
20744
|
//#region src/fonts/cid-font.ts
|
|
20831
|
-
/**
|
|
20832
|
-
* CIDFont - Descendant font for Type0 composite fonts.
|
|
20833
|
-
*
|
|
20834
|
-
* CIDFonts contain the actual glyph descriptions and metrics for
|
|
20835
|
-
* composite (Type0) fonts. They use CIDs (Character IDs) to identify
|
|
20836
|
-
* glyphs rather than character codes.
|
|
20837
|
-
*
|
|
20838
|
-
* Font structure:
|
|
20839
|
-
* <<
|
|
20840
|
-
* /Type /Font
|
|
20841
|
-
* /Subtype /CIDFontType2 (or /CIDFontType0)
|
|
20842
|
-
* /BaseFont /NotoSansCJK-Regular
|
|
20843
|
-
* /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>
|
|
20844
|
-
* /FontDescriptor 14 0 R
|
|
20845
|
-
* /W [1 [500 600] 100 200 500] % Complex width format
|
|
20846
|
-
* /DW 1000
|
|
20847
|
-
* /CIDToGIDMap /Identity
|
|
20848
|
-
* >>
|
|
20849
|
-
*/
|
|
20850
20745
|
const isCIDFontSubtype = (subtype) => {
|
|
20851
20746
|
return subtype === "CIDFontType0" || subtype === "CIDFontType2";
|
|
20852
20747
|
};
|
|
@@ -21011,7 +20906,7 @@ function parseCIDFont(dict, options = {}) {
|
|
|
21011
20906
|
ordering: "Identity",
|
|
21012
20907
|
supplement: 0
|
|
21013
20908
|
};
|
|
21014
|
-
const sysInfoDict = dict.getDict("CIDSystemInfo");
|
|
20909
|
+
const sysInfoDict = dict.getDict("CIDSystemInfo", options.resolver);
|
|
21015
20910
|
if (sysInfoDict) cidSystemInfo = {
|
|
21016
20911
|
registry: sysInfoDict.getString("Registry")?.asString() ?? "Adobe",
|
|
21017
20912
|
ordering: sysInfoDict.getString("Ordering")?.asString() ?? "Identity",
|
|
@@ -21019,30 +20914,23 @@ function parseCIDFont(dict, options = {}) {
|
|
|
21019
20914
|
};
|
|
21020
20915
|
const defaultWidth = dict.getNumber("DW")?.value ?? 1e3;
|
|
21021
20916
|
let widths = new CIDWidthMap();
|
|
21022
|
-
let w = dict.get("W");
|
|
20917
|
+
let w = dict.get("W", options.resolver);
|
|
21023
20918
|
let wArray = null;
|
|
21024
|
-
if (w instanceof PdfRef && options.resolveRef) w = options.resolveRef(w) ?? void 0;
|
|
21025
20919
|
if (w instanceof PdfArray) wArray = w;
|
|
21026
20920
|
if (wArray) widths = parseCIDWidths(wArray);
|
|
21027
20921
|
let descriptor = null;
|
|
21028
20922
|
let embeddedProgram = null;
|
|
21029
|
-
const
|
|
21030
|
-
if (
|
|
21031
|
-
|
|
21032
|
-
|
|
21033
|
-
descriptor = FontDescriptor.parse(descriptorDict);
|
|
21034
|
-
if (options.decodeStream) embeddedProgram = parseEmbeddedProgram(descriptorDict, {
|
|
21035
|
-
decodeStream: options.decodeStream,
|
|
21036
|
-
resolveRef: options.resolveRef
|
|
21037
|
-
});
|
|
21038
|
-
}
|
|
20923
|
+
const fontDescriptor = dict.getDict("FontDescriptor", options.resolver);
|
|
20924
|
+
if (fontDescriptor) {
|
|
20925
|
+
descriptor = FontDescriptor.parse(fontDescriptor);
|
|
20926
|
+
embeddedProgram = parseEmbeddedProgram(fontDescriptor, { resolver: options.resolver });
|
|
21039
20927
|
}
|
|
21040
20928
|
let cidToGidMap = "Identity";
|
|
21041
|
-
const cidToGidValue = dict.get("CIDToGIDMap");
|
|
20929
|
+
const cidToGidValue = dict.get("CIDToGIDMap", options.resolver);
|
|
21042
20930
|
if (cidToGidValue) {
|
|
21043
|
-
if (cidToGidValue
|
|
21044
|
-
if (cidToGidValue
|
|
21045
|
-
const mapData =
|
|
20931
|
+
if (cidToGidValue instanceof PdfName && cidToGidValue.value === "Identity") cidToGidMap = "Identity";
|
|
20932
|
+
if (cidToGidValue instanceof PdfStream) {
|
|
20933
|
+
const mapData = cidToGidValue.getDecodedData();
|
|
21046
20934
|
if (mapData && mapData.length >= 2) {
|
|
21047
20935
|
const numEntries = mapData.length / 2;
|
|
21048
20936
|
cidToGidMap = new Uint16Array(numEntries);
|
|
@@ -21324,24 +21212,6 @@ function bytesToLatin1$1(data) {
|
|
|
21324
21212
|
//#endregion
|
|
21325
21213
|
//#region src/fonts/composite-font.ts
|
|
21326
21214
|
/**
|
|
21327
|
-
* CompositeFont - Type0 composite font for CJK and Unicode text.
|
|
21328
|
-
*
|
|
21329
|
-
* Composite fonts (Type0) combine:
|
|
21330
|
-
* - A CMap (character code to CID mapping)
|
|
21331
|
-
* - One or more CIDFonts (the actual glyph data)
|
|
21332
|
-
* - Optional ToUnicode map (for text extraction)
|
|
21333
|
-
*
|
|
21334
|
-
* Font structure:
|
|
21335
|
-
* <<
|
|
21336
|
-
* /Type /Font
|
|
21337
|
-
* /Subtype /Type0
|
|
21338
|
-
* /BaseFont /NotoSansCJK-Regular
|
|
21339
|
-
* /Encoding /Identity-H (or stream)
|
|
21340
|
-
* /DescendantFonts [12 0 R]
|
|
21341
|
-
* /ToUnicode 13 0 R
|
|
21342
|
-
* >>
|
|
21343
|
-
*/
|
|
21344
|
-
/**
|
|
21345
21215
|
* CompositeFont handles Type0 composite fonts (CJK, Unicode).
|
|
21346
21216
|
*/
|
|
21347
21217
|
var CompositeFont = class extends PdfFont {
|
|
@@ -21416,40 +21286,28 @@ var CompositeFont = class extends PdfFont {
|
|
|
21416
21286
|
* Parse CMap from encoding value.
|
|
21417
21287
|
*/
|
|
21418
21288
|
function parseCMapFromEncoding(encodingValue, options) {
|
|
21419
|
-
|
|
21420
|
-
|
|
21421
|
-
if (
|
|
21422
|
-
if (
|
|
21423
|
-
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();
|
|
21424
21294
|
return data ? parseCMap(data) : CMap.identityH();
|
|
21425
21295
|
}
|
|
21426
|
-
if (enc.type === "ref" && options.resolveRef && options.decodeStream) {
|
|
21427
|
-
const resolved = options.resolveRef(encodingValue);
|
|
21428
|
-
if (resolved && resolved.type === "stream") {
|
|
21429
|
-
const data = options.decodeStream(resolved);
|
|
21430
|
-
return data ? parseCMap(data) : CMap.identityH();
|
|
21431
|
-
}
|
|
21432
|
-
}
|
|
21433
21296
|
return CMap.identityH();
|
|
21434
21297
|
}
|
|
21435
21298
|
/**
|
|
21436
21299
|
* Parse a CompositeFont from a PDF font dictionary.
|
|
21437
21300
|
*/
|
|
21438
21301
|
function parseCompositeFont(dict, options = {}) {
|
|
21439
|
-
const baseFontName = dict.getName("BaseFont")?.value ?? "Unknown";
|
|
21440
|
-
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);
|
|
21441
21304
|
let cidFont;
|
|
21442
|
-
let descendants = dict.get("DescendantFonts");
|
|
21305
|
+
let descendants = dict.get("DescendantFonts", options.resolver);
|
|
21443
21306
|
let descendantsArray = null;
|
|
21444
|
-
if (descendants instanceof PdfRef && options.resolveRef) descendants = options.resolveRef(descendants) ?? void 0;
|
|
21445
21307
|
if (descendants instanceof PdfArray) descendantsArray = descendants;
|
|
21446
21308
|
if (descendantsArray && descendantsArray.length > 0) {
|
|
21447
|
-
const firstDescendant = descendantsArray.at(0);
|
|
21448
|
-
if (firstDescendant
|
|
21449
|
-
const cidFontDict = options.resolveRef(firstDescendant);
|
|
21450
|
-
if (cidFontDict?.type === "dict") cidFont = parseCIDFont(cidFontDict, options);
|
|
21451
|
-
else cidFont = createDefaultCIDFont(baseFontName);
|
|
21452
|
-
} 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);
|
|
21453
21311
|
else cidFont = createDefaultCIDFont(baseFontName);
|
|
21454
21312
|
} else cidFont = createDefaultCIDFont(baseFontName);
|
|
21455
21313
|
return new CompositeFont({
|
|
@@ -21480,7 +21338,7 @@ function createDefaultCIDFont(baseFontName) {
|
|
|
21480
21338
|
* @returns A SimpleFont or CompositeFont instance
|
|
21481
21339
|
*/
|
|
21482
21340
|
function parseFont(dict, options = {}) {
|
|
21483
|
-
switch (dict.getName("Subtype")?.value) {
|
|
21341
|
+
switch (dict.getName("Subtype", options.resolver)?.value) {
|
|
21484
21342
|
case "Type0": return parseCompositeFont(dict, options);
|
|
21485
21343
|
case "TrueType":
|
|
21486
21344
|
case "Type1":
|
|
@@ -24306,8 +24164,8 @@ var PDFPage = class PDFPage {
|
|
|
24306
24164
|
* Page rotation in degrees (0, 90, 180, or 270).
|
|
24307
24165
|
*/
|
|
24308
24166
|
get rotation() {
|
|
24309
|
-
const rotate = this.dict.
|
|
24310
|
-
if (rotate
|
|
24167
|
+
const rotate = this.dict.getNumber("Rotate", this.ctx.resolve.bind(this.ctx));
|
|
24168
|
+
if (rotate) {
|
|
24311
24169
|
const value = rotate.value % 360;
|
|
24312
24170
|
if (value === 90 || value === -270) return 90;
|
|
24313
24171
|
if (value === 180 || value === -180) return 180;
|
|
@@ -24332,8 +24190,7 @@ var PDFPage = class PDFPage {
|
|
|
24332
24190
|
* a new empty dict is created on this page.
|
|
24333
24191
|
*/
|
|
24334
24192
|
getResources() {
|
|
24335
|
-
let resources = this.dict.get("Resources");
|
|
24336
|
-
if (resources instanceof PdfRef) resources = this.ctx.resolve(resources) ?? void 0;
|
|
24193
|
+
let resources = this.dict.get("Resources", this.ctx.resolve.bind(this.ctx));
|
|
24337
24194
|
if (resources instanceof PdfDict) return resources;
|
|
24338
24195
|
resources = new PdfDict();
|
|
24339
24196
|
this.dict.set("Resources", resources);
|
|
@@ -25014,13 +24871,9 @@ var PDFPage = class PDFPage {
|
|
|
25014
24871
|
for (let i = 0; i < annotsArray.length; i++) {
|
|
25015
24872
|
const entry = annotsArray.at(i);
|
|
25016
24873
|
if (!entry) continue;
|
|
25017
|
-
|
|
25018
|
-
|
|
25019
|
-
|
|
25020
|
-
annotRef = entry;
|
|
25021
|
-
const resolved = this.ctx.resolve(entry);
|
|
25022
|
-
if (resolved instanceof PdfDict) annotDict = resolved;
|
|
25023
|
-
} 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;
|
|
25024
24877
|
if (!annotDict) continue;
|
|
25025
24878
|
if (isWidgetAnnotation(annotDict)) continue;
|
|
25026
24879
|
if (isPopupAnnotation(annotDict)) continue;
|
|
@@ -25042,13 +24895,9 @@ var PDFPage = class PDFPage {
|
|
|
25042
24895
|
for (let i = 0; i < annotsArray.length; i++) {
|
|
25043
24896
|
let entry = annotsArray.at(i);
|
|
25044
24897
|
if (!entry) continue;
|
|
25045
|
-
|
|
25046
|
-
|
|
25047
|
-
|
|
25048
|
-
annotRef = entry;
|
|
25049
|
-
entry = this.ctx.resolve(entry) ?? void 0;
|
|
25050
|
-
}
|
|
25051
|
-
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;
|
|
25052
24901
|
if (!annotDict || !isPopupAnnotation(annotDict)) continue;
|
|
25053
24902
|
popups.push(new PDFPopupAnnotation(annotDict, annotRef, this.ctx.registry));
|
|
25054
24903
|
}
|
|
@@ -25497,16 +25346,24 @@ var PDFPage = class PDFPage {
|
|
|
25497
25346
|
prependContent(content) {
|
|
25498
25347
|
const existingContents = this.dict.get("Contents");
|
|
25499
25348
|
const newContent = this.createContentStream(`${content}\n`);
|
|
25500
|
-
if (!existingContents)
|
|
25501
|
-
|
|
25349
|
+
if (!existingContents) {
|
|
25350
|
+
this.dict.set("Contents", newContent);
|
|
25351
|
+
return;
|
|
25352
|
+
}
|
|
25353
|
+
if (existingContents instanceof PdfRef) {
|
|
25502
25354
|
this.dict.set("Contents", new PdfArray([newContent, existingContents]));
|
|
25503
25355
|
this._contentWrapped = true;
|
|
25504
|
-
|
|
25356
|
+
return;
|
|
25357
|
+
}
|
|
25358
|
+
if (existingContents instanceof PdfStream) {
|
|
25505
25359
|
this.dict.set("Contents", new PdfArray([newContent, existingContents]));
|
|
25506
25360
|
this._contentWrapped = true;
|
|
25507
|
-
|
|
25361
|
+
return;
|
|
25362
|
+
}
|
|
25363
|
+
if (existingContents instanceof PdfArray) {
|
|
25508
25364
|
existingContents.insert(0, newContent);
|
|
25509
25365
|
this._contentWrapped = true;
|
|
25366
|
+
return;
|
|
25510
25367
|
}
|
|
25511
25368
|
}
|
|
25512
25369
|
/** Track whether we've already wrapped the original content in q/Q */
|
|
@@ -25529,19 +25386,25 @@ var PDFPage = class PDFPage {
|
|
|
25529
25386
|
this._contentWrapped = true;
|
|
25530
25387
|
const qStream = this.createContentStream("q\n");
|
|
25531
25388
|
const QStream = this.createContentStream("\nQ");
|
|
25532
|
-
if (existingContents instanceof PdfRef)
|
|
25533
|
-
|
|
25534
|
-
|
|
25535
|
-
|
|
25536
|
-
|
|
25537
|
-
|
|
25538
|
-
|
|
25539
|
-
|
|
25540
|
-
|
|
25541
|
-
|
|
25542
|
-
|
|
25543
|
-
|
|
25544
|
-
|
|
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) {
|
|
25545
25408
|
const newArray = new PdfArray([qStream]);
|
|
25546
25409
|
for (let i = 0; i < existingContents.length; i++) {
|
|
25547
25410
|
const item = existingContents.at(i);
|
|
@@ -25550,18 +25413,20 @@ var PDFPage = class PDFPage {
|
|
|
25550
25413
|
newArray.push(QStream);
|
|
25551
25414
|
newArray.push(newContent);
|
|
25552
25415
|
this.dict.set("Contents", newArray);
|
|
25416
|
+
return;
|
|
25553
25417
|
}
|
|
25554
|
-
} else {
|
|
25555
|
-
const contents = this.dict.get("Contents");
|
|
25556
|
-
if (contents instanceof PdfArray) contents.push(newContent);
|
|
25557
|
-
else if (contents !== void 0) this.dict.set("Contents", new PdfArray([contents, newContent]));
|
|
25558
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]));
|
|
25559
25424
|
}
|
|
25560
25425
|
/**
|
|
25561
25426
|
* Get a box (MediaBox, CropBox, etc.) from the page dictionary.
|
|
25562
25427
|
*/
|
|
25563
25428
|
getBox(name) {
|
|
25564
|
-
const box = this.dict.get(name);
|
|
25429
|
+
const box = this.dict.get(name, this.ctx.resolve.bind(this.ctx));
|
|
25565
25430
|
if (!(box instanceof PdfArray) || box.length < 4) return null;
|
|
25566
25431
|
const x1 = box.at(0);
|
|
25567
25432
|
const y1 = box.at(1);
|
|
@@ -25598,7 +25463,7 @@ var PDFPage = class PDFPage {
|
|
|
25598
25463
|
*/
|
|
25599
25464
|
addFontResource(font) {
|
|
25600
25465
|
const resources = this.getResources();
|
|
25601
|
-
let fonts = resources.get("Font");
|
|
25466
|
+
let fonts = resources.get("Font", this.ctx.resolve.bind(this.ctx));
|
|
25602
25467
|
if (!(fonts instanceof PdfDict)) {
|
|
25603
25468
|
fonts = new PdfDict();
|
|
25604
25469
|
resources.set("Font", fonts);
|
|
@@ -25606,7 +25471,7 @@ var PDFPage = class PDFPage {
|
|
|
25606
25471
|
if (typeof font === "string") {
|
|
25607
25472
|
if (!isStandard14Font(font)) throw new Error(`Unknown Standard 14 font: ${font}`);
|
|
25608
25473
|
for (const [existingName, value] of fonts) if (value instanceof PdfDict) {
|
|
25609
|
-
const baseFont = value.get("BaseFont");
|
|
25474
|
+
const baseFont = value.get("BaseFont", this.ctx.resolve.bind(this.ctx));
|
|
25610
25475
|
if (baseFont instanceof PdfName && baseFont.value === font) return existingName.value;
|
|
25611
25476
|
}
|
|
25612
25477
|
const fontDict = PdfDict.of({
|
|
@@ -25699,21 +25564,14 @@ var PDFPage = class PDFPage {
|
|
|
25699
25564
|
* Get the concatenated content stream bytes.
|
|
25700
25565
|
*/
|
|
25701
25566
|
getContentBytes() {
|
|
25702
|
-
const contents = this.dict.get("Contents");
|
|
25567
|
+
const contents = this.dict.get("Contents", this.ctx.resolve.bind(this.ctx));
|
|
25703
25568
|
if (!contents) return new Uint8Array(0);
|
|
25704
|
-
if (contents instanceof PdfRef && this.ctx) {
|
|
25705
|
-
const stream = this.ctx.resolve(contents);
|
|
25706
|
-
if (stream instanceof PdfStream) return stream.getDecodedData();
|
|
25707
|
-
}
|
|
25708
25569
|
if (contents instanceof PdfStream) return contents.getDecodedData();
|
|
25709
25570
|
if (contents instanceof PdfArray) {
|
|
25710
25571
|
const chunks = [];
|
|
25711
25572
|
for (let i = 0; i < contents.length; i++) {
|
|
25712
|
-
const item = contents.at(i);
|
|
25713
|
-
if (item instanceof
|
|
25714
|
-
const stream = this.ctx.resolve(item);
|
|
25715
|
-
if (stream instanceof PdfStream) chunks.push(stream.getDecodedData());
|
|
25716
|
-
} 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());
|
|
25717
25575
|
}
|
|
25718
25576
|
return this.concatenateChunks(chunks);
|
|
25719
25577
|
}
|
|
@@ -25744,17 +25602,11 @@ var PDFPage = class PDFPage {
|
|
|
25744
25602
|
resolveInheritedResources() {
|
|
25745
25603
|
let currentDict = this.dict;
|
|
25746
25604
|
while (currentDict) {
|
|
25747
|
-
const
|
|
25748
|
-
if (
|
|
25749
|
-
|
|
25750
|
-
|
|
25751
|
-
|
|
25752
|
-
const parentEntry = currentDict.get("Parent");
|
|
25753
|
-
if (parentEntry instanceof PdfRef) {
|
|
25754
|
-
const parent = this.ctx.resolve(parentEntry);
|
|
25755
|
-
if (parent instanceof PdfDict) currentDict = parent;
|
|
25756
|
-
else break;
|
|
25757
|
-
} 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;
|
|
25758
25610
|
}
|
|
25759
25611
|
return null;
|
|
25760
25612
|
}
|
|
@@ -25764,81 +25616,22 @@ var PDFPage = class PDFPage {
|
|
|
25764
25616
|
createFontResolver() {
|
|
25765
25617
|
const resourcesDict = this.resolveInheritedResources();
|
|
25766
25618
|
if (!resourcesDict) return () => null;
|
|
25767
|
-
|
|
25768
|
-
|
|
25769
|
-
if (fontEntry instanceof PdfRef && this.ctx) {
|
|
25770
|
-
const resolved = this.ctx.resolve(fontEntry);
|
|
25771
|
-
if (resolved instanceof PdfDict) fontDict = resolved;
|
|
25772
|
-
} else if (fontEntry instanceof PdfDict) fontDict = fontEntry;
|
|
25773
|
-
if (!fontDict) return () => null;
|
|
25619
|
+
const font = resourcesDict.getDict("Font", this.ctx.resolve.bind(this.ctx));
|
|
25620
|
+
if (!font) return () => null;
|
|
25774
25621
|
const fontCache = /* @__PURE__ */ new Map();
|
|
25775
|
-
for (const [
|
|
25776
|
-
const name =
|
|
25777
|
-
|
|
25778
|
-
|
|
25779
|
-
|
|
25780
|
-
if (resolved instanceof PdfDict) fontDictEntry = resolved;
|
|
25781
|
-
} else if (fontEntry$1 instanceof PdfDict) fontDictEntry = fontEntry$1;
|
|
25782
|
-
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;
|
|
25783
25627
|
let toUnicodeMap = null;
|
|
25784
|
-
const
|
|
25785
|
-
|
|
25786
|
-
|
|
25787
|
-
|
|
25788
|
-
|
|
25789
|
-
|
|
25790
|
-
|
|
25791
|
-
if (toUnicodeStream) try {
|
|
25792
|
-
toUnicodeMap = parseToUnicode(toUnicodeStream.getDecodedData());
|
|
25793
|
-
} catch {}
|
|
25794
|
-
}
|
|
25795
|
-
const resolvedRefs = /* @__PURE__ */ new Map();
|
|
25796
|
-
const decodedStreams = /* @__PURE__ */ new Map();
|
|
25797
|
-
const preResolveValue = (value) => {
|
|
25798
|
-
if (value instanceof PdfRef) {
|
|
25799
|
-
const key$1 = `${value.objectNumber} ${value.generation} R`;
|
|
25800
|
-
if (resolvedRefs.has(key$1)) return;
|
|
25801
|
-
const resolved = this.ctx.resolve(value);
|
|
25802
|
-
if (resolved instanceof PdfDict || resolved instanceof PdfArray || resolved instanceof PdfStream) {
|
|
25803
|
-
resolvedRefs.set(key$1, resolved);
|
|
25804
|
-
if (resolved instanceof PdfStream) try {
|
|
25805
|
-
const decoded = resolved.getDecodedData();
|
|
25806
|
-
decodedStreams.set(key$1, decoded);
|
|
25807
|
-
} catch {}
|
|
25808
|
-
preResolveValue(resolved);
|
|
25809
|
-
}
|
|
25810
|
-
} else if (value instanceof PdfDict) for (const [, v] of value) preResolveValue(v);
|
|
25811
|
-
else if (value instanceof PdfArray) for (let i = 0; i < value.length; i++) preResolveValue(value.at(i));
|
|
25812
|
-
};
|
|
25813
|
-
preResolveValue(fontDictEntry.get("DescendantFonts"));
|
|
25814
|
-
preResolveValue(fontDictEntry.get("FontDescriptor"));
|
|
25815
|
-
preResolveValue(fontDictEntry.get("Encoding"));
|
|
25816
|
-
preResolveValue(fontDictEntry.get("Widths"));
|
|
25817
|
-
const pdfFont = parseFont(fontDictEntry, {
|
|
25818
|
-
resolveRef: (ref) => {
|
|
25819
|
-
if (ref instanceof PdfRef && this.ctx) {
|
|
25820
|
-
const obj = this.ctx.resolve(ref);
|
|
25821
|
-
if (obj instanceof PdfDict || obj instanceof PdfArray || obj instanceof PdfStream) return obj;
|
|
25822
|
-
}
|
|
25823
|
-
return null;
|
|
25824
|
-
},
|
|
25825
|
-
decodeStream: (stream) => {
|
|
25826
|
-
if (stream instanceof PdfRef) {
|
|
25827
|
-
const key$1 = `${stream.objectNumber} ${stream.generation} R`;
|
|
25828
|
-
const decoded = decodedStreams.get(key$1);
|
|
25829
|
-
if (decoded) return decoded;
|
|
25830
|
-
const preResolved = resolvedRefs.get(key$1);
|
|
25831
|
-
if (preResolved instanceof PdfStream) return preResolved.data;
|
|
25832
|
-
}
|
|
25833
|
-
if (stream instanceof PdfStream) {
|
|
25834
|
-
for (const [key$1, resolved] of resolvedRefs) if (resolved === stream) {
|
|
25835
|
-
const decoded = decodedStreams.get(key$1);
|
|
25836
|
-
if (decoded) return decoded;
|
|
25837
|
-
}
|
|
25838
|
-
return stream.data;
|
|
25839
|
-
}
|
|
25840
|
-
return null;
|
|
25841
|
-
},
|
|
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),
|
|
25842
25635
|
toUnicodeMap
|
|
25843
25636
|
});
|
|
25844
25637
|
fontCache.set(name, pdfFont);
|
|
@@ -25939,9 +25732,9 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
|
|
|
25939
25732
|
* Get the URI if this is an external link.
|
|
25940
25733
|
*/
|
|
25941
25734
|
get uri() {
|
|
25942
|
-
const action = this.dict.getDict("A");
|
|
25735
|
+
const action = this.dict.getDict("A", this.registry.resolve.bind(this.registry));
|
|
25943
25736
|
if (action) {
|
|
25944
|
-
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;
|
|
25945
25738
|
}
|
|
25946
25739
|
return null;
|
|
25947
25740
|
}
|
|
@@ -25949,12 +25742,12 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
|
|
|
25949
25742
|
* Get the destination if this is an internal link.
|
|
25950
25743
|
*/
|
|
25951
25744
|
get destination() {
|
|
25952
|
-
const dest = this.dict.get("Dest");
|
|
25745
|
+
const dest = this.dict.get("Dest", this.registry.resolve.bind(this.registry));
|
|
25953
25746
|
if (dest) return this.parseDestination(dest);
|
|
25954
|
-
const action = this.dict.getDict("A");
|
|
25747
|
+
const action = this.dict.getDict("A", this.registry.resolve.bind(this.registry));
|
|
25955
25748
|
if (action) {
|
|
25956
|
-
if (action.getName("S")?.value === "GoTo") {
|
|
25957
|
-
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));
|
|
25958
25751
|
if (d) return this.parseDestination(d);
|
|
25959
25752
|
}
|
|
25960
25753
|
}
|
|
@@ -25974,12 +25767,12 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
|
|
|
25974
25767
|
type: "goto",
|
|
25975
25768
|
destination: dest
|
|
25976
25769
|
};
|
|
25977
|
-
const action = this.dict.getDict("A");
|
|
25770
|
+
const action = this.dict.getDict("A", this.registry.resolve.bind(this.registry));
|
|
25978
25771
|
if (action) {
|
|
25979
|
-
const actionType = action.getName("S")?.value;
|
|
25772
|
+
const actionType = action.getName("S", this.registry.resolve.bind(this.registry))?.value;
|
|
25980
25773
|
if (actionType === "GoToR") {
|
|
25981
|
-
const file = action.getString("F")?.asString() ?? "";
|
|
25982
|
-
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));
|
|
25983
25776
|
return {
|
|
25984
25777
|
type: "gotoRemote",
|
|
25985
25778
|
file,
|
|
@@ -25994,7 +25787,7 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
|
|
|
25994
25787
|
* Highlight mode when the link is clicked.
|
|
25995
25788
|
*/
|
|
25996
25789
|
get highlightMode() {
|
|
25997
|
-
switch (this.dict.getName("H")?.value) {
|
|
25790
|
+
switch (this.dict.getName("H", this.registry.resolve.bind(this.registry))?.value) {
|
|
25998
25791
|
case "N": return "None";
|
|
25999
25792
|
case "I": return "Invert";
|
|
26000
25793
|
case "O": return "Outline";
|
|
@@ -26183,7 +25976,7 @@ var PDFUnknownAnnotation = class extends PDFAnnotation {};
|
|
|
26183
25976
|
* @returns The appropriate annotation class instance
|
|
26184
25977
|
*/
|
|
26185
25978
|
function createAnnotation(dict, ref, registry) {
|
|
26186
|
-
const subtypeName = dict.getName("Subtype")?.value;
|
|
25979
|
+
const subtypeName = dict.getName("Subtype", registry.resolve.bind(registry))?.value;
|
|
26187
25980
|
switch (isAnnotationSubtype(subtypeName) ? subtypeName : "Text") {
|
|
26188
25981
|
case "Text": return new PDFTextAnnotation(dict, ref, registry);
|
|
26189
25982
|
case "Link": return new PDFLinkAnnotation(dict, ref, registry);
|
|
@@ -26209,14 +26002,14 @@ function createAnnotation(dict, ref, registry) {
|
|
|
26209
26002
|
/**
|
|
26210
26003
|
* Check if an annotation is a Widget (form field).
|
|
26211
26004
|
*/
|
|
26212
|
-
function isWidgetAnnotation(dict) {
|
|
26213
|
-
return dict.getName("Subtype")?.value === "Widget";
|
|
26005
|
+
function isWidgetAnnotation(dict, registry) {
|
|
26006
|
+
return dict.getName("Subtype", registry?.resolve.bind(registry))?.value === "Widget";
|
|
26214
26007
|
}
|
|
26215
26008
|
/**
|
|
26216
26009
|
* Check if an annotation is a Popup.
|
|
26217
26010
|
*/
|
|
26218
|
-
function isPopupAnnotation(dict) {
|
|
26219
|
-
return dict.getName("Subtype")?.value === "Popup";
|
|
26011
|
+
function isPopupAnnotation(dict, registry) {
|
|
26012
|
+
return dict.getName("Subtype", registry?.resolve.bind(registry))?.value === "Popup";
|
|
26220
26013
|
}
|
|
26221
26014
|
|
|
26222
26015
|
//#endregion
|
|
@@ -26264,19 +26057,14 @@ var AnnotationFlattener = class {
|
|
|
26264
26057
|
* @returns Number of annotations flattened
|
|
26265
26058
|
*/
|
|
26266
26059
|
flattenPage(pageDict, options = {}) {
|
|
26267
|
-
let
|
|
26268
|
-
if (!annotsEntry) return 0;
|
|
26269
|
-
if (annotsEntry instanceof PdfRef) annotsEntry = this.registry.resolve(annotsEntry) ?? void 0;
|
|
26270
|
-
let annots = annotsEntry instanceof PdfArray ? annotsEntry : null;
|
|
26060
|
+
let annots = pageDict.getArray("Annots", this.registry.resolve.bind(this.registry));
|
|
26271
26061
|
if (!annots || annots.length === 0) return 0;
|
|
26272
|
-
let resources = pageDict.get("Resources");
|
|
26273
|
-
if (resources instanceof PdfRef) resources = this.registry.resolve(resources) ?? void 0;
|
|
26062
|
+
let resources = pageDict.get("Resources", this.registry.resolve.bind(this.registry));
|
|
26274
26063
|
if (!(resources instanceof PdfDict)) {
|
|
26275
26064
|
resources = new PdfDict();
|
|
26276
26065
|
pageDict.set("Resources", resources);
|
|
26277
26066
|
}
|
|
26278
|
-
let xObjects = resources.get("XObject");
|
|
26279
|
-
if (xObjects instanceof PdfRef) xObjects = this.registry.resolve(xObjects) ?? void 0;
|
|
26067
|
+
let xObjects = resources.get("XObject", this.registry.resolve.bind(this.registry));
|
|
26280
26068
|
if (!(xObjects instanceof PdfDict)) {
|
|
26281
26069
|
xObjects = new PdfDict();
|
|
26282
26070
|
resources.set("XObject", xObjects);
|
|
@@ -26286,19 +26074,20 @@ var AnnotationFlattener = class {
|
|
|
26286
26074
|
let xObjectIndex = 0;
|
|
26287
26075
|
let flattenedCount = 0;
|
|
26288
26076
|
for (let i = 0; i < annots.length; i++) {
|
|
26289
|
-
|
|
26077
|
+
let entry = annots.at(i);
|
|
26290
26078
|
if (!entry) continue;
|
|
26291
26079
|
let annotDict = null;
|
|
26292
26080
|
let annotRef = null;
|
|
26293
26081
|
if (entry instanceof PdfRef) {
|
|
26294
26082
|
annotRef = entry;
|
|
26295
|
-
|
|
26296
|
-
|
|
26297
|
-
|
|
26083
|
+
entry = this.registry.resolve(entry) ?? void 0;
|
|
26084
|
+
}
|
|
26085
|
+
if (entry instanceof PdfDict) annotDict = entry;
|
|
26298
26086
|
if (!annotDict) continue;
|
|
26299
26087
|
if (isWidgetAnnotation(annotDict)) continue;
|
|
26300
26088
|
if (isPopupAnnotation(annotDict)) continue;
|
|
26301
|
-
const
|
|
26089
|
+
const subtypeName = annotDict.getName("Subtype")?.value;
|
|
26090
|
+
const subtype = isAnnotationSubtype(subtypeName) ? subtypeName : null;
|
|
26302
26091
|
if (!subtype) continue;
|
|
26303
26092
|
if (subtype === "Link") {
|
|
26304
26093
|
if (options.removeLinks) {
|
|
@@ -26407,9 +26196,7 @@ var AnnotationFlattener = class {
|
|
|
26407
26196
|
* Get annotation rectangle as [x1, y1, x2, y2].
|
|
26408
26197
|
*/
|
|
26409
26198
|
getAnnotationRect(annotDict) {
|
|
26410
|
-
|
|
26411
|
-
if (rectArray instanceof PdfRef) rectArray = this.registry.resolve(rectArray) ?? void 0;
|
|
26412
|
-
let rect = rectArray instanceof PdfArray ? rectArray : null;
|
|
26199
|
+
const rect = annotDict.getArray("Rect", this.registry.resolve.bind(this.registry));
|
|
26413
26200
|
if (!rect || rect.length < 4) return [
|
|
26414
26201
|
0,
|
|
26415
26202
|
0,
|
|
@@ -26471,7 +26258,7 @@ var AnnotationFlattener = class {
|
|
|
26471
26258
|
* Get appearance BBox, with fallback.
|
|
26472
26259
|
*/
|
|
26473
26260
|
getAppearanceBBox(appearance) {
|
|
26474
|
-
const bbox = appearance.getArray("BBox");
|
|
26261
|
+
const bbox = appearance.getArray("BBox", this.registry.resolve.bind(this.registry));
|
|
26475
26262
|
if (!bbox || bbox.length < 4) return [
|
|
26476
26263
|
0,
|
|
26477
26264
|
0,
|
|
@@ -26490,7 +26277,7 @@ var AnnotationFlattener = class {
|
|
|
26490
26277
|
* Get the appearance stream's transformation matrix.
|
|
26491
26278
|
*/
|
|
26492
26279
|
getAppearanceMatrix(appearance) {
|
|
26493
|
-
const matrixArray = appearance.getArray("Matrix");
|
|
26280
|
+
const matrixArray = appearance.getArray("Matrix", this.registry.resolve.bind(this.registry));
|
|
26494
26281
|
if (!matrixArray || matrixArray.length < 6) return Matrix.identity();
|
|
26495
26282
|
const [a, b, c, d, e, f] = matrixArray.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
|
|
26496
26283
|
return new Matrix(a ?? 0, b ?? 0, c ?? 0, d ?? 0, e ?? 0, f ?? 0);
|
|
@@ -26499,7 +26286,7 @@ var AnnotationFlattener = class {
|
|
|
26499
26286
|
* Check if appearance stream has valid dimensions.
|
|
26500
26287
|
*/
|
|
26501
26288
|
isVisibleAppearance(appearance) {
|
|
26502
|
-
const bbox = appearance.getArray("BBox");
|
|
26289
|
+
const bbox = appearance.getArray("BBox", this.registry.resolve.bind(this.registry));
|
|
26503
26290
|
if (!bbox || bbox.length < 4) return false;
|
|
26504
26291
|
const [x1, y1, x2, y2] = bbox.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
|
|
26505
26292
|
const width = Math.abs((x2 ?? 0) - (x1 ?? 0));
|
|
@@ -26515,6 +26302,8 @@ var AnnotationFlattener = class {
|
|
|
26515
26302
|
}
|
|
26516
26303
|
/**
|
|
26517
26304
|
* Wrap existing page content in q...Q and append new content.
|
|
26305
|
+
*
|
|
26306
|
+
* @todo Consider using PDFPage API for this.
|
|
26518
26307
|
*/
|
|
26519
26308
|
wrapAndAppendContent(page, newContent) {
|
|
26520
26309
|
const existing = page.get("Contents");
|
|
@@ -26563,7 +26352,8 @@ var AnnotationFlattener = class {
|
|
|
26563
26352
|
if (annotsEntry instanceof PdfRef) {
|
|
26564
26353
|
const resolved = this.registry.resolve(annotsEntry);
|
|
26565
26354
|
annots = resolved instanceof PdfArray ? resolved : void 0;
|
|
26566
|
-
}
|
|
26355
|
+
}
|
|
26356
|
+
if (annotsEntry instanceof PdfArray) annots = annotsEntry;
|
|
26567
26357
|
if (!annots) return;
|
|
26568
26358
|
const indicesToRemove = [];
|
|
26569
26359
|
for (let i = 0; i < annots.length; i++) {
|
|
@@ -27745,17 +27535,10 @@ function parseDefaultConfig(dDict, resolve) {
|
|
|
27745
27535
|
function hasLayers(ctx) {
|
|
27746
27536
|
const catalog = ctx.catalog.getDict();
|
|
27747
27537
|
if (!catalog) return false;
|
|
27748
|
-
|
|
27749
|
-
|
|
27750
|
-
let ocPropsDict = null;
|
|
27751
|
-
if (ocProperties instanceof PdfRef) ocProperties = ctx.resolve(ocProperties) ?? void 0;
|
|
27752
|
-
if (ocProperties instanceof PdfDict) ocPropsDict = ocProperties;
|
|
27538
|
+
const resolve = ctx.resolve.bind(ctx);
|
|
27539
|
+
const ocPropsDict = catalog.getDict("OCProperties", resolve);
|
|
27753
27540
|
if (!ocPropsDict) return false;
|
|
27754
|
-
|
|
27755
|
-
if (!ocgs) return false;
|
|
27756
|
-
let ocgsArray = null;
|
|
27757
|
-
if (ocgs instanceof PdfRef) ocgs = ctx.resolve(ocgs) ?? void 0;
|
|
27758
|
-
if (ocgs instanceof PdfArray) ocgsArray = ocgs;
|
|
27541
|
+
const ocgsArray = ocPropsDict.getArray("OCGs", resolve);
|
|
27759
27542
|
if (!ocgsArray || ocgsArray.length === 0) return false;
|
|
27760
27543
|
return true;
|
|
27761
27544
|
}
|
|
@@ -27768,19 +27551,12 @@ function hasLayers(ctx) {
|
|
|
27768
27551
|
function getLayers(ctx) {
|
|
27769
27552
|
const catalog = ctx.catalog.getDict();
|
|
27770
27553
|
if (!catalog) return [];
|
|
27771
|
-
|
|
27772
|
-
|
|
27773
|
-
let ocPropsDict = null;
|
|
27774
|
-
if (ocProperties instanceof PdfRef) ocProperties = ctx.resolve(ocProperties) ?? void 0;
|
|
27775
|
-
if (ocProperties instanceof PdfDict) ocPropsDict = ocProperties;
|
|
27554
|
+
const resolve = ctx.resolve.bind(ctx);
|
|
27555
|
+
const ocPropsDict = catalog.getDict("OCProperties", resolve);
|
|
27776
27556
|
if (!ocPropsDict) return [];
|
|
27777
|
-
|
|
27778
|
-
if (!ocgs) return [];
|
|
27779
|
-
let ocgsArray = null;
|
|
27780
|
-
if (ocgs instanceof PdfRef) ocgs = ctx.resolve(ocgs) ?? void 0;
|
|
27781
|
-
if (ocgs instanceof PdfArray) ocgsArray = ocgs;
|
|
27557
|
+
const ocgsArray = ocPropsDict.getArray("OCGs", resolve);
|
|
27782
27558
|
if (!ocgsArray) return [];
|
|
27783
|
-
const defaultConfig = parseDefaultConfig(ocPropsDict.get("D"),
|
|
27559
|
+
const defaultConfig = parseDefaultConfig(ocPropsDict.get("D"), resolve);
|
|
27784
27560
|
const layers = [];
|
|
27785
27561
|
for (const item of ocgsArray) {
|
|
27786
27562
|
if (!(item instanceof PdfRef)) continue;
|
|
@@ -30834,22 +30610,36 @@ var DocumentParser = class {
|
|
|
30834
30610
|
else throw error;
|
|
30835
30611
|
}
|
|
30836
30612
|
const lengthResolver = (ref) => {
|
|
30837
|
-
const
|
|
30838
|
-
const cached = cache.get(
|
|
30839
|
-
if (cached
|
|
30613
|
+
const cacheKey = `${ref.objectNumber} ${ref.generation}`;
|
|
30614
|
+
const cached = cache.get(cacheKey);
|
|
30615
|
+
if (cached instanceof PdfNumber) return cached.value;
|
|
30840
30616
|
const entry = xref.get(ref.objectNumber);
|
|
30841
|
-
if (entry
|
|
30842
|
-
|
|
30843
|
-
|
|
30844
|
-
|
|
30845
|
-
|
|
30846
|
-
|
|
30847
|
-
|
|
30848
|
-
|
|
30617
|
+
if (!entry || entry.type === "free") return null;
|
|
30618
|
+
const savedPosition = this.scanner.position;
|
|
30619
|
+
try {
|
|
30620
|
+
let lengthObj = null;
|
|
30621
|
+
if (entry.type === "uncompressed") lengthObj = new IndirectObjectParser(this.scanner).parseObjectAt(entry.offset).value;
|
|
30622
|
+
else {
|
|
30623
|
+
const streamEntry = xref.get(entry.streamObjNum);
|
|
30624
|
+
if (streamEntry?.type === "uncompressed") {
|
|
30625
|
+
let objStreamParser = objectStreamCache.get(entry.streamObjNum);
|
|
30626
|
+
if (!objStreamParser) {
|
|
30627
|
+
const streamResult = new IndirectObjectParser(this.scanner).parseObjectAt(streamEntry.offset);
|
|
30628
|
+
if (streamResult.value instanceof PdfStream) {
|
|
30629
|
+
objStreamParser = new ObjectStreamParser(streamResult.value);
|
|
30630
|
+
objectStreamCache.set(entry.streamObjNum, objStreamParser);
|
|
30631
|
+
}
|
|
30632
|
+
}
|
|
30633
|
+
if (objStreamParser) lengthObj = objStreamParser.getObject(entry.indexInStream);
|
|
30849
30634
|
}
|
|
30850
|
-
} catch {
|
|
30851
|
-
this.scanner.moveTo(savedPosition);
|
|
30852
30635
|
}
|
|
30636
|
+
this.scanner.moveTo(savedPosition);
|
|
30637
|
+
if (lengthObj instanceof PdfNumber) {
|
|
30638
|
+
cache.set(cacheKey, lengthObj);
|
|
30639
|
+
return lengthObj.value;
|
|
30640
|
+
}
|
|
30641
|
+
} catch {
|
|
30642
|
+
this.scanner.moveTo(savedPosition);
|
|
30853
30643
|
}
|
|
30854
30644
|
return null;
|
|
30855
30645
|
};
|
|
@@ -30944,7 +30734,7 @@ var DocumentParser = class {
|
|
|
30944
30734
|
if (type?.value === "Page") {
|
|
30945
30735
|
if (currentRef) pages.push(currentRef);
|
|
30946
30736
|
} else if (type?.value === "Pages") {
|
|
30947
|
-
const kids = nodeOrRef.getArray("Kids");
|
|
30737
|
+
const kids = nodeOrRef.getArray("Kids", getObject);
|
|
30948
30738
|
if (kids) for (let i = 0; i < kids.length; i++) {
|
|
30949
30739
|
const kid = kids.at(i);
|
|
30950
30740
|
if (kid instanceof PdfRef) walkNode(kid);
|
|
@@ -31733,12 +31523,7 @@ function decodeFilename(str) {
|
|
|
31733
31523
|
* @returns The stream if found, null if external reference or missing
|
|
31734
31524
|
*/
|
|
31735
31525
|
function getEmbeddedFileStream(fileSpec, resolver) {
|
|
31736
|
-
const
|
|
31737
|
-
let ef = null;
|
|
31738
|
-
if (efEntry instanceof PdfRef) {
|
|
31739
|
-
const resolved = resolver(efEntry);
|
|
31740
|
-
if (resolved instanceof PdfDict) ef = resolved;
|
|
31741
|
-
} else if (efEntry instanceof PdfDict) ef = efEntry;
|
|
31526
|
+
const ef = fileSpec.getDict("EF", resolver);
|
|
31742
31527
|
if (!ef) return null;
|
|
31743
31528
|
const streamRef = ef.getRef("F") ?? ef.getRef("UF");
|
|
31744
31529
|
if (!streamRef) return null;
|
|
@@ -31765,12 +31550,7 @@ function parseFileSpec(fileSpec, name, resolver) {
|
|
|
31765
31550
|
if (desc) info.description = desc.asString();
|
|
31766
31551
|
const subtype = stream.getName("Subtype");
|
|
31767
31552
|
if (subtype) info.mimeType = subtype.value.replaceAll("#2F", "/").replaceAll("#20", " ");
|
|
31768
|
-
const
|
|
31769
|
-
let params = null;
|
|
31770
|
-
if (paramsEntry instanceof PdfRef) {
|
|
31771
|
-
const resolved = resolver(paramsEntry);
|
|
31772
|
-
if (resolved instanceof PdfDict) params = resolved;
|
|
31773
|
-
} else if (paramsEntry instanceof PdfDict) params = paramsEntry;
|
|
31553
|
+
const params = stream.getDict("Params", resolver);
|
|
31774
31554
|
if (params) {
|
|
31775
31555
|
const size = params.getNumber("Size");
|
|
31776
31556
|
if (size) info.size = size.value;
|
|
@@ -31881,12 +31661,7 @@ var NameTree = class {
|
|
|
31881
31661
|
let found = false;
|
|
31882
31662
|
while (lo$1 <= hi$1) {
|
|
31883
31663
|
const mid = lo$1 + hi$1 >>> 1;
|
|
31884
|
-
const
|
|
31885
|
-
if (!(kidRef instanceof PdfRef)) {
|
|
31886
|
-
lo$1 = mid + 1;
|
|
31887
|
-
continue;
|
|
31888
|
-
}
|
|
31889
|
-
const kid = this.resolver(kidRef);
|
|
31664
|
+
const kid = kids.at(mid, this.resolver);
|
|
31890
31665
|
if (!(kid instanceof PdfDict)) {
|
|
31891
31666
|
lo$1 = mid + 1;
|
|
31892
31667
|
continue;
|
|
@@ -31929,16 +31704,10 @@ var NameTree = class {
|
|
|
31929
31704
|
else if (cmp > 0) lo = mid + 1;
|
|
31930
31705
|
else {
|
|
31931
31706
|
const valueIndex = keyIndex + 1;
|
|
31932
|
-
|
|
31933
|
-
if (value instanceof PdfRef) return this.resolver(value);
|
|
31934
|
-
return value ?? null;
|
|
31707
|
+
return names.at(valueIndex, this.resolver) ?? null;
|
|
31935
31708
|
}
|
|
31936
31709
|
}
|
|
31937
|
-
for (let i = 0; i < names.length; i += 2) if (extractKey(names.at(i)) === key$1)
|
|
31938
|
-
const value = names.at(i + 1);
|
|
31939
|
-
if (value instanceof PdfRef) return this.resolver(value);
|
|
31940
|
-
return value ?? null;
|
|
31941
|
-
}
|
|
31710
|
+
for (let i = 0; i < names.length; i += 2) if (extractKey(names.at(i)) === key$1) return names.at(i + 1, this.resolver) ?? null;
|
|
31942
31711
|
return null;
|
|
31943
31712
|
}
|
|
31944
31713
|
/**
|
|
@@ -31965,15 +31734,17 @@ var NameTree = class {
|
|
|
31965
31734
|
}
|
|
31966
31735
|
if (node.has("Kids")) {
|
|
31967
31736
|
const kids = node.getArray("Kids");
|
|
31968
|
-
if (kids) for (
|
|
31969
|
-
|
|
31970
|
-
|
|
31971
|
-
|
|
31972
|
-
|
|
31973
|
-
|
|
31737
|
+
if (kids) for (let i = 0; i < kids.length; i++) {
|
|
31738
|
+
const kidRef = kids.at(i);
|
|
31739
|
+
if (kidRef instanceof PdfRef) {
|
|
31740
|
+
const refKey$1 = `${kidRef.objectNumber}:${kidRef.generation}`;
|
|
31741
|
+
if (visited.has(refKey$1)) {
|
|
31742
|
+
console.warn(`NameTree: circular reference detected at ${refKey$1}`);
|
|
31743
|
+
continue;
|
|
31744
|
+
}
|
|
31745
|
+
visited.add(refKey$1);
|
|
31974
31746
|
}
|
|
31975
|
-
|
|
31976
|
-
const kid = this.resolver(kidRef);
|
|
31747
|
+
const kid = kids.at(i, this.resolver);
|
|
31977
31748
|
if (kid instanceof PdfDict) queue.push({
|
|
31978
31749
|
node: kid,
|
|
31979
31750
|
depth: depth + 1
|
|
@@ -31984,9 +31755,8 @@ var NameTree = class {
|
|
|
31984
31755
|
if (names) for (let i = 0; i < names.length; i += 2) {
|
|
31985
31756
|
const key$1 = extractKey(names.at(i));
|
|
31986
31757
|
if (key$1 === null) continue;
|
|
31987
|
-
|
|
31988
|
-
if (value
|
|
31989
|
-
if (value !== null && value !== void 0) yield [key$1, value];
|
|
31758
|
+
const value = names.at(i + 1, this.resolver);
|
|
31759
|
+
if (value !== void 0) yield [key$1, value];
|
|
31990
31760
|
}
|
|
31991
31761
|
}
|
|
31992
31762
|
}
|
|
@@ -32253,9 +32023,7 @@ var PDFCatalog = class {
|
|
|
32253
32023
|
* Get the /Names dictionary.
|
|
32254
32024
|
*/
|
|
32255
32025
|
getNames() {
|
|
32256
|
-
|
|
32257
|
-
if (namesEntry instanceof PdfRef) namesEntry = this.registry.resolve(namesEntry) ?? void 0;
|
|
32258
|
-
return namesEntry instanceof PdfDict ? namesEntry : null;
|
|
32026
|
+
return this.dict.getDict("Names", this.registry.resolve.bind(this.registry)) ?? null;
|
|
32259
32027
|
}
|
|
32260
32028
|
/**
|
|
32261
32029
|
* Get or create the /Names dictionary.
|
|
@@ -32279,12 +32047,7 @@ var PDFCatalog = class {
|
|
|
32279
32047
|
this._embeddedFilesTree = null;
|
|
32280
32048
|
return null;
|
|
32281
32049
|
}
|
|
32282
|
-
const
|
|
32283
|
-
let embeddedFiles = null;
|
|
32284
|
-
if (embeddedFilesEntry instanceof PdfRef) {
|
|
32285
|
-
const resolved = this.registry.resolve(embeddedFilesEntry);
|
|
32286
|
-
if (resolved instanceof PdfDict) embeddedFiles = resolved;
|
|
32287
|
-
} else if (embeddedFilesEntry instanceof PdfDict) embeddedFiles = embeddedFilesEntry;
|
|
32050
|
+
const embeddedFiles = names.getDict("EmbeddedFiles", this.registry.resolve.bind(this.registry));
|
|
32288
32051
|
if (!embeddedFiles) {
|
|
32289
32052
|
this._embeddedFilesTree = null;
|
|
32290
32053
|
return null;
|
|
@@ -34978,14 +34741,7 @@ var PDFForm = class PDFForm {
|
|
|
34978
34741
|
for (const pageRef of pageRefs) {
|
|
34979
34742
|
const pageDict = this._ctx.registry.resolve(pageRef);
|
|
34980
34743
|
if (!(pageDict instanceof PdfDict)) continue;
|
|
34981
|
-
const
|
|
34982
|
-
if (!annotsEntry) continue;
|
|
34983
|
-
let annots = null;
|
|
34984
|
-
if (annotsEntry instanceof PdfArray) annots = annotsEntry;
|
|
34985
|
-
else if (annotsEntry instanceof PdfRef) {
|
|
34986
|
-
const resolved = this._ctx.registry.resolve(annotsEntry);
|
|
34987
|
-
if (resolved instanceof PdfArray) annots = resolved;
|
|
34988
|
-
}
|
|
34744
|
+
const annots = pageDict.getArray("Annots", this._ctx.registry.resolve.bind(this._ctx.registry));
|
|
34989
34745
|
if (!annots) continue;
|
|
34990
34746
|
for (let i = annots.length - 1; i >= 0; i--) {
|
|
34991
34747
|
const item = annots.at(i);
|
|
@@ -35946,49 +35702,28 @@ var DSSBuilder = class DSSBuilder {
|
|
|
35946
35702
|
*/
|
|
35947
35703
|
static async fromCatalog(catalog, registry, options) {
|
|
35948
35704
|
const builder = new DSSBuilder(registry, options);
|
|
35949
|
-
const
|
|
35950
|
-
|
|
35951
|
-
|
|
35952
|
-
if (dssVal instanceof PdfDict) dss = dssVal;
|
|
35953
|
-
else if (dssVal instanceof PdfRef) {
|
|
35954
|
-
const resolved = registry.resolve(dssVal);
|
|
35955
|
-
if (!(resolved instanceof PdfDict)) return builder;
|
|
35956
|
-
dss = resolved;
|
|
35957
|
-
} else return builder;
|
|
35705
|
+
const resolve = registry.resolve.bind(registry);
|
|
35706
|
+
const dss = catalog.getDict("DSS", resolve);
|
|
35707
|
+
if (!dss) return builder;
|
|
35958
35708
|
await builder.loadExistingData(dss, "Certs", builder.certMap, builder.existingCertRefs);
|
|
35959
35709
|
await builder.loadExistingData(dss, "OCSPs", builder.ocspMap, builder.existingOcspRefs);
|
|
35960
35710
|
await builder.loadExistingData(dss, "CRLs", builder.crlMap, builder.existingCrlRefs);
|
|
35961
|
-
const
|
|
35962
|
-
if (
|
|
35963
|
-
|
|
35964
|
-
|
|
35965
|
-
|
|
35966
|
-
const
|
|
35967
|
-
|
|
35968
|
-
|
|
35969
|
-
|
|
35970
|
-
|
|
35971
|
-
|
|
35972
|
-
|
|
35973
|
-
|
|
35974
|
-
|
|
35975
|
-
|
|
35976
|
-
|
|
35977
|
-
if (!(resolved instanceof PdfDict)) continue;
|
|
35978
|
-
entry = resolved;
|
|
35979
|
-
} else continue;
|
|
35980
|
-
const certHashes = await builder.extractRefHashes(entry, "Cert", builder.certMap);
|
|
35981
|
-
const ocspHashes = await builder.extractRefHashes(entry, "OCSP", builder.ocspMap);
|
|
35982
|
-
const crlHashes = await builder.extractRefHashes(entry, "CRL", builder.crlMap);
|
|
35983
|
-
let timestamp;
|
|
35984
|
-
if (entry.get("TU") instanceof PdfString) timestamp = /* @__PURE__ */ new Date();
|
|
35985
|
-
builder.vriEntries.set(key$1.value.toUpperCase(), {
|
|
35986
|
-
certHashes,
|
|
35987
|
-
ocspHashes,
|
|
35988
|
-
crlHashes,
|
|
35989
|
-
timestamp
|
|
35990
|
-
});
|
|
35991
|
-
}
|
|
35711
|
+
const vri = dss.getDict("VRI", resolve);
|
|
35712
|
+
if (vri) for (const key$1 of vri.keys()) {
|
|
35713
|
+
const entryVal = vri.get(key$1, resolve);
|
|
35714
|
+
const entry = entryVal instanceof PdfDict ? entryVal : null;
|
|
35715
|
+
if (entry) {
|
|
35716
|
+
const certHashes = await builder.extractRefHashes(entry, "Cert", builder.certMap);
|
|
35717
|
+
const ocspHashes = await builder.extractRefHashes(entry, "OCSP", builder.ocspMap);
|
|
35718
|
+
const crlHashes = await builder.extractRefHashes(entry, "CRL", builder.crlMap);
|
|
35719
|
+
let timestamp;
|
|
35720
|
+
if (entry.getString("TU", resolve)) timestamp = /* @__PURE__ */ new Date();
|
|
35721
|
+
builder.vriEntries.set(key$1.value.toUpperCase(), {
|
|
35722
|
+
certHashes,
|
|
35723
|
+
ocspHashes,
|
|
35724
|
+
crlHashes,
|
|
35725
|
+
timestamp
|
|
35726
|
+
});
|
|
35992
35727
|
}
|
|
35993
35728
|
}
|
|
35994
35729
|
return builder;
|
|
@@ -36069,11 +35804,8 @@ var DSSBuilder = class DSSBuilder {
|
|
|
36069
35804
|
* Load existing data from DSS array.
|
|
36070
35805
|
*/
|
|
36071
35806
|
async loadExistingData(dss, key$1, dataMap, refMap) {
|
|
36072
|
-
|
|
36073
|
-
|
|
36074
|
-
let array;
|
|
36075
|
-
if (arrayVal instanceof PdfRef) arrayVal = this.registry.resolve(arrayVal) ?? void 0;
|
|
36076
|
-
if (arrayVal instanceof PdfArray) array = arrayVal;
|
|
35807
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
35808
|
+
const array = dss.getArray(key$1, resolve);
|
|
36077
35809
|
if (!array) return;
|
|
36078
35810
|
for (const item of array) if (item instanceof PdfRef) {
|
|
36079
35811
|
const stream = this.registry.resolve(item);
|
|
@@ -36093,10 +35825,8 @@ var DSSBuilder = class DSSBuilder {
|
|
|
36093
35825
|
*/
|
|
36094
35826
|
async extractRefHashes(entry, key$1, dataMap) {
|
|
36095
35827
|
const hashes = [];
|
|
36096
|
-
|
|
36097
|
-
|
|
36098
|
-
if (arrayVal instanceof PdfRef) arrayVal = this.registry.resolve(arrayVal) ?? void 0;
|
|
36099
|
-
const array = arrayVal instanceof PdfArray ? arrayVal : null;
|
|
35828
|
+
const resolve = this.registry.resolve.bind(this.registry);
|
|
35829
|
+
const array = entry.getArray(key$1, resolve);
|
|
36100
35830
|
if (!array) return hashes;
|
|
36101
35831
|
for (const item of array) if (item instanceof PdfRef) {
|
|
36102
35832
|
const stream = this.registry.resolve(item);
|
|
@@ -38324,12 +38054,8 @@ var PDF = class PDF {
|
|
|
38324
38054
|
*/
|
|
38325
38055
|
getOrCreateViewerPreferences() {
|
|
38326
38056
|
const catalog = this.ctx.catalog.getDict();
|
|
38327
|
-
const existing = catalog.
|
|
38328
|
-
if (existing
|
|
38329
|
-
if (existing instanceof PdfRef) {
|
|
38330
|
-
const resolved = this.ctx.registry.getObject(existing);
|
|
38331
|
-
if (resolved instanceof PdfDict) return resolved;
|
|
38332
|
-
}
|
|
38057
|
+
const existing = catalog.getDict("ViewerPreferences", this.ctx.resolve.bind(this.ctx));
|
|
38058
|
+
if (existing) return existing;
|
|
38333
38059
|
const prefs = new PdfDict();
|
|
38334
38060
|
catalog.set("ViewerPreferences", prefs);
|
|
38335
38061
|
return prefs;
|
|
@@ -38380,24 +38106,9 @@ var PDF = class PDF {
|
|
|
38380
38106
|
if (!ref) return null;
|
|
38381
38107
|
const dict = this.ctx.resolve(ref);
|
|
38382
38108
|
if (!(dict instanceof PdfDict)) return null;
|
|
38383
|
-
this.ensurePageResourcesResolved(dict);
|
|
38384
38109
|
return new PDFPage(ref, dict, index, this.ctx);
|
|
38385
38110
|
}
|
|
38386
38111
|
/**
|
|
38387
|
-
* Ensure page resources are resolved (not a reference).
|
|
38388
|
-
*
|
|
38389
|
-
* Pages may have Resources as a PdfRef pointing to a shared resources dict.
|
|
38390
|
-
* The sync getResources() method on PDFPage needs the actual dict, not a ref.
|
|
38391
|
-
* This resolves the reference and replaces it in the page dict.
|
|
38392
|
-
*/
|
|
38393
|
-
ensurePageResourcesResolved(pageDict) {
|
|
38394
|
-
const resources = pageDict.get("Resources");
|
|
38395
|
-
if (resources instanceof PdfRef) {
|
|
38396
|
-
const resolved = this.ctx.resolve(resources);
|
|
38397
|
-
if (resolved instanceof PdfDict) pageDict.set("Resources", resolved.clone());
|
|
38398
|
-
}
|
|
38399
|
-
}
|
|
38400
|
-
/**
|
|
38401
38112
|
* Add a new blank page.
|
|
38402
38113
|
*
|
|
38403
38114
|
* @param options - Page size, rotation, and insertion position
|
|
@@ -38582,14 +38293,12 @@ var PDF = class PDF {
|
|
|
38582
38293
|
if (!srcPage) throw new RangeError(`Page index ${pageIndex} out of bounds`);
|
|
38583
38294
|
const contentData = this.getPageContentData(source, srcPage);
|
|
38584
38295
|
const copier = new ObjectCopier(source, this, { includeAnnotations: false });
|
|
38585
|
-
|
|
38586
|
-
let resources
|
|
38587
|
-
if (srcResources
|
|
38588
|
-
if (srcResources instanceof PdfDict) {
|
|
38296
|
+
const srcResources = srcPage.dict.getDict("Resources", source.getObject.bind(source));
|
|
38297
|
+
let resources;
|
|
38298
|
+
if (srcResources) {
|
|
38589
38299
|
const copied = await copier.copyObject(srcResources);
|
|
38590
|
-
|
|
38591
|
-
}
|
|
38592
|
-
if (!resources) resources = new PdfDict();
|
|
38300
|
+
resources = copied instanceof PdfDict ? copied : new PdfDict();
|
|
38301
|
+
} else resources = new PdfDict();
|
|
38593
38302
|
const mediaBox = srcPage.getMediaBox();
|
|
38594
38303
|
const formXObject = PdfStream.fromDict({
|
|
38595
38304
|
Type: PdfName.of("XObject"),
|
|
@@ -38609,13 +38318,9 @@ var PDF = class PDF {
|
|
|
38609
38318
|
* Get the concatenated content stream data from a page.
|
|
38610
38319
|
*/
|
|
38611
38320
|
getPageContentData(source, page) {
|
|
38612
|
-
const contents = page.dict.get("Contents");
|
|
38321
|
+
const contents = page.dict.get("Contents", source.getObject.bind(source));
|
|
38613
38322
|
if (!contents) return new Uint8Array(0);
|
|
38614
|
-
if (contents instanceof
|
|
38615
|
-
const stream = source.getObject(contents);
|
|
38616
|
-
if (stream instanceof PdfStream) return stream.getDecodedData();
|
|
38617
|
-
return new Uint8Array(0);
|
|
38618
|
-
}
|
|
38323
|
+
if (contents instanceof PdfStream) return contents.getDecodedData();
|
|
38619
38324
|
if (contents instanceof PdfArray) {
|
|
38620
38325
|
const chunks = [];
|
|
38621
38326
|
for (let i = 0; i < contents.length; i++) {
|
|
@@ -38637,7 +38342,6 @@ var PDF = class PDF {
|
|
|
38637
38342
|
}
|
|
38638
38343
|
return result;
|
|
38639
38344
|
}
|
|
38640
|
-
if (contents instanceof PdfStream) return contents.getDecodedData();
|
|
38641
38345
|
return new Uint8Array(0);
|
|
38642
38346
|
}
|
|
38643
38347
|
/**
|