modern-pdf-lib 0.12.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/dist/index.cjs +1020 -347
- package/dist/index.d.cts +394 -23
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +394 -23
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1014 -348
- package/dist/{libdeflateWasm-CRFwmrSl.mjs → libdeflateWasm-DlHgU5oy.mjs} +2 -2
- package/dist/{libdeflateWasm-DeU6cupL.cjs → libdeflateWasm-OkNoqBnO.cjs} +2 -2
- package/dist/{loader-CZMj0gBy.mjs → loader-CQfoGFp9.mjs} +4 -3
- package/dist/{loader-DWwMj8jZ.cjs → loader-_fqS-TmT.cjs} +4 -3
- package/dist/{pdfCatalog-CTfeeqtF.mjs → pdfCatalog-BB2Wnmud.mjs} +23 -9
- package/dist/{pdfCatalog-y_XG8Hq1.cjs → pdfCatalog-COKoYQ8C.cjs} +23 -9
- package/dist/{pdfPage-BMGFx7Xd.cjs → pdfPage-DBfdinTR.cjs} +713 -232
- package/dist/{pdfPage-JiCJLV3x.mjs → pdfPage-N1K2U3jI.mjs} +692 -241
- package/dist/{pngEmbed-CHyesD7i.mjs → pngEmbed-DTOqgEUC.mjs} +2 -2
- package/dist/{pngEmbed-1RWu6KsO.cjs → pngEmbed-OYyOe_W0.cjs} +2 -2
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { a as formatPdfDate, c as PdfBool, d as PdfNull, f as PdfNumber, g as PdfString, h as PdfStream, i as buildPageTree, l as PdfDict, m as PdfRef, n as buildDocumentStructure, p as PdfObjectRegistry, r as buildInfoDict, s as PdfArray, t as buildCatalog, u as PdfName } from "./pdfCatalog-
|
|
3
|
-
import { n as isAvailable, t as deflateSync$1 } from "./libdeflateWasm-
|
|
1
|
+
import { $ as colorToComponents, $t as setTextMatrix, A as beginMarkedContent, At as fill, B as radians, Bt as setLineJoin, C as AnnotationFlags, Ct as closeFillEvenOddAndStroke, D as createAnnotation, Dt as curveToInitial, E as buildAnnotationDict, Et as curveToFinal, F as endMarkedContent, Ft as moveTo, G as saveState, Gt as endText, H as restoreState, Ht as setMiterLimit, I as wrapInMarkedContent, It as rectangle, J as skew, Jt as nextLine, K as scale, Kt as moveText, L as concatMatrix, Lt as setDashPattern, M as beginMarkedContentWithProperties, Mt as fillEvenOdd, N as createMarkedContentScope, Nt as fillEvenOddAndStroke, O as beginArtifact, Ot as ellipsePath, P as endArtifact, Pt as lineTo, Q as cmyk, Qt as setLeading, R as degrees, Rt as setFlatness, S as parseSvgTransform, St as closeFillAndStroke, T as annotationFromDict, Tt as curveTo, U as rotate, Ut as stroke, V as radiansToDegrees, Vt as setLineWidth, W as rotationMatrix, Wt as beginText, X as applyFillColor, Xt as setFont, Y as translate, Yt as setCharacterSpacing, Z as applyStrokeColor, Zt as setFontSize, _ as drawSvgOnPage, _t as drawXObject, a as buildGradientObjects, an as showTextHex, at as setFillColorCmyk, b as parseSvgColor, bt as clipEvenOdd, c as radialGradient, ct as setFillingColor, d as getRedactionMarks, dt as setStrokeColorGray, en as setTextRenderingMode, et as componentsToColor, f as markForRedaction, ft as setStrokeColorRgb, g as endLayerContent, gt as drawImageXObject, h as beginLayerContent, ht as drawImageWithMatrix, i as wrapText, in as showTextArray, it as setFillColor, j as beginMarkedContentSequence, jt as fillAndStroke, k as beginArtifactWithType, kt as endPath, l as tilingPattern, lt as setStrokeColor, m as PdfLayerManager, mt as setStrokingColor, n as PdfPage, nn as setWordSpacing, nt as rgb, o as buildPatternObjects, on as showTextNextLine, ot as setFillColorGray, p as PdfLayer, pt as setStrokeColorSpace, q as setGraphicsState, qt as moveTextSetLeading, rn as showText, rt as setColorSpace, s as linearGradient, sn as showTextWithSpacing, st as setFillColorRgb, t as PageSizes, tn as setTextRise, tt as grayscale, u as applyRedactions, ut as setStrokeColorCmyk, v as svgToPdfOperators, vt as circlePath, w as PdfAnnotation, wt as closePath, x as parseSvgPath, xt as closeAndStroke, y as parseSvg, yt as clip, z as degreesToRadians, zt as setLineCap } from "./pdfPage-N1K2U3jI.mjs";
|
|
2
|
+
import { a as formatPdfDate, c as PdfBool, d as PdfNull, f as PdfNumber, g as PdfString, h as PdfStream, i as buildPageTree, l as PdfDict, m as PdfRef, n as buildDocumentStructure, p as PdfObjectRegistry, r as buildInfoDict, s as PdfArray, t as buildCatalog, u as PdfName } from "./pdfCatalog-BB2Wnmud.mjs";
|
|
3
|
+
import { n as isAvailable, t as deflateSync$1 } from "./libdeflateWasm-DlHgU5oy.mjs";
|
|
4
4
|
import { i as subsetFont, n as computeSubsetTag, t as buildSubsetCmap } from "./fontSubset-ZpLoOZ2e.mjs";
|
|
5
|
-
import { t as embedPng } from "./pngEmbed-
|
|
5
|
+
import { t as embedPng } from "./pngEmbed-DTOqgEUC.mjs";
|
|
6
6
|
import { t as decompressSync } from "./fflateAdapter-DX0VqT5k.mjs";
|
|
7
7
|
import { deflateSync, inflateSync, unzlibSync } from "fflate";
|
|
8
8
|
|
|
@@ -199,20 +199,19 @@ var PdfWriter = class {
|
|
|
199
199
|
*/
|
|
200
200
|
writeObjectStream(entries, xrefEntries) {
|
|
201
201
|
const serializedObjects = [];
|
|
202
|
-
new StringByteWriter();
|
|
203
202
|
for (const entry of entries) {
|
|
204
203
|
const objWriter = new StringByteWriter();
|
|
205
204
|
entry.object.serialize(objWriter);
|
|
206
205
|
serializedObjects.push(objWriter.toUint8Array());
|
|
207
206
|
}
|
|
208
|
-
|
|
207
|
+
const headerParts = [];
|
|
209
208
|
let dataOffset = 0;
|
|
210
209
|
for (let i = 0; i < entries.length; i++) {
|
|
211
|
-
|
|
212
|
-
headerStr += `${entries[i].ref.objectNumber} ${dataOffset}`;
|
|
210
|
+
headerParts.push(`${entries[i].ref.objectNumber} ${dataOffset}`);
|
|
213
211
|
dataOffset += serializedObjects[i].length;
|
|
214
212
|
if (i < entries.length - 1) dataOffset += 1;
|
|
215
213
|
}
|
|
214
|
+
const headerStr = headerParts.join(" ");
|
|
216
215
|
const headerBytes = encoder$5.encode(headerStr + " ");
|
|
217
216
|
const firstOffset = headerBytes.length;
|
|
218
217
|
let totalDataLen = firstOffset;
|
|
@@ -3235,7 +3234,7 @@ function extractMetricsWasm(fontData) {
|
|
|
3235
3234
|
* Tracks which glyphs have been used so that subsetting can be
|
|
3236
3235
|
* performed at save time, and provides text measurement methods.
|
|
3237
3236
|
*
|
|
3238
|
-
* Create via
|
|
3237
|
+
* Create via `PdfDocument.embedFont()`.
|
|
3239
3238
|
*/
|
|
3240
3239
|
var EmbeddedFont = class {
|
|
3241
3240
|
/** The raw font file bytes. */
|
|
@@ -3580,6 +3579,53 @@ function findTable(data, tag) {
|
|
|
3580
3579
|
}
|
|
3581
3580
|
}
|
|
3582
3581
|
|
|
3582
|
+
//#endregion
|
|
3583
|
+
//#region src/parser/parseError.ts
|
|
3584
|
+
/**
|
|
3585
|
+
* @module parser/parseError
|
|
3586
|
+
* Structured error class for PDF parsing failures.
|
|
3587
|
+
* @packageDocumentation
|
|
3588
|
+
*/
|
|
3589
|
+
var PdfParseError = class extends Error {
|
|
3590
|
+
name = "PdfParseError";
|
|
3591
|
+
offset;
|
|
3592
|
+
expected;
|
|
3593
|
+
actual;
|
|
3594
|
+
hexContext;
|
|
3595
|
+
constructor(options) {
|
|
3596
|
+
const hexCtx = options.data ? formatHexContext(options.data, options.offset) : "";
|
|
3597
|
+
const parts = [options.message];
|
|
3598
|
+
if (options.expected) parts.push(` Expected: ${options.expected}`);
|
|
3599
|
+
if (options.actual) parts.push(` Got: ${options.actual}`);
|
|
3600
|
+
if (hexCtx) parts.push(` Context:\n${hexCtx}`);
|
|
3601
|
+
super(parts.join("\n"), options.cause ? { cause: options.cause } : void 0);
|
|
3602
|
+
this.offset = options.offset;
|
|
3603
|
+
this.expected = options.expected ?? "";
|
|
3604
|
+
this.actual = options.actual ?? "";
|
|
3605
|
+
this.hexContext = hexCtx;
|
|
3606
|
+
}
|
|
3607
|
+
};
|
|
3608
|
+
function formatHexContext(data, offset, windowSize = 16) {
|
|
3609
|
+
const start = Math.max(0, offset - windowSize);
|
|
3610
|
+
const end = Math.min(data.length, offset + windowSize);
|
|
3611
|
+
const slice = data.subarray(start, end);
|
|
3612
|
+
const hexParts = [];
|
|
3613
|
+
const asciiParts = [];
|
|
3614
|
+
for (let i = 0; i < slice.length; i++) {
|
|
3615
|
+
const byte = slice[i];
|
|
3616
|
+
const isErrorByte = start + i === offset;
|
|
3617
|
+
const hex = byte.toString(16).padStart(2, "0");
|
|
3618
|
+
hexParts.push(isErrorByte ? `[${hex}]` : ` ${hex} `);
|
|
3619
|
+
asciiParts.push(byte >= 32 && byte <= 126 ? String.fromCharCode(byte) : ".");
|
|
3620
|
+
}
|
|
3621
|
+
return [
|
|
3622
|
+
` Offset ${start}:`,
|
|
3623
|
+
` Hex: ${hexParts.join("")}`,
|
|
3624
|
+
` ASCII: ${asciiParts.join(" ")}`,
|
|
3625
|
+
` Error at offset ${offset} (marked with [])`
|
|
3626
|
+
].join("\n");
|
|
3627
|
+
}
|
|
3628
|
+
|
|
3583
3629
|
//#endregion
|
|
3584
3630
|
//#region src/parser/lexer.ts
|
|
3585
3631
|
/**
|
|
@@ -3707,7 +3753,7 @@ const isDelimiter = /* @__PURE__ */ (() => {
|
|
|
3707
3753
|
* `hexVal[b]` is the numeric value (0-15) of a hex character, or -1 if
|
|
3708
3754
|
* the byte is not a valid hex digit.
|
|
3709
3755
|
*/
|
|
3710
|
-
const hexVal = /* @__PURE__ */ (() => {
|
|
3756
|
+
const hexVal$1 = /* @__PURE__ */ (() => {
|
|
3711
3757
|
const t = new Int8Array(256).fill(-1);
|
|
3712
3758
|
for (let i = 0; i <= 9; i++) t[CH_0 + i] = i;
|
|
3713
3759
|
for (let i = 0; i < 6; i++) {
|
|
@@ -3735,7 +3781,7 @@ const hexVal = /* @__PURE__ */ (() => {
|
|
|
3735
3781
|
*/
|
|
3736
3782
|
var PdfLexer = class {
|
|
3737
3783
|
/** The raw PDF bytes being tokenized. */
|
|
3738
|
-
|
|
3784
|
+
_data;
|
|
3739
3785
|
/** Total length of the input (cached for hot loops). */
|
|
3740
3786
|
len;
|
|
3741
3787
|
/** Current read position (byte offset). */
|
|
@@ -3758,11 +3804,20 @@ var PdfLexer = class {
|
|
|
3758
3804
|
* must not mutate it while the lexer is in use.
|
|
3759
3805
|
*/
|
|
3760
3806
|
constructor(data) {
|
|
3761
|
-
this.
|
|
3807
|
+
this._data = data;
|
|
3762
3808
|
this.len = data.length;
|
|
3763
3809
|
this.position = 0;
|
|
3764
3810
|
}
|
|
3765
3811
|
/**
|
|
3812
|
+
* Public accessor for the raw PDF byte buffer.
|
|
3813
|
+
*
|
|
3814
|
+
* This allows other parsers (e.g. object parser, xref parser) to
|
|
3815
|
+
* include hex-context dumps in structured error messages.
|
|
3816
|
+
*/
|
|
3817
|
+
get rawData() {
|
|
3818
|
+
return this._data;
|
|
3819
|
+
}
|
|
3820
|
+
/**
|
|
3766
3821
|
* Consume and return the next token.
|
|
3767
3822
|
*
|
|
3768
3823
|
* Returns a token with `type === TokenType.EOF` when the input is
|
|
@@ -3798,8 +3853,14 @@ var PdfLexer = class {
|
|
|
3798
3853
|
* @throws If there are not enough bytes remaining.
|
|
3799
3854
|
*/
|
|
3800
3855
|
readStreamData(length) {
|
|
3801
|
-
if (this.position + length > this.len) throw new
|
|
3802
|
-
|
|
3856
|
+
if (this.position + length > this.len) throw new PdfParseError({
|
|
3857
|
+
message: `PdfLexer.readStreamData: requested ${length} bytes at offset ${this.position}, but only ${this.len - this.position} remain`,
|
|
3858
|
+
offset: this.position,
|
|
3859
|
+
expected: `${length} bytes available`,
|
|
3860
|
+
actual: `${this.len - this.position} bytes remaining`,
|
|
3861
|
+
data: this._data
|
|
3862
|
+
});
|
|
3863
|
+
const slice = this._data.subarray(this.position, this.position + length);
|
|
3803
3864
|
this.position += length;
|
|
3804
3865
|
return slice;
|
|
3805
3866
|
}
|
|
@@ -3812,7 +3873,13 @@ var PdfLexer = class {
|
|
|
3812
3873
|
* @throws If the offset is out of range.
|
|
3813
3874
|
*/
|
|
3814
3875
|
seek(offset) {
|
|
3815
|
-
if (offset < 0 || offset > this.len) throw new
|
|
3876
|
+
if (offset < 0 || offset > this.len) throw new PdfParseError({
|
|
3877
|
+
message: `PdfLexer.seek: offset ${offset} is outside [0, ${this.len}]`,
|
|
3878
|
+
offset,
|
|
3879
|
+
expected: `offset in range [0, ${this.len}]`,
|
|
3880
|
+
actual: `${offset}`,
|
|
3881
|
+
data: this._data
|
|
3882
|
+
});
|
|
3816
3883
|
this.position = offset;
|
|
3817
3884
|
this.peeked = null;
|
|
3818
3885
|
}
|
|
@@ -3825,7 +3892,7 @@ var PdfLexer = class {
|
|
|
3825
3892
|
*/
|
|
3826
3893
|
byteAt(offset) {
|
|
3827
3894
|
if (offset < 0 || offset >= this.len) return -1;
|
|
3828
|
-
return this.
|
|
3895
|
+
return this._data[offset];
|
|
3829
3896
|
}
|
|
3830
3897
|
/**
|
|
3831
3898
|
* Return the total length of the input buffer (in bytes).
|
|
@@ -3841,7 +3908,7 @@ var PdfLexer = class {
|
|
|
3841
3908
|
* extracting stream data.
|
|
3842
3909
|
*/
|
|
3843
3910
|
skipWhitespace() {
|
|
3844
|
-
const d = this.
|
|
3911
|
+
const d = this._data;
|
|
3845
3912
|
let pos = this.position;
|
|
3846
3913
|
while (pos < this.len) {
|
|
3847
3914
|
const b = d[pos];
|
|
@@ -3875,7 +3942,7 @@ var PdfLexer = class {
|
|
|
3875
3942
|
value: null,
|
|
3876
3943
|
offset: this.position
|
|
3877
3944
|
};
|
|
3878
|
-
const d = this.
|
|
3945
|
+
const d = this._data;
|
|
3879
3946
|
const startPos = this.position;
|
|
3880
3947
|
const b = d[startPos];
|
|
3881
3948
|
if (b === CH_LBRACKET) {
|
|
@@ -3915,7 +3982,13 @@ var PdfLexer = class {
|
|
|
3915
3982
|
};
|
|
3916
3983
|
}
|
|
3917
3984
|
this.position++;
|
|
3918
|
-
throw new
|
|
3985
|
+
throw new PdfParseError({
|
|
3986
|
+
message: `PdfLexer: unexpected '>' at offset ${startPos} (expected '>>' for dict end)`,
|
|
3987
|
+
offset: startPos,
|
|
3988
|
+
expected: "'>>' (dict end delimiter)",
|
|
3989
|
+
actual: "'>' (lone angle bracket)",
|
|
3990
|
+
data: this._data
|
|
3991
|
+
});
|
|
3919
3992
|
}
|
|
3920
3993
|
if (b === CH_LPAREN) return this.readLiteralString(startPos);
|
|
3921
3994
|
if (b === CH_SLASH) return this.readName(startPos);
|
|
@@ -3930,7 +4003,7 @@ var PdfLexer = class {
|
|
|
3930
4003
|
* `-.002`, `+.5`). Scientific notation is **not** permitted.
|
|
3931
4004
|
*/
|
|
3932
4005
|
readNumber(startPos) {
|
|
3933
|
-
const d = this.
|
|
4006
|
+
const d = this._data;
|
|
3934
4007
|
let pos = startPos;
|
|
3935
4008
|
let hasSign = false;
|
|
3936
4009
|
let hasDot = false;
|
|
@@ -3974,10 +4047,10 @@ var PdfLexer = class {
|
|
|
3974
4047
|
* parentheses.
|
|
3975
4048
|
*/
|
|
3976
4049
|
readLiteralString(startPos) {
|
|
3977
|
-
const d = this.
|
|
4050
|
+
const d = this._data;
|
|
3978
4051
|
let pos = startPos + 1;
|
|
3979
4052
|
let depth = 1;
|
|
3980
|
-
|
|
4053
|
+
const parts = [];
|
|
3981
4054
|
while (pos < this.len && depth > 0) {
|
|
3982
4055
|
const c = d[pos];
|
|
3983
4056
|
if (c === CH_BACKSLASH) {
|
|
@@ -3986,35 +4059,35 @@ var PdfLexer = class {
|
|
|
3986
4059
|
const esc = d[pos];
|
|
3987
4060
|
switch (esc) {
|
|
3988
4061
|
case 110:
|
|
3989
|
-
|
|
4062
|
+
parts.push("\n");
|
|
3990
4063
|
pos++;
|
|
3991
4064
|
break;
|
|
3992
4065
|
case 114:
|
|
3993
|
-
|
|
4066
|
+
parts.push("\r");
|
|
3994
4067
|
pos++;
|
|
3995
4068
|
break;
|
|
3996
4069
|
case 116:
|
|
3997
|
-
|
|
4070
|
+
parts.push(" ");
|
|
3998
4071
|
pos++;
|
|
3999
4072
|
break;
|
|
4000
4073
|
case 98:
|
|
4001
|
-
|
|
4074
|
+
parts.push("\b");
|
|
4002
4075
|
pos++;
|
|
4003
4076
|
break;
|
|
4004
4077
|
case 102:
|
|
4005
|
-
|
|
4078
|
+
parts.push("\f");
|
|
4006
4079
|
pos++;
|
|
4007
4080
|
break;
|
|
4008
4081
|
case CH_LPAREN:
|
|
4009
|
-
|
|
4082
|
+
parts.push("(");
|
|
4010
4083
|
pos++;
|
|
4011
4084
|
break;
|
|
4012
4085
|
case CH_RPAREN:
|
|
4013
|
-
|
|
4086
|
+
parts.push(")");
|
|
4014
4087
|
pos++;
|
|
4015
4088
|
break;
|
|
4016
4089
|
case CH_BACKSLASH:
|
|
4017
|
-
|
|
4090
|
+
parts.push("\\");
|
|
4018
4091
|
pos++;
|
|
4019
4092
|
break;
|
|
4020
4093
|
case WS_LF:
|
|
@@ -4036,9 +4109,9 @@ var PdfLexer = class {
|
|
|
4036
4109
|
pos++;
|
|
4037
4110
|
}
|
|
4038
4111
|
}
|
|
4039
|
-
|
|
4112
|
+
parts.push(String.fromCharCode(octal & 255));
|
|
4040
4113
|
} else {
|
|
4041
|
-
|
|
4114
|
+
parts.push(String.fromCharCode(esc));
|
|
4042
4115
|
pos++;
|
|
4043
4116
|
}
|
|
4044
4117
|
break;
|
|
@@ -4047,30 +4120,36 @@ var PdfLexer = class {
|
|
|
4047
4120
|
}
|
|
4048
4121
|
if (c === CH_LPAREN) {
|
|
4049
4122
|
depth++;
|
|
4050
|
-
|
|
4123
|
+
parts.push("(");
|
|
4051
4124
|
pos++;
|
|
4052
4125
|
continue;
|
|
4053
4126
|
}
|
|
4054
4127
|
if (c === CH_RPAREN) {
|
|
4055
4128
|
depth--;
|
|
4056
|
-
if (depth > 0)
|
|
4129
|
+
if (depth > 0) parts.push(")");
|
|
4057
4130
|
pos++;
|
|
4058
4131
|
continue;
|
|
4059
4132
|
}
|
|
4060
4133
|
if (c === WS_CR) {
|
|
4061
|
-
|
|
4134
|
+
parts.push("\n");
|
|
4062
4135
|
pos++;
|
|
4063
4136
|
if (pos < this.len && d[pos] === WS_LF) pos++;
|
|
4064
4137
|
continue;
|
|
4065
4138
|
}
|
|
4066
|
-
|
|
4139
|
+
parts.push(String.fromCharCode(c));
|
|
4067
4140
|
pos++;
|
|
4068
4141
|
}
|
|
4069
|
-
if (depth !== 0) throw new
|
|
4142
|
+
if (depth !== 0) throw new PdfParseError({
|
|
4143
|
+
message: `PdfLexer: unterminated literal string starting at offset ${startPos}`,
|
|
4144
|
+
offset: startPos,
|
|
4145
|
+
expected: "closing ')' for literal string",
|
|
4146
|
+
actual: "end of input",
|
|
4147
|
+
data: this._data
|
|
4148
|
+
});
|
|
4070
4149
|
this.position = pos;
|
|
4071
4150
|
return {
|
|
4072
4151
|
type: TokenType$1.LiteralString,
|
|
4073
|
-
value:
|
|
4152
|
+
value: parts.join(""),
|
|
4074
4153
|
offset: startPos
|
|
4075
4154
|
};
|
|
4076
4155
|
}
|
|
@@ -4081,9 +4160,10 @@ var PdfLexer = class {
|
|
|
4081
4160
|
* odd, a trailing `0` is assumed (per spec SS 7.3.4.3).
|
|
4082
4161
|
*/
|
|
4083
4162
|
readHexString(startPos) {
|
|
4084
|
-
const d = this.
|
|
4163
|
+
const d = this._data;
|
|
4085
4164
|
let pos = startPos + 1;
|
|
4086
|
-
|
|
4165
|
+
const bytes = [];
|
|
4166
|
+
let hi = -1;
|
|
4087
4167
|
while (pos < this.len) {
|
|
4088
4168
|
const c = d[pos];
|
|
4089
4169
|
if (c === CH_GT) {
|
|
@@ -4094,21 +4174,26 @@ var PdfLexer = class {
|
|
|
4094
4174
|
pos++;
|
|
4095
4175
|
continue;
|
|
4096
4176
|
}
|
|
4097
|
-
|
|
4098
|
-
|
|
4177
|
+
const v = hexVal$1[c];
|
|
4178
|
+
if (v === -1) throw new PdfParseError({
|
|
4179
|
+
message: `PdfLexer: invalid hex digit 0x${c.toString(16).padStart(2, "0")} at offset ${pos} in hex string starting at ${startPos}`,
|
|
4180
|
+
offset: pos,
|
|
4181
|
+
expected: "hex digit (0-9, a-f, A-F)",
|
|
4182
|
+
actual: `0x${c.toString(16).padStart(2, "0")}`,
|
|
4183
|
+
data: this._data
|
|
4184
|
+
});
|
|
4185
|
+
if (hi === -1) hi = v;
|
|
4186
|
+
else {
|
|
4187
|
+
bytes.push(hi << 4 | v);
|
|
4188
|
+
hi = -1;
|
|
4189
|
+
}
|
|
4099
4190
|
pos++;
|
|
4100
4191
|
}
|
|
4101
|
-
if (
|
|
4102
|
-
let result = "";
|
|
4103
|
-
for (let i = 0; i < hex.length; i += 2) {
|
|
4104
|
-
const hi = hexVal[hex.charCodeAt(i)];
|
|
4105
|
-
const lo = hexVal[hex.charCodeAt(i + 1)];
|
|
4106
|
-
result += String.fromCharCode(hi << 4 | lo);
|
|
4107
|
-
}
|
|
4192
|
+
if (hi !== -1) bytes.push(hi << 4);
|
|
4108
4193
|
this.position = pos;
|
|
4109
4194
|
return {
|
|
4110
4195
|
type: TokenType$1.HexString,
|
|
4111
|
-
value:
|
|
4196
|
+
value: String.fromCharCode.apply(null, bytes),
|
|
4112
4197
|
offset: startPos
|
|
4113
4198
|
};
|
|
4114
4199
|
}
|
|
@@ -4119,28 +4204,40 @@ var PdfLexer = class {
|
|
|
4119
4204
|
* **includes** the leading `/`.
|
|
4120
4205
|
*/
|
|
4121
4206
|
readName(startPos) {
|
|
4122
|
-
const d = this.
|
|
4207
|
+
const d = this._data;
|
|
4123
4208
|
let pos = startPos + 1;
|
|
4124
|
-
|
|
4209
|
+
const parts = ["/"];
|
|
4125
4210
|
while (pos < this.len) {
|
|
4126
4211
|
const c = d[pos];
|
|
4127
4212
|
if (isWhitespace[c] || isDelimiter[c]) break;
|
|
4128
4213
|
if (c === CH_HASH) {
|
|
4129
|
-
if (pos + 2 >= this.len) throw new
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4214
|
+
if (pos + 2 >= this.len) throw new PdfParseError({
|
|
4215
|
+
message: `PdfLexer: incomplete #XX escape in name at offset ${pos}`,
|
|
4216
|
+
offset: pos,
|
|
4217
|
+
expected: "two hex digits after # in name",
|
|
4218
|
+
actual: "end of input",
|
|
4219
|
+
data: this._data
|
|
4220
|
+
});
|
|
4221
|
+
const hi = hexVal$1[d[pos + 1]];
|
|
4222
|
+
const lo = hexVal$1[d[pos + 2]];
|
|
4223
|
+
if (hi === -1 || lo === -1) throw new PdfParseError({
|
|
4224
|
+
message: `PdfLexer: invalid #XX escape in name at offset ${pos}`,
|
|
4225
|
+
offset: pos,
|
|
4226
|
+
expected: "valid hex digits after # in name",
|
|
4227
|
+
actual: `#${String.fromCharCode(d[pos + 1])}${String.fromCharCode(d[pos + 2])}`,
|
|
4228
|
+
data: this._data
|
|
4229
|
+
});
|
|
4230
|
+
parts.push(String.fromCharCode(hi << 4 | lo));
|
|
4134
4231
|
pos += 3;
|
|
4135
4232
|
continue;
|
|
4136
4233
|
}
|
|
4137
|
-
|
|
4234
|
+
parts.push(String.fromCharCode(c));
|
|
4138
4235
|
pos++;
|
|
4139
4236
|
}
|
|
4140
4237
|
this.position = pos;
|
|
4141
4238
|
return {
|
|
4142
4239
|
type: TokenType$1.Name,
|
|
4143
|
-
value:
|
|
4240
|
+
value: parts.join(""),
|
|
4144
4241
|
offset: startPos
|
|
4145
4242
|
};
|
|
4146
4243
|
}
|
|
@@ -4151,7 +4248,7 @@ var PdfLexer = class {
|
|
|
4151
4248
|
* available for callers that want to preserve them.
|
|
4152
4249
|
*/
|
|
4153
4250
|
readComment(startPos) {
|
|
4154
|
-
const d = this.
|
|
4251
|
+
const d = this._data;
|
|
4155
4252
|
let pos = startPos + 1;
|
|
4156
4253
|
const begin = pos;
|
|
4157
4254
|
while (pos < this.len) {
|
|
@@ -4176,7 +4273,7 @@ var PdfLexer = class {
|
|
|
4176
4273
|
* handle them.
|
|
4177
4274
|
*/
|
|
4178
4275
|
readKeyword(startPos) {
|
|
4179
|
-
const d = this.
|
|
4276
|
+
const d = this._data;
|
|
4180
4277
|
let pos = startPos;
|
|
4181
4278
|
while (pos < this.len) {
|
|
4182
4279
|
const c = d[pos];
|
|
@@ -4255,10 +4352,7 @@ var PdfLexer = class {
|
|
|
4255
4352
|
* because it avoids the per-call overhead of the streaming decoder.
|
|
4256
4353
|
*/
|
|
4257
4354
|
bytesToAscii(from, to) {
|
|
4258
|
-
|
|
4259
|
-
let s = "";
|
|
4260
|
-
for (let i = from; i < to; i++) s += String.fromCharCode(d[i]);
|
|
4261
|
-
return s;
|
|
4355
|
+
return String.fromCharCode.apply(null, this._data.subarray(from, to));
|
|
4262
4356
|
}
|
|
4263
4357
|
};
|
|
4264
4358
|
|
|
@@ -4331,13 +4425,31 @@ var PdfObjectParser = class {
|
|
|
4331
4425
|
*/
|
|
4332
4426
|
parseIndirectObject() {
|
|
4333
4427
|
const objNumToken = this.lexer.nextToken();
|
|
4334
|
-
if (objNumToken.type !== TokenType$1.Number || !Number.isInteger(objNumToken.value)) throw new
|
|
4428
|
+
if (objNumToken.type !== TokenType$1.Number || !Number.isInteger(objNumToken.value)) throw new PdfParseError({
|
|
4429
|
+
message: `PdfObjectParser.parseIndirectObject: expected integer object number at offset ${objNumToken.offset}, got ${TokenType$1[objNumToken.type]} (${String(objNumToken.value)})`,
|
|
4430
|
+
offset: objNumToken.offset,
|
|
4431
|
+
expected: "integer object number",
|
|
4432
|
+
actual: `${TokenType$1[objNumToken.type]} (${String(objNumToken.value)})`,
|
|
4433
|
+
data: this.lexer.rawData
|
|
4434
|
+
});
|
|
4335
4435
|
const objNum = objNumToken.value;
|
|
4336
4436
|
const genNumToken = this.lexer.nextToken();
|
|
4337
|
-
if (genNumToken.type !== TokenType$1.Number || !Number.isInteger(genNumToken.value)) throw new
|
|
4437
|
+
if (genNumToken.type !== TokenType$1.Number || !Number.isInteger(genNumToken.value)) throw new PdfParseError({
|
|
4438
|
+
message: `PdfObjectParser.parseIndirectObject: expected integer generation number at offset ${genNumToken.offset}, got ${TokenType$1[genNumToken.type]} (${String(genNumToken.value)})`,
|
|
4439
|
+
offset: genNumToken.offset,
|
|
4440
|
+
expected: "integer generation number",
|
|
4441
|
+
actual: `${TokenType$1[genNumToken.type]} (${String(genNumToken.value)})`,
|
|
4442
|
+
data: this.lexer.rawData
|
|
4443
|
+
});
|
|
4338
4444
|
const genNum = genNumToken.value;
|
|
4339
4445
|
const objKw = this.lexer.nextToken();
|
|
4340
|
-
if (objKw.type !== TokenType$1.ObjKeyword) throw new
|
|
4446
|
+
if (objKw.type !== TokenType$1.ObjKeyword) throw new PdfParseError({
|
|
4447
|
+
message: `PdfObjectParser.parseIndirectObject: expected 'obj' keyword at offset ${objKw.offset}, got ${TokenType$1[objKw.type]} (${String(objKw.value)})`,
|
|
4448
|
+
offset: objKw.offset,
|
|
4449
|
+
expected: "'obj' keyword",
|
|
4450
|
+
actual: `${TokenType$1[objKw.type]} (${String(objKw.value)})`,
|
|
4451
|
+
data: this.lexer.rawData
|
|
4452
|
+
});
|
|
4341
4453
|
return this.parseIndirectObjectBody(objNum, genNum);
|
|
4342
4454
|
}
|
|
4343
4455
|
/**
|
|
@@ -4382,8 +4494,20 @@ var PdfObjectParser = class {
|
|
|
4382
4494
|
case TokenType$1.Name: return PdfName.of(token.value);
|
|
4383
4495
|
case TokenType$1.ArrayStart: return this.parseArray();
|
|
4384
4496
|
case TokenType$1.DictStart: return this.parseDictOrStream();
|
|
4385
|
-
case TokenType$1.EOF: throw new
|
|
4386
|
-
|
|
4497
|
+
case TokenType$1.EOF: throw new PdfParseError({
|
|
4498
|
+
message: `PdfObjectParser: unexpected end of input at offset ${token.offset}`,
|
|
4499
|
+
offset: token.offset,
|
|
4500
|
+
expected: "a PDF object (number, string, name, array, dict, etc.)",
|
|
4501
|
+
actual: "end of input",
|
|
4502
|
+
data: this.lexer.rawData
|
|
4503
|
+
});
|
|
4504
|
+
default: throw new PdfParseError({
|
|
4505
|
+
message: `PdfObjectParser: unexpected token ${TokenType$1[token.type]} (${String(token.value)}) at offset ${token.offset}`,
|
|
4506
|
+
offset: token.offset,
|
|
4507
|
+
expected: "a PDF object (number, string, name, array, dict, etc.)",
|
|
4508
|
+
actual: `${TokenType$1[token.type]} (${String(token.value)})`,
|
|
4509
|
+
data: this.lexer.rawData
|
|
4510
|
+
});
|
|
4387
4511
|
}
|
|
4388
4512
|
}
|
|
4389
4513
|
/**
|
|
@@ -4429,7 +4553,13 @@ var PdfObjectParser = class {
|
|
|
4429
4553
|
if (this.lexer.peekToken().type === TokenType$1.StreamKeyword) finalObject = this.readStream(object);
|
|
4430
4554
|
}
|
|
4431
4555
|
const endToken = this.lexer.nextToken();
|
|
4432
|
-
if (endToken.type !== TokenType$1.EndObjKeyword) throw new
|
|
4556
|
+
if (endToken.type !== TokenType$1.EndObjKeyword) throw new PdfParseError({
|
|
4557
|
+
message: `PdfObjectParser: expected 'endobj' for object ${objNum} ${genNum} at offset ${endToken.offset}, got ${TokenType$1[endToken.type]} (${String(endToken.value)})`,
|
|
4558
|
+
offset: endToken.offset,
|
|
4559
|
+
expected: `'endobj' keyword for object ${objNum} ${genNum}`,
|
|
4560
|
+
actual: `${TokenType$1[endToken.type]} (${String(endToken.value)})`,
|
|
4561
|
+
data: this.lexer.rawData
|
|
4562
|
+
});
|
|
4433
4563
|
this.registry.registerWithRef(ref, finalObject);
|
|
4434
4564
|
return {
|
|
4435
4565
|
ref,
|
|
@@ -4449,7 +4579,13 @@ var PdfObjectParser = class {
|
|
|
4449
4579
|
this.lexer.nextToken();
|
|
4450
4580
|
break;
|
|
4451
4581
|
}
|
|
4452
|
-
if (peek.type === TokenType$1.EOF) throw new
|
|
4582
|
+
if (peek.type === TokenType$1.EOF) throw new PdfParseError({
|
|
4583
|
+
message: `PdfObjectParser: unterminated array at offset ${peek.offset}`,
|
|
4584
|
+
offset: peek.offset,
|
|
4585
|
+
expected: "']' to close array",
|
|
4586
|
+
actual: "end of input",
|
|
4587
|
+
data: this.lexer.rawData
|
|
4588
|
+
});
|
|
4453
4589
|
items.push(this.parseObject());
|
|
4454
4590
|
}
|
|
4455
4591
|
return new PdfArray(items);
|
|
@@ -4478,9 +4614,21 @@ var PdfObjectParser = class {
|
|
|
4478
4614
|
this.lexer.nextToken();
|
|
4479
4615
|
break;
|
|
4480
4616
|
}
|
|
4481
|
-
if (peek.type === TokenType$1.EOF) throw new
|
|
4617
|
+
if (peek.type === TokenType$1.EOF) throw new PdfParseError({
|
|
4618
|
+
message: `PdfObjectParser: unterminated dictionary at offset ${peek.offset}`,
|
|
4619
|
+
offset: peek.offset,
|
|
4620
|
+
expected: "'>>' to close dictionary",
|
|
4621
|
+
actual: "end of input",
|
|
4622
|
+
data: this.lexer.rawData
|
|
4623
|
+
});
|
|
4482
4624
|
const keyToken = this.lexer.nextToken();
|
|
4483
|
-
if (keyToken.type !== TokenType$1.Name) throw new
|
|
4625
|
+
if (keyToken.type !== TokenType$1.Name) throw new PdfParseError({
|
|
4626
|
+
message: `PdfObjectParser: expected name as dictionary key at offset ${keyToken.offset}, got ${TokenType$1[keyToken.type]} (${String(keyToken.value)})`,
|
|
4627
|
+
offset: keyToken.offset,
|
|
4628
|
+
expected: "name token as dictionary key",
|
|
4629
|
+
actual: `${TokenType$1[keyToken.type]} (${String(keyToken.value)})`,
|
|
4630
|
+
data: this.lexer.rawData
|
|
4631
|
+
});
|
|
4484
4632
|
const key = keyToken.value;
|
|
4485
4633
|
const value = this.parseObject();
|
|
4486
4634
|
dict.set(key, value);
|
|
@@ -4499,13 +4647,25 @@ var PdfObjectParser = class {
|
|
|
4499
4647
|
*/
|
|
4500
4648
|
readStream(dict) {
|
|
4501
4649
|
const streamKw = this.lexer.nextToken();
|
|
4502
|
-
if (streamKw.type !== TokenType$1.StreamKeyword) throw new
|
|
4650
|
+
if (streamKw.type !== TokenType$1.StreamKeyword) throw new PdfParseError({
|
|
4651
|
+
message: `PdfObjectParser.readStream: expected 'stream' keyword at offset ${streamKw.offset}, got ${TokenType$1[streamKw.type]}`,
|
|
4652
|
+
offset: streamKw.offset,
|
|
4653
|
+
expected: "'stream' keyword",
|
|
4654
|
+
actual: `${TokenType$1[streamKw.type]}`,
|
|
4655
|
+
data: this.lexer.rawData
|
|
4656
|
+
});
|
|
4503
4657
|
this.skipStreamEol();
|
|
4504
4658
|
const length = this.resolveStreamLength(dict);
|
|
4505
4659
|
const data = this.lexer.readStreamData(length);
|
|
4506
4660
|
this.skipEndstreamWhitespace();
|
|
4507
4661
|
const endKw = this.lexer.nextToken();
|
|
4508
|
-
if (endKw.type !== TokenType$1.EndStreamKeyword) throw new
|
|
4662
|
+
if (endKw.type !== TokenType$1.EndStreamKeyword) throw new PdfParseError({
|
|
4663
|
+
message: `PdfObjectParser.readStream: expected 'endstream' keyword at offset ${endKw.offset}, got ${TokenType$1[endKw.type]} (${String(endKw.value)})`,
|
|
4664
|
+
offset: endKw.offset,
|
|
4665
|
+
expected: "'endstream' keyword",
|
|
4666
|
+
actual: `${TokenType$1[endKw.type]} (${String(endKw.value)})`,
|
|
4667
|
+
data: this.lexer.rawData
|
|
4668
|
+
});
|
|
4509
4669
|
return new PdfStream(dict, data);
|
|
4510
4670
|
}
|
|
4511
4671
|
/**
|
|
@@ -4550,18 +4710,42 @@ var PdfObjectParser = class {
|
|
|
4550
4710
|
*/
|
|
4551
4711
|
resolveStreamLength(dict) {
|
|
4552
4712
|
const lengthObj = dict.get("/Length");
|
|
4553
|
-
if (lengthObj === void 0) throw new
|
|
4713
|
+
if (lengthObj === void 0) throw new PdfParseError({
|
|
4714
|
+
message: "PdfObjectParser.resolveStreamLength: stream dictionary is missing /Length",
|
|
4715
|
+
offset: this.lexer.position,
|
|
4716
|
+
expected: "/Length entry in stream dictionary",
|
|
4717
|
+
actual: "no /Length entry",
|
|
4718
|
+
data: this.lexer.rawData
|
|
4719
|
+
});
|
|
4554
4720
|
if (lengthObj.kind === "number") return lengthObj.value;
|
|
4555
4721
|
if (lengthObj.kind === "ref") {
|
|
4556
4722
|
const ref = lengthObj;
|
|
4557
4723
|
const resolved = this.registry.resolve(ref);
|
|
4558
4724
|
if (resolved !== void 0) {
|
|
4559
|
-
if (resolved.kind !== "number") throw new
|
|
4725
|
+
if (resolved.kind !== "number") throw new PdfParseError({
|
|
4726
|
+
message: `PdfObjectParser.resolveStreamLength: /Length reference ${ref.objectNumber} ${ref.generationNumber} R resolved to ${resolved.kind}, expected number`,
|
|
4727
|
+
offset: this.lexer.position,
|
|
4728
|
+
expected: "number for /Length reference",
|
|
4729
|
+
actual: `${resolved.kind}`,
|
|
4730
|
+
data: this.lexer.rawData
|
|
4731
|
+
});
|
|
4560
4732
|
return resolved.value;
|
|
4561
4733
|
}
|
|
4562
|
-
throw new
|
|
4734
|
+
throw new PdfParseError({
|
|
4735
|
+
message: `PdfObjectParser.resolveStreamLength: /Length reference ${ref.objectNumber} ${ref.generationNumber} R is not yet resolved in the registry. Parse the referenced object first.`,
|
|
4736
|
+
offset: this.lexer.position,
|
|
4737
|
+
expected: "resolved /Length reference",
|
|
4738
|
+
actual: `unresolved reference ${ref.objectNumber} ${ref.generationNumber} R`,
|
|
4739
|
+
data: this.lexer.rawData
|
|
4740
|
+
});
|
|
4563
4741
|
}
|
|
4564
|
-
throw new
|
|
4742
|
+
throw new PdfParseError({
|
|
4743
|
+
message: `PdfObjectParser.resolveStreamLength: /Length must be a number or indirect reference, got ${lengthObj.kind}`,
|
|
4744
|
+
offset: this.lexer.position,
|
|
4745
|
+
expected: "number or indirect reference for /Length",
|
|
4746
|
+
actual: `${lengthObj.kind}`,
|
|
4747
|
+
data: this.lexer.rawData
|
|
4748
|
+
});
|
|
4565
4749
|
}
|
|
4566
4750
|
};
|
|
4567
4751
|
|
|
@@ -4642,10 +4826,10 @@ async function tryLoadLibdeflate() {
|
|
|
4642
4826
|
if (libdeflateAttempted) return libdeflateEngine;
|
|
4643
4827
|
libdeflateAttempted = true;
|
|
4644
4828
|
try {
|
|
4645
|
-
const { LibdeflateWasm: LibdeflateCtor, initDeflateWasm } = await import("./libdeflateWasm-
|
|
4829
|
+
const { LibdeflateWasm: LibdeflateCtor, initDeflateWasm } = await import("./libdeflateWasm-DlHgU5oy.mjs").then((n) => n.r);
|
|
4646
4830
|
let customBytes;
|
|
4647
4831
|
try {
|
|
4648
|
-
const { getWasmLoaderConfig } = await import("./loader-
|
|
4832
|
+
const { getWasmLoaderConfig } = await import("./loader-CQfoGFp9.mjs");
|
|
4649
4833
|
customBytes = getWasmLoaderConfig().moduleBytes?.["libdeflate"];
|
|
4650
4834
|
} catch {}
|
|
4651
4835
|
await initDeflateWasm(customBytes);
|
|
@@ -4763,9 +4947,19 @@ function stringToLatin1Bytes(str) {
|
|
|
4763
4947
|
*/
|
|
4764
4948
|
function extractTrailer(dict) {
|
|
4765
4949
|
const sizeVal = numVal$2(dict.get("/Size"));
|
|
4766
|
-
if (sizeVal === void 0) throw new
|
|
4950
|
+
if (sizeVal === void 0) throw new PdfParseError({
|
|
4951
|
+
message: "Invalid PDF: trailer dictionary missing /Size entry",
|
|
4952
|
+
offset: 0,
|
|
4953
|
+
expected: "/Size entry in trailer dictionary",
|
|
4954
|
+
actual: "no /Size entry"
|
|
4955
|
+
});
|
|
4767
4956
|
const rootRef = refVal(dict.get("/Root"));
|
|
4768
|
-
if (rootRef === void 0) throw new
|
|
4957
|
+
if (rootRef === void 0) throw new PdfParseError({
|
|
4958
|
+
message: "Invalid PDF: trailer dictionary missing /Root entry",
|
|
4959
|
+
offset: 0,
|
|
4960
|
+
expected: "/Root entry in trailer dictionary",
|
|
4961
|
+
actual: "no /Root entry"
|
|
4962
|
+
});
|
|
4769
4963
|
const trailer = {
|
|
4770
4964
|
size: sizeVal,
|
|
4771
4965
|
rootRef
|
|
@@ -4804,7 +4998,12 @@ async function decodeStream$1(streamData, dict) {
|
|
|
4804
4998
|
const arr = filter;
|
|
4805
4999
|
if (arr.length > 0 && arr.items[0].kind === "name") filterName = arr.items[0].value;
|
|
4806
5000
|
}
|
|
4807
|
-
if (filterName !== "/FlateDecode") throw new
|
|
5001
|
+
if (filterName !== "/FlateDecode") throw new PdfParseError({
|
|
5002
|
+
message: `Unsupported xref stream filter: ${filterName ?? "unknown"}. Only /FlateDecode is supported for cross-reference streams.`,
|
|
5003
|
+
offset: 0,
|
|
5004
|
+
expected: "/FlateDecode filter",
|
|
5005
|
+
actual: `${filterName ?? "unknown"} filter`
|
|
5006
|
+
});
|
|
4808
5007
|
let decompressed = await decompress(streamData);
|
|
4809
5008
|
const decodeParms = dict.get("/DecodeParms");
|
|
4810
5009
|
if (decodeParms !== void 0 && decodeParms.kind === "dict") {
|
|
@@ -4938,11 +5137,30 @@ var XrefParser = class {
|
|
|
4938
5137
|
const startPos = this.data.length - searchWindow;
|
|
4939
5138
|
const tail = TEXT_DECODER$1.decode(this.data.subarray(startPos, this.data.length));
|
|
4940
5139
|
const idx = tail.lastIndexOf("startxref");
|
|
4941
|
-
if (idx === -1) throw new
|
|
4942
|
-
|
|
4943
|
-
|
|
5140
|
+
if (idx === -1) throw new PdfParseError({
|
|
5141
|
+
message: "Invalid PDF: could not find \"startxref\" marker in the last 2048 bytes. The file may be truncated or corrupt.",
|
|
5142
|
+
offset: startPos,
|
|
5143
|
+
expected: "\"startxref\" marker near end of file",
|
|
5144
|
+
actual: "no \"startxref\" found",
|
|
5145
|
+
data: this.data
|
|
5146
|
+
});
|
|
5147
|
+
const afterKeyword = tail.substring(idx + 9).trim();
|
|
5148
|
+
const match = afterKeyword.match(/^(\d+)/);
|
|
5149
|
+
if (!match) throw new PdfParseError({
|
|
5150
|
+
message: "Invalid PDF: \"startxref\" found but no valid offset follows it.",
|
|
5151
|
+
offset: startPos + idx,
|
|
5152
|
+
expected: "decimal offset after \"startxref\"",
|
|
5153
|
+
actual: `"${afterKeyword.substring(0, 20)}"`,
|
|
5154
|
+
data: this.data
|
|
5155
|
+
});
|
|
4944
5156
|
const offset = parseInt(match[1], 10);
|
|
4945
|
-
if (offset < 0 || offset >= this.data.length) throw new
|
|
5157
|
+
if (offset < 0 || offset >= this.data.length) throw new PdfParseError({
|
|
5158
|
+
message: `Invalid PDF: startxref offset ${offset} is out of range (file size: ${this.data.length}).`,
|
|
5159
|
+
offset: startPos + idx,
|
|
5160
|
+
expected: `offset in range [0, ${this.data.length})`,
|
|
5161
|
+
actual: `${offset}`,
|
|
5162
|
+
data: this.data
|
|
5163
|
+
});
|
|
4946
5164
|
return offset;
|
|
4947
5165
|
}
|
|
4948
5166
|
/**
|
|
@@ -4995,7 +5213,13 @@ var XrefParser = class {
|
|
|
4995
5213
|
const prevVal = numVal$2(trailerDict.get("/Prev"));
|
|
4996
5214
|
currentOffset = prevVal !== void 0 && prevVal >= 0 ? prevVal : void 0;
|
|
4997
5215
|
}
|
|
4998
|
-
if (primaryTrailer === void 0) throw new
|
|
5216
|
+
if (primaryTrailer === void 0) throw new PdfParseError({
|
|
5217
|
+
message: "Invalid PDF: could not extract a valid trailer from the cross-reference structure.",
|
|
5218
|
+
offset: startOffset,
|
|
5219
|
+
expected: "valid trailer dictionary in cross-reference structure",
|
|
5220
|
+
actual: "no valid trailer found",
|
|
5221
|
+
data: this.data
|
|
5222
|
+
});
|
|
4999
5223
|
return {
|
|
5000
5224
|
entries,
|
|
5001
5225
|
trailer: primaryTrailer
|
|
@@ -5022,40 +5246,82 @@ var XrefParser = class {
|
|
|
5022
5246
|
parseTraditionalXref(offset) {
|
|
5023
5247
|
const entries = [];
|
|
5024
5248
|
let pos = offset;
|
|
5025
|
-
|
|
5026
|
-
|
|
5249
|
+
if (!this.isTraditionalXref(pos)) {
|
|
5250
|
+
const xrefTag = TEXT_DECODER$1.decode(this.data.subarray(pos, pos + 4));
|
|
5251
|
+
throw new PdfParseError({
|
|
5252
|
+
message: `Invalid PDF: expected "xref" keyword at offset ${offset}, found "${xrefTag}".`,
|
|
5253
|
+
offset,
|
|
5254
|
+
expected: "\"xref\" keyword",
|
|
5255
|
+
actual: `"${xrefTag}"`,
|
|
5256
|
+
data: this.data
|
|
5257
|
+
});
|
|
5258
|
+
}
|
|
5027
5259
|
pos += 4;
|
|
5028
5260
|
pos = this.skipWhitespaceAt(pos);
|
|
5029
5261
|
while (pos < this.data.length) {
|
|
5030
|
-
if (
|
|
5262
|
+
if (this.matchesBytes(pos, 116, 114, 97, 105, 108, 101, 114)) break;
|
|
5031
5263
|
const headerLine = this.readLineAt(pos);
|
|
5032
5264
|
const headerMatch = headerLine.text.trim().match(/^(\d+)\s+(\d+)/);
|
|
5033
|
-
if (!headerMatch) throw new
|
|
5265
|
+
if (!headerMatch) throw new PdfParseError({
|
|
5266
|
+
message: `Invalid PDF: malformed xref subsection header at offset ${pos}: "${headerLine.text.trim()}"`,
|
|
5267
|
+
offset: pos,
|
|
5268
|
+
expected: "xref subsection header \"firstObjNum count\"",
|
|
5269
|
+
actual: `"${headerLine.text.trim()}"`,
|
|
5270
|
+
data: this.data
|
|
5271
|
+
});
|
|
5034
5272
|
const firstObjNum = parseInt(headerMatch[1], 10);
|
|
5035
5273
|
const count = parseInt(headerMatch[2], 10);
|
|
5036
5274
|
pos = headerLine.nextPos;
|
|
5037
5275
|
for (let i = 0; i < count; i++) {
|
|
5038
5276
|
const objectNumber = firstObjNum + i;
|
|
5039
|
-
const
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5277
|
+
const parsed = this.parseXrefEntryDirect(pos);
|
|
5278
|
+
if (parsed) {
|
|
5279
|
+
entries.push({
|
|
5280
|
+
objectNumber,
|
|
5281
|
+
generationNumber: parsed.gen,
|
|
5282
|
+
offset: parsed.offset,
|
|
5283
|
+
type: parsed.type
|
|
5284
|
+
});
|
|
5285
|
+
pos = parsed.nextPos;
|
|
5286
|
+
} else {
|
|
5287
|
+
const entryText = this.readXrefEntryAt(pos);
|
|
5288
|
+
const entryMatch = entryText.text.trim().match(/^(\d{10})\s+(\d{5})\s+([fn])/);
|
|
5289
|
+
if (!entryMatch) throw new PdfParseError({
|
|
5290
|
+
message: `Invalid PDF: malformed xref entry at offset ${pos} for object ${objectNumber}: "${entryText.text.trim()}"`,
|
|
5291
|
+
offset: pos,
|
|
5292
|
+
expected: "xref entry \"OOOOOOOOOO GGGGG f/n\"",
|
|
5293
|
+
actual: `"${entryText.text.trim()}"`,
|
|
5294
|
+
data: this.data
|
|
5295
|
+
});
|
|
5296
|
+
entries.push({
|
|
5297
|
+
objectNumber,
|
|
5298
|
+
generationNumber: parseInt(entryMatch[2], 10),
|
|
5299
|
+
offset: parseInt(entryMatch[1], 10),
|
|
5300
|
+
type: entryMatch[3] === "n" ? "in-use" : "free"
|
|
5301
|
+
});
|
|
5302
|
+
pos = entryText.nextPos;
|
|
5303
|
+
}
|
|
5052
5304
|
}
|
|
5053
5305
|
}
|
|
5054
|
-
|
|
5055
|
-
|
|
5306
|
+
if (!this.matchesBytes(pos, 116, 114, 97, 105, 108, 101, 114)) {
|
|
5307
|
+
const trailerTag = TEXT_DECODER$1.decode(this.data.subarray(pos, pos + 7));
|
|
5308
|
+
throw new PdfParseError({
|
|
5309
|
+
message: `Invalid PDF: expected "trailer" keyword at offset ${pos}, found "${trailerTag}".`,
|
|
5310
|
+
offset: pos,
|
|
5311
|
+
expected: "\"trailer\" keyword",
|
|
5312
|
+
actual: `"${trailerTag}"`,
|
|
5313
|
+
data: this.data
|
|
5314
|
+
});
|
|
5315
|
+
}
|
|
5056
5316
|
pos += 7;
|
|
5057
5317
|
const trailerObj = this.objectParser.parseObjectAt(pos);
|
|
5058
|
-
if (trailerObj.kind !== "dict") throw new
|
|
5318
|
+
if (trailerObj.kind !== "dict") throw new PdfParseError({
|
|
5319
|
+
message: `Invalid PDF: expected dictionary after "trailer" keyword at offset ${pos}, got ${trailerObj.kind}.`,
|
|
5320
|
+
offset: pos,
|
|
5321
|
+
expected: "dictionary after \"trailer\" keyword",
|
|
5322
|
+
actual: `${trailerObj.kind}`,
|
|
5323
|
+
data: this.data
|
|
5324
|
+
});
|
|
5059
5325
|
return {
|
|
5060
5326
|
entries,
|
|
5061
5327
|
trailerDict: trailerObj
|
|
@@ -5074,22 +5340,58 @@ var XrefParser = class {
|
|
|
5074
5340
|
*/
|
|
5075
5341
|
async parseXrefStream(offset) {
|
|
5076
5342
|
const { object } = this.objectParser.parseIndirectObjectAt(offset);
|
|
5077
|
-
if (object.kind !== "stream") throw new
|
|
5343
|
+
if (object.kind !== "stream") throw new PdfParseError({
|
|
5344
|
+
message: `Invalid PDF: expected stream object at offset ${offset} for xref stream, got ${object.kind}.`,
|
|
5345
|
+
offset,
|
|
5346
|
+
expected: "stream object for xref stream",
|
|
5347
|
+
actual: `${object.kind}`,
|
|
5348
|
+
data: this.data
|
|
5349
|
+
});
|
|
5078
5350
|
const stream = object;
|
|
5079
5351
|
const dict = stream.dict;
|
|
5080
5352
|
const typeObj = dict.get("/Type");
|
|
5081
|
-
if (typeObj === void 0 || typeObj.kind !== "name" || typeObj.value !== "/XRef") throw new
|
|
5353
|
+
if (typeObj === void 0 || typeObj.kind !== "name" || typeObj.value !== "/XRef") throw new PdfParseError({
|
|
5354
|
+
message: `Invalid PDF: cross-reference stream at offset ${offset} does not have /Type /XRef.`,
|
|
5355
|
+
offset,
|
|
5356
|
+
expected: "/Type /XRef in cross-reference stream dictionary",
|
|
5357
|
+
actual: typeObj ? `${typeObj.kind}` : "no /Type entry",
|
|
5358
|
+
data: this.data
|
|
5359
|
+
});
|
|
5082
5360
|
const wObj = dict.get("/W");
|
|
5083
|
-
if (wObj === void 0 || wObj.kind !== "array") throw new
|
|
5361
|
+
if (wObj === void 0 || wObj.kind !== "array") throw new PdfParseError({
|
|
5362
|
+
message: "Invalid PDF: cross-reference stream missing /W (field widths) array.",
|
|
5363
|
+
offset,
|
|
5364
|
+
expected: "/W array in cross-reference stream",
|
|
5365
|
+
actual: wObj ? `${wObj.kind}` : "no /W entry",
|
|
5366
|
+
data: this.data
|
|
5367
|
+
});
|
|
5084
5368
|
const wArr = wObj;
|
|
5085
|
-
if (wArr.length < 3) throw new
|
|
5369
|
+
if (wArr.length < 3) throw new PdfParseError({
|
|
5370
|
+
message: "Invalid PDF: cross-reference stream /W array must have at least 3 elements.",
|
|
5371
|
+
offset,
|
|
5372
|
+
expected: "/W array with at least 3 elements",
|
|
5373
|
+
actual: `/W array with ${wArr.length} element(s)`,
|
|
5374
|
+
data: this.data
|
|
5375
|
+
});
|
|
5086
5376
|
const w0 = numVal$2(wArr.items[0]) ?? 0;
|
|
5087
5377
|
const w1 = numVal$2(wArr.items[1]) ?? 0;
|
|
5088
5378
|
const w2 = numVal$2(wArr.items[2]) ?? 0;
|
|
5089
5379
|
const entryWidth = w0 + w1 + w2;
|
|
5090
|
-
if (entryWidth === 0) throw new
|
|
5380
|
+
if (entryWidth === 0) throw new PdfParseError({
|
|
5381
|
+
message: "Invalid PDF: cross-reference stream /W widths sum to 0.",
|
|
5382
|
+
offset,
|
|
5383
|
+
expected: "non-zero sum of /W widths",
|
|
5384
|
+
actual: "0",
|
|
5385
|
+
data: this.data
|
|
5386
|
+
});
|
|
5091
5387
|
const size = numVal$2(dict.get("/Size"));
|
|
5092
|
-
if (size === void 0) throw new
|
|
5388
|
+
if (size === void 0) throw new PdfParseError({
|
|
5389
|
+
message: "Invalid PDF: cross-reference stream missing /Size.",
|
|
5390
|
+
offset,
|
|
5391
|
+
expected: "/Size entry in cross-reference stream",
|
|
5392
|
+
actual: "no /Size entry",
|
|
5393
|
+
data: this.data
|
|
5394
|
+
});
|
|
5093
5395
|
let subsections;
|
|
5094
5396
|
const indexObj = dict.get("/Index");
|
|
5095
5397
|
if (indexObj !== void 0 && indexObj.kind === "array") {
|
|
@@ -5165,24 +5467,50 @@ var XrefParser = class {
|
|
|
5165
5467
|
*/
|
|
5166
5468
|
rebuildXrefFromScan() {
|
|
5167
5469
|
const entries = /* @__PURE__ */ new Map();
|
|
5168
|
-
const
|
|
5169
|
-
const
|
|
5170
|
-
let
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5470
|
+
const d = this.data;
|
|
5471
|
+
const len = d.length;
|
|
5472
|
+
for (let i = 0; i < len - 2; i++) {
|
|
5473
|
+
if (d[i] !== 111 || d[i + 1] !== 98 || d[i + 2] !== 106) continue;
|
|
5474
|
+
if (i + 3 < len) {
|
|
5475
|
+
const after = d[i + 3];
|
|
5476
|
+
if (after > 32 && after !== 37 && after !== 40 && after !== 41 && after !== 47 && after !== 60 && after !== 62 && after !== 91 && after !== 93 && after !== 123 && after !== 125) continue;
|
|
5477
|
+
}
|
|
5478
|
+
let j = i - 1;
|
|
5479
|
+
while (j >= 0 && (d[j] === 32 || d[j] === 10 || d[j] === 13 || d[j] === 9 || d[j] === 0)) j--;
|
|
5480
|
+
const genEnd = j + 1;
|
|
5481
|
+
while (j >= 0 && d[j] >= 48 && d[j] <= 57) j--;
|
|
5482
|
+
const genStart = j + 1;
|
|
5483
|
+
if (genStart >= genEnd) continue;
|
|
5484
|
+
while (j >= 0 && (d[j] === 32 || d[j] === 10 || d[j] === 13 || d[j] === 9 || d[j] === 0)) j--;
|
|
5485
|
+
const objEnd = j + 1;
|
|
5486
|
+
while (j >= 0 && d[j] >= 48 && d[j] <= 57) j--;
|
|
5487
|
+
const objStart = j + 1;
|
|
5488
|
+
if (objStart >= objEnd) continue;
|
|
5489
|
+
let objectNumber = 0;
|
|
5490
|
+
for (let k = objStart; k < objEnd; k++) objectNumber = objectNumber * 10 + (d[k] - 48);
|
|
5491
|
+
let gen = 0;
|
|
5492
|
+
for (let k = genStart; k < genEnd; k++) gen = gen * 10 + (d[k] - 48);
|
|
5175
5493
|
entries.set(objectNumber, {
|
|
5176
5494
|
objectNumber,
|
|
5177
5495
|
generationNumber: gen,
|
|
5178
|
-
offset,
|
|
5496
|
+
offset: objStart,
|
|
5179
5497
|
type: "in-use"
|
|
5180
5498
|
});
|
|
5181
5499
|
}
|
|
5182
|
-
if (entries.size === 0) throw new
|
|
5500
|
+
if (entries.size === 0) throw new PdfParseError({
|
|
5501
|
+
message: "Invalid PDF: could not find any indirect objects during recovery scan. The file may not be a valid PDF.",
|
|
5502
|
+
offset: 0,
|
|
5503
|
+
expected: "at least one \"N G obj\" pattern in file",
|
|
5504
|
+
actual: "no indirect objects found",
|
|
5505
|
+
data: this.data
|
|
5506
|
+
});
|
|
5183
5507
|
let rootRef;
|
|
5184
5508
|
let infoRef;
|
|
5185
|
-
|
|
5509
|
+
let trailerIdx = -1;
|
|
5510
|
+
for (let i = len - 7; i >= 0; i--) if (d[i] === 116 && d[i + 1] === 114 && d[i + 2] === 97 && d[i + 3] === 105 && d[i + 4] === 108 && d[i + 5] === 101 && d[i + 6] === 114) {
|
|
5511
|
+
trailerIdx = i;
|
|
5512
|
+
break;
|
|
5513
|
+
}
|
|
5186
5514
|
if (trailerIdx !== -1) try {
|
|
5187
5515
|
const trailerObj = this.objectParser.parseObjectAt(trailerIdx + 7);
|
|
5188
5516
|
if (trailerObj.kind === "dict") {
|
|
@@ -5202,7 +5530,13 @@ var XrefParser = class {
|
|
|
5202
5530
|
}
|
|
5203
5531
|
}
|
|
5204
5532
|
} catch {}
|
|
5205
|
-
if (rootRef === void 0) throw new
|
|
5533
|
+
if (rootRef === void 0) throw new PdfParseError({
|
|
5534
|
+
message: "Invalid PDF: recovery scan could not locate the document catalog (/Root). The file appears to be severely corrupt.",
|
|
5535
|
+
offset: 0,
|
|
5536
|
+
expected: "document catalog (/Type /Catalog) in recovery scan",
|
|
5537
|
+
actual: "no /Root or /Catalog found",
|
|
5538
|
+
data: this.data
|
|
5539
|
+
});
|
|
5206
5540
|
const trailer = {
|
|
5207
5541
|
size: (entries.size > 0 ? entries.keys().reduce((max, n) => Math.max(max, n), 0) : 0) + 1,
|
|
5208
5542
|
rootRef
|
|
@@ -5217,6 +5551,48 @@ var XrefParser = class {
|
|
|
5217
5551
|
* Determine whether the data at the given offset starts with the
|
|
5218
5552
|
* "xref" keyword (indicating a traditional xref table).
|
|
5219
5553
|
*/
|
|
5554
|
+
/**
|
|
5555
|
+
* Check if the bytes at `pos` match the given byte values.
|
|
5556
|
+
*/
|
|
5557
|
+
matchesBytes(pos, ...bytes) {
|
|
5558
|
+
if (pos + bytes.length > this.data.length) return false;
|
|
5559
|
+
for (let i = 0; i < bytes.length; i++) if (this.data[pos + i] !== bytes[i]) return false;
|
|
5560
|
+
return true;
|
|
5561
|
+
}
|
|
5562
|
+
/**
|
|
5563
|
+
* Parse a standard xref entry directly from bytes, avoiding TextDecoder
|
|
5564
|
+
* and regex. Returns null if the bytes don't form a valid entry.
|
|
5565
|
+
*
|
|
5566
|
+
* Standard format: `OOOOOOOOOO GGGGG f/n` (18 significant bytes)
|
|
5567
|
+
*/
|
|
5568
|
+
parseXrefEntryDirect(pos) {
|
|
5569
|
+
const d = this.data;
|
|
5570
|
+
if (pos + 18 > d.length) return null;
|
|
5571
|
+
let offset = 0;
|
|
5572
|
+
for (let k = 0; k < 10; k++) {
|
|
5573
|
+
const b = d[pos + k];
|
|
5574
|
+
if (b < 48 || b > 57) return null;
|
|
5575
|
+
offset = offset * 10 + (b - 48);
|
|
5576
|
+
}
|
|
5577
|
+
if (d[pos + 10] !== 32) return null;
|
|
5578
|
+
let gen = 0;
|
|
5579
|
+
for (let k = 0; k < 5; k++) {
|
|
5580
|
+
const b = d[pos + 11 + k];
|
|
5581
|
+
if (b < 48 || b > 57) return null;
|
|
5582
|
+
gen = gen * 10 + (b - 48);
|
|
5583
|
+
}
|
|
5584
|
+
if (d[pos + 16] !== 32) return null;
|
|
5585
|
+
const marker = d[pos + 17];
|
|
5586
|
+
if (marker !== 110 && marker !== 102) return null;
|
|
5587
|
+
let nextPos = pos + 18;
|
|
5588
|
+
while (nextPos < d.length && (d[nextPos] === 32 || d[nextPos] === 13 || d[nextPos] === 10)) nextPos++;
|
|
5589
|
+
return {
|
|
5590
|
+
offset,
|
|
5591
|
+
gen,
|
|
5592
|
+
type: marker === 110 ? "in-use" : "free",
|
|
5593
|
+
nextPos
|
|
5594
|
+
};
|
|
5595
|
+
}
|
|
5220
5596
|
isTraditionalXref(offset) {
|
|
5221
5597
|
if (offset + 4 > this.data.length) return false;
|
|
5222
5598
|
return this.data[offset] === 120 && this.data[offset + 1] === 114 && this.data[offset + 2] === 101 && this.data[offset + 3] === 102;
|
|
@@ -6014,10 +6390,12 @@ function computeOwnerPasswordValue(ownerPassword, userPassword, revision, keyLen
|
|
|
6014
6390
|
if (revision >= 3) for (let i = 0; i < 50; i++) hash = md5(hash.subarray(0, keyByteLength));
|
|
6015
6391
|
const rc4Key = hash.subarray(0, keyByteLength);
|
|
6016
6392
|
let encrypted = rc4(rc4Key, padPassword(userPassword));
|
|
6017
|
-
if (revision >= 3)
|
|
6393
|
+
if (revision >= 3) {
|
|
6018
6394
|
const modKey = new Uint8Array(rc4Key.length);
|
|
6019
|
-
for (let
|
|
6020
|
-
|
|
6395
|
+
for (let i = 1; i <= 19; i++) {
|
|
6396
|
+
for (let j = 0; j < rc4Key.length; j++) modKey[j] = (rc4Key[j] ^ i) & 255;
|
|
6397
|
+
encrypted = rc4(modKey, encrypted);
|
|
6398
|
+
}
|
|
6021
6399
|
}
|
|
6022
6400
|
return encrypted;
|
|
6023
6401
|
}
|
|
@@ -6047,10 +6425,12 @@ function computeUserPasswordR2(fileKey) {
|
|
|
6047
6425
|
*/
|
|
6048
6426
|
function computeUserPasswordR3R4(fileKey, fileId) {
|
|
6049
6427
|
let encrypted = rc4(fileKey, md5(concat$1(PASSWORD_PADDING, fileId)));
|
|
6050
|
-
|
|
6428
|
+
{
|
|
6051
6429
|
const modKey = new Uint8Array(fileKey.length);
|
|
6052
|
-
for (let
|
|
6053
|
-
|
|
6430
|
+
for (let i = 1; i <= 19; i++) {
|
|
6431
|
+
for (let j = 0; j < fileKey.length; j++) modKey[j] = (fileKey[j] ^ i) & 255;
|
|
6432
|
+
encrypted = rc4(modKey, encrypted);
|
|
6433
|
+
}
|
|
6054
6434
|
}
|
|
6055
6435
|
const result = new Uint8Array(32);
|
|
6056
6436
|
result.set(encrypted.subarray(0, 16));
|
|
@@ -6116,9 +6496,17 @@ async function algorithm2B(password, salt, uKey) {
|
|
|
6116
6496
|
let K = await sha256(uKey ? concat$1(password, salt, uKey) : concat$1(password, salt));
|
|
6117
6497
|
let round = 0;
|
|
6118
6498
|
while (true) {
|
|
6119
|
-
const
|
|
6120
|
-
const
|
|
6121
|
-
|
|
6499
|
+
const pLen = password.length;
|
|
6500
|
+
const kLen = K.length;
|
|
6501
|
+
const uLen = uKey ? uKey.length : 0;
|
|
6502
|
+
const blockLen = pLen + kLen + uLen;
|
|
6503
|
+
const K1 = new Uint8Array(blockLen * 64);
|
|
6504
|
+
for (let i = 0; i < 64; i++) {
|
|
6505
|
+
const base = i * blockLen;
|
|
6506
|
+
K1.set(password, base);
|
|
6507
|
+
K1.set(K, base + pLen);
|
|
6508
|
+
if (uKey) K1.set(uKey, base + pLen + kLen);
|
|
6509
|
+
}
|
|
6122
6510
|
const E = await aesEncryptCBCNoPad(K.subarray(0, 16), K.subarray(16, 32), K1);
|
|
6123
6511
|
let bigModVal = 0;
|
|
6124
6512
|
for (let i = 0; i < 16; i++) bigModVal = (bigModVal * 256 + E[i]) % 3;
|
|
@@ -6915,7 +7303,13 @@ var PdfDocumentParser = class {
|
|
|
6915
7303
|
* @param data The raw PDF file bytes as a Uint8Array.
|
|
6916
7304
|
*/
|
|
6917
7305
|
constructor(data) {
|
|
6918
|
-
if (data.length < 8) throw new
|
|
7306
|
+
if (data.length < 8) throw new PdfParseError({
|
|
7307
|
+
message: "Invalid PDF: file is too short to contain a valid PDF header.",
|
|
7308
|
+
offset: 0,
|
|
7309
|
+
expected: "at least 8 bytes for a valid PDF header",
|
|
7310
|
+
actual: `${data.length} bytes`,
|
|
7311
|
+
data
|
|
7312
|
+
});
|
|
6919
7313
|
this.data = data;
|
|
6920
7314
|
}
|
|
6921
7315
|
/**
|
|
@@ -6966,7 +7360,14 @@ var PdfDocumentParser = class {
|
|
|
6966
7360
|
const { object } = this.objectParser.parseIndirectObjectAt(entry.offset);
|
|
6967
7361
|
resolved = object;
|
|
6968
7362
|
} catch (err) {
|
|
6969
|
-
throw new
|
|
7363
|
+
throw new PdfParseError({
|
|
7364
|
+
message: `Failed to parse indirect object ${objNum} ${entry.generationNumber} at offset ${entry.offset}`,
|
|
7365
|
+
offset: entry.offset,
|
|
7366
|
+
expected: `valid indirect object ${objNum} ${entry.generationNumber}`,
|
|
7367
|
+
actual: "parse failure",
|
|
7368
|
+
data: this.data,
|
|
7369
|
+
cause: err instanceof Error ? err : void 0
|
|
7370
|
+
});
|
|
6970
7371
|
}
|
|
6971
7372
|
this.objectCache.set(objNum, resolved);
|
|
6972
7373
|
return resolved;
|
|
@@ -6990,7 +7391,13 @@ var PdfDocumentParser = class {
|
|
|
6990
7391
|
const encryptRef = this.trailer.encryptRef;
|
|
6991
7392
|
this.encryptDictObjNum = encryptRef.objectNumber;
|
|
6992
7393
|
const encryptObj = this.resolveRef(encryptRef);
|
|
6993
|
-
if (encryptObj.kind !== "dict") throw new
|
|
7394
|
+
if (encryptObj.kind !== "dict") throw new PdfParseError({
|
|
7395
|
+
message: "Invalid PDF: /Encrypt entry is not a dictionary.",
|
|
7396
|
+
offset: 0,
|
|
7397
|
+
expected: "dictionary for /Encrypt entry",
|
|
7398
|
+
actual: `${encryptObj.kind}`,
|
|
7399
|
+
data: this.data
|
|
7400
|
+
});
|
|
6994
7401
|
const encryptDict = encryptObj;
|
|
6995
7402
|
const fileId = this.trailer.id?.[0] ?? new Uint8Array(0);
|
|
6996
7403
|
const passwordsToTry = [];
|
|
@@ -7005,8 +7412,21 @@ var PdfDocumentParser = class {
|
|
|
7005
7412
|
} catch (err) {
|
|
7006
7413
|
lastError = err instanceof Error ? err : new Error(String(err));
|
|
7007
7414
|
}
|
|
7008
|
-
if (password !== void 0) throw new
|
|
7009
|
-
|
|
7415
|
+
if (password !== void 0) throw new PdfParseError({
|
|
7416
|
+
message: `Failed to decrypt PDF: the provided password is incorrect. ${lastError?.message ?? ""}`,
|
|
7417
|
+
offset: 0,
|
|
7418
|
+
expected: "valid decryption password",
|
|
7419
|
+
actual: "incorrect password",
|
|
7420
|
+
data: this.data,
|
|
7421
|
+
cause: lastError
|
|
7422
|
+
});
|
|
7423
|
+
else throw new PdfParseError({
|
|
7424
|
+
message: "This PDF is encrypted and requires a password. Pass { password: \"...\" } in the options to decrypt it.",
|
|
7425
|
+
offset: 0,
|
|
7426
|
+
expected: "unencrypted PDF or password option",
|
|
7427
|
+
actual: "encrypted PDF without password",
|
|
7428
|
+
data: this.data
|
|
7429
|
+
});
|
|
7010
7430
|
}
|
|
7011
7431
|
/**
|
|
7012
7432
|
* Decrypt all resolved objects in the object cache.
|
|
@@ -7102,7 +7522,12 @@ var PdfDocumentParser = class {
|
|
|
7102
7522
|
* @throws If the page index is out of range.
|
|
7103
7523
|
*/
|
|
7104
7524
|
getPageDict(pageIndex) {
|
|
7105
|
-
if (pageIndex < 0 || pageIndex >= this.flattenedPages.length) throw new
|
|
7525
|
+
if (pageIndex < 0 || pageIndex >= this.flattenedPages.length) throw new PdfParseError({
|
|
7526
|
+
message: `Page index ${pageIndex} is out of range. The document has ${this.flattenedPages.length} page(s).`,
|
|
7527
|
+
offset: 0,
|
|
7528
|
+
expected: `page index in range [0, ${this.flattenedPages.length})`,
|
|
7529
|
+
actual: `${pageIndex}`
|
|
7530
|
+
});
|
|
7106
7531
|
return this.flattenedPages[pageIndex].dict;
|
|
7107
7532
|
}
|
|
7108
7533
|
/**
|
|
@@ -7122,16 +7547,34 @@ var PdfDocumentParser = class {
|
|
|
7122
7547
|
validateHeader() {
|
|
7123
7548
|
const header = TEXT_DECODER.decode(this.data.subarray(0, Math.min(1024, this.data.length)));
|
|
7124
7549
|
const pdfIdx = header.indexOf("%PDF-");
|
|
7125
|
-
if (pdfIdx === -1 || pdfIdx > 1024) throw new
|
|
7550
|
+
if (pdfIdx === -1 || pdfIdx > 1024) throw new PdfParseError({
|
|
7551
|
+
message: "Invalid PDF: file does not start with \"%PDF-\" header. This may not be a PDF file.",
|
|
7552
|
+
offset: 0,
|
|
7553
|
+
expected: "\"%PDF-\" header near start of file",
|
|
7554
|
+
actual: "no \"%PDF-\" marker found",
|
|
7555
|
+
data: this.data
|
|
7556
|
+
});
|
|
7126
7557
|
const versionMatch = header.substring(pdfIdx).match(/%PDF-(\d+\.\d+)/);
|
|
7127
|
-
if (!versionMatch) throw new
|
|
7558
|
+
if (!versionMatch) throw new PdfParseError({
|
|
7559
|
+
message: "Invalid PDF: could not parse version from header.",
|
|
7560
|
+
offset: pdfIdx,
|
|
7561
|
+
expected: "\"%PDF-X.Y\" version string",
|
|
7562
|
+
actual: `"${header.substring(pdfIdx, pdfIdx + 10)}"`,
|
|
7563
|
+
data: this.data
|
|
7564
|
+
});
|
|
7128
7565
|
this.pdfVersion = versionMatch[1];
|
|
7129
7566
|
const majorMinor = this.pdfVersion.split(".");
|
|
7130
7567
|
const major = parseInt(majorMinor[0], 10);
|
|
7131
7568
|
const minor = parseInt(majorMinor[1], 10);
|
|
7132
7569
|
if (major === 1 && minor >= 0 && minor <= 9) return;
|
|
7133
7570
|
if (major === 2 && minor >= 0) return;
|
|
7134
|
-
throw new
|
|
7571
|
+
throw new PdfParseError({
|
|
7572
|
+
message: `Unsupported PDF version: ${this.pdfVersion}. Expected PDF 1.0-1.9 or 2.0+.`,
|
|
7573
|
+
offset: 0,
|
|
7574
|
+
expected: "PDF version 1.0-1.9 or 2.0+",
|
|
7575
|
+
actual: `PDF version ${this.pdfVersion}`,
|
|
7576
|
+
data: this.data
|
|
7577
|
+
});
|
|
7135
7578
|
}
|
|
7136
7579
|
/**
|
|
7137
7580
|
* Resolve the document catalog dictionary from the trailer's /Root
|
|
@@ -7139,12 +7582,24 @@ var PdfDocumentParser = class {
|
|
|
7139
7582
|
*/
|
|
7140
7583
|
resolveCatalog() {
|
|
7141
7584
|
const rootObj = this.resolveRef(this.trailer.rootRef);
|
|
7142
|
-
if (rootObj.kind !== "dict") throw new
|
|
7585
|
+
if (rootObj.kind !== "dict") throw new PdfParseError({
|
|
7586
|
+
message: `Invalid PDF: /Root (catalog) at object ${this.trailer.rootRef.objectNumber} is not a dictionary (got ${rootObj.kind}).`,
|
|
7587
|
+
offset: 0,
|
|
7588
|
+
expected: "dictionary for /Root (catalog)",
|
|
7589
|
+
actual: `${rootObj.kind}`,
|
|
7590
|
+
data: this.data
|
|
7591
|
+
});
|
|
7143
7592
|
const catalog = rootObj;
|
|
7144
7593
|
const typeObj = catalog.get("/Type");
|
|
7145
7594
|
if (typeObj !== void 0 && typeObj.kind === "name") {
|
|
7146
7595
|
const typeName = typeObj.value;
|
|
7147
|
-
if (typeName !== "/Catalog") throw new
|
|
7596
|
+
if (typeName !== "/Catalog") throw new PdfParseError({
|
|
7597
|
+
message: `Invalid PDF: /Root dictionary has /Type "${typeName}", expected "/Catalog".`,
|
|
7598
|
+
offset: 0,
|
|
7599
|
+
expected: "/Type /Catalog in /Root dictionary",
|
|
7600
|
+
actual: `/Type "${typeName}"`,
|
|
7601
|
+
data: this.data
|
|
7602
|
+
});
|
|
7148
7603
|
}
|
|
7149
7604
|
return catalog;
|
|
7150
7605
|
}
|
|
@@ -7158,9 +7613,21 @@ var PdfDocumentParser = class {
|
|
|
7158
7613
|
*/
|
|
7159
7614
|
resolvePageTree(catalog) {
|
|
7160
7615
|
const pagesRef = catalog.get("/Pages");
|
|
7161
|
-
if (pagesRef === void 0) throw new
|
|
7616
|
+
if (pagesRef === void 0) throw new PdfParseError({
|
|
7617
|
+
message: "Invalid PDF: catalog dictionary missing /Pages entry.",
|
|
7618
|
+
offset: 0,
|
|
7619
|
+
expected: "/Pages entry in catalog dictionary",
|
|
7620
|
+
actual: "no /Pages entry",
|
|
7621
|
+
data: this.data
|
|
7622
|
+
});
|
|
7162
7623
|
const pagesObj = this.resolveObject(pagesRef);
|
|
7163
|
-
if (pagesObj.kind !== "dict") throw new
|
|
7624
|
+
if (pagesObj.kind !== "dict") throw new PdfParseError({
|
|
7625
|
+
message: `Invalid PDF: /Pages entry is not a dictionary (got ${pagesObj.kind}).`,
|
|
7626
|
+
offset: 0,
|
|
7627
|
+
expected: "dictionary for /Pages entry",
|
|
7628
|
+
actual: `${pagesObj.kind}`,
|
|
7629
|
+
data: this.data
|
|
7630
|
+
});
|
|
7164
7631
|
const pages = [];
|
|
7165
7632
|
this.traversePageTree(pagesObj, {}, pages, /* @__PURE__ */ new Set());
|
|
7166
7633
|
return pages;
|
|
@@ -7197,7 +7664,13 @@ var PdfDocumentParser = class {
|
|
|
7197
7664
|
}
|
|
7198
7665
|
if (typeName === "/Page") {
|
|
7199
7666
|
const mediaBox = currentInherited.mediaBox;
|
|
7200
|
-
if (mediaBox === void 0) throw new
|
|
7667
|
+
if (mediaBox === void 0) throw new PdfParseError({
|
|
7668
|
+
message: "Invalid PDF: /Page node has no /MediaBox (not even inherited).",
|
|
7669
|
+
offset: 0,
|
|
7670
|
+
expected: "/MediaBox on page node or inherited from parent",
|
|
7671
|
+
actual: "no /MediaBox found",
|
|
7672
|
+
data: this.data
|
|
7673
|
+
});
|
|
7201
7674
|
result.push({
|
|
7202
7675
|
dict: node,
|
|
7203
7676
|
mediaBox,
|
|
@@ -7209,7 +7682,13 @@ var PdfDocumentParser = class {
|
|
|
7209
7682
|
const kidsObj = node.get("/Kids");
|
|
7210
7683
|
if (kidsObj === void 0) return;
|
|
7211
7684
|
const kids = this.resolveObject(kidsObj);
|
|
7212
|
-
if (kids.kind !== "array") throw new
|
|
7685
|
+
if (kids.kind !== "array") throw new PdfParseError({
|
|
7686
|
+
message: `Invalid PDF: /Pages /Kids is not an array (got ${kids.kind}).`,
|
|
7687
|
+
offset: 0,
|
|
7688
|
+
expected: "array for /Pages /Kids",
|
|
7689
|
+
actual: `${kids.kind}`,
|
|
7690
|
+
data: this.data
|
|
7691
|
+
});
|
|
7213
7692
|
const kidsArr = kids;
|
|
7214
7693
|
for (let i = 0; i < kidsArr.length; i++) {
|
|
7215
7694
|
const kidRef = kidsArr.items[i];
|
|
@@ -7245,22 +7724,53 @@ var PdfDocumentParser = class {
|
|
|
7245
7724
|
return PdfNull.instance;
|
|
7246
7725
|
}
|
|
7247
7726
|
const containerEntry = this.xrefEntries.get(containerNum);
|
|
7248
|
-
if (containerEntry === void 0 || containerEntry.type !== "in-use") throw new
|
|
7727
|
+
if (containerEntry === void 0 || containerEntry.type !== "in-use") throw new PdfParseError({
|
|
7728
|
+
message: `Invalid PDF: object stream ${containerNum} referenced by compressed object ${entry.objectNumber} not found in xref table.`,
|
|
7729
|
+
offset: 0,
|
|
7730
|
+
expected: `in-use xref entry for object stream ${containerNum}`,
|
|
7731
|
+
actual: containerEntry ? `${containerEntry.type} entry` : "no entry",
|
|
7732
|
+
data: this.data
|
|
7733
|
+
});
|
|
7249
7734
|
let containerObj;
|
|
7250
7735
|
try {
|
|
7251
7736
|
const { object } = this.objectParser.parseIndirectObjectAt(containerEntry.offset);
|
|
7252
7737
|
containerObj = object;
|
|
7253
7738
|
} catch (err) {
|
|
7254
|
-
throw new
|
|
7739
|
+
throw new PdfParseError({
|
|
7740
|
+
message: `Failed to parse object stream ${containerNum} at offset ${containerEntry.offset}`,
|
|
7741
|
+
offset: containerEntry.offset,
|
|
7742
|
+
expected: `valid object stream ${containerNum}`,
|
|
7743
|
+
actual: "parse failure",
|
|
7744
|
+
data: this.data,
|
|
7745
|
+
cause: err instanceof Error ? err : void 0
|
|
7746
|
+
});
|
|
7255
7747
|
}
|
|
7256
|
-
if (containerObj.kind !== "stream") throw new
|
|
7748
|
+
if (containerObj.kind !== "stream") throw new PdfParseError({
|
|
7749
|
+
message: `Invalid PDF: object ${containerNum} expected to be an object stream but is ${containerObj.kind}.`,
|
|
7750
|
+
offset: containerEntry.offset,
|
|
7751
|
+
expected: "stream object for object stream",
|
|
7752
|
+
actual: `${containerObj.kind}`,
|
|
7753
|
+
data: this.data
|
|
7754
|
+
});
|
|
7257
7755
|
const containerStream = containerObj;
|
|
7258
7756
|
const containerDict = containerStream.dict;
|
|
7259
7757
|
const typeObj = containerDict.get("/Type");
|
|
7260
|
-
if (typeObj === void 0 || typeObj.kind !== "name" || typeObj.value !== "/ObjStm") throw new
|
|
7758
|
+
if (typeObj === void 0 || typeObj.kind !== "name" || typeObj.value !== "/ObjStm") throw new PdfParseError({
|
|
7759
|
+
message: `Invalid PDF: object ${containerNum} is not an object stream (/Type /ObjStm).`,
|
|
7760
|
+
offset: containerEntry.offset,
|
|
7761
|
+
expected: "/Type /ObjStm in object stream dictionary",
|
|
7762
|
+
actual: typeObj ? `${typeObj.kind}` : "no /Type entry",
|
|
7763
|
+
data: this.data
|
|
7764
|
+
});
|
|
7261
7765
|
const n = numVal$1(containerDict.get("/N"));
|
|
7262
7766
|
const first = numVal$1(containerDict.get("/First"));
|
|
7263
|
-
if (n === void 0 || first === void 0) throw new
|
|
7767
|
+
if (n === void 0 || first === void 0) throw new PdfParseError({
|
|
7768
|
+
message: `Invalid PDF: object stream ${containerNum} missing /N or /First entries.`,
|
|
7769
|
+
offset: containerEntry.offset,
|
|
7770
|
+
expected: "/N and /First entries in object stream",
|
|
7771
|
+
actual: `${n === void 0 ? "no /N" : "/N present"}, ${first === void 0 ? "no /First" : "/First present"}`,
|
|
7772
|
+
data: this.data
|
|
7773
|
+
});
|
|
7264
7774
|
const decompressedData = this.decompressStreamSync(containerStream);
|
|
7265
7775
|
const headerTokens = TEXT_DECODER.decode(decompressedData.subarray(0, first)).trim().split(/\s+/);
|
|
7266
7776
|
const objEntries = [];
|
|
@@ -7657,7 +8167,7 @@ function undoPngPredictorSync(data, columns) {
|
|
|
7657
8167
|
* string.
|
|
7658
8168
|
*
|
|
7659
8169
|
* This is the primary entry point for parsing existing PDFs. It creates
|
|
7660
|
-
* a
|
|
8170
|
+
* a `PdfDocumentParser`, runs the full parse pipeline, and returns
|
|
7661
8171
|
* a populated {@link PdfDocument}.
|
|
7662
8172
|
*
|
|
7663
8173
|
* @param data The PDF data as a `Uint8Array`, `ArrayBuffer`, or a
|
|
@@ -8148,7 +8658,17 @@ const NS_PDFAID = "http://www.aiim.org/pdfa/ns/id/";
|
|
|
8148
8658
|
* @internal
|
|
8149
8659
|
*/
|
|
8150
8660
|
function escapeXml(str) {
|
|
8151
|
-
|
|
8661
|
+
const parts = [];
|
|
8662
|
+
for (let i = 0; i < str.length; i++) {
|
|
8663
|
+
const c = str.charCodeAt(i);
|
|
8664
|
+
if (c === 38) parts.push("&");
|
|
8665
|
+
else if (c === 60) parts.push("<");
|
|
8666
|
+
else if (c === 62) parts.push(">");
|
|
8667
|
+
else if (c === 34) parts.push(""");
|
|
8668
|
+
else if (c === 39) parts.push("'");
|
|
8669
|
+
else parts.push(str[i]);
|
|
8670
|
+
}
|
|
8671
|
+
return parts.join("");
|
|
8152
8672
|
}
|
|
8153
8673
|
/**
|
|
8154
8674
|
* Format a Date as an ISO 8601 string for XMP.
|
|
@@ -9451,9 +9971,10 @@ function remapRef$1(sourceRef, context) {
|
|
|
9451
9971
|
context.refMap.set(sourceRef.objectNumber, placeholderRef);
|
|
9452
9972
|
return placeholderRef;
|
|
9453
9973
|
}
|
|
9974
|
+
let streamHash;
|
|
9454
9975
|
if (sourceObj.kind === "stream") {
|
|
9455
|
-
|
|
9456
|
-
const dedup = context.hashMap.get(
|
|
9976
|
+
streamHash = hashBytes(sourceObj.data);
|
|
9977
|
+
const dedup = context.hashMap.get(streamHash);
|
|
9457
9978
|
if (dedup) {
|
|
9458
9979
|
context.refMap.set(sourceRef.objectNumber, dedup);
|
|
9459
9980
|
return dedup;
|
|
@@ -9463,10 +9984,7 @@ function remapRef$1(sourceRef, context) {
|
|
|
9463
9984
|
context.refMap.set(sourceRef.objectNumber, targetRef);
|
|
9464
9985
|
const clonedObj = deepClone$1(sourceObj, context);
|
|
9465
9986
|
context.targetRegistry.assign(targetRef, clonedObj);
|
|
9466
|
-
if (
|
|
9467
|
-
const hash = hashBytes(sourceObj.data);
|
|
9468
|
-
context.hashMap.set(hash, targetRef);
|
|
9469
|
-
}
|
|
9987
|
+
if (streamHash !== void 0) context.hashMap.set(streamHash, targetRef);
|
|
9470
9988
|
return targetRef;
|
|
9471
9989
|
}
|
|
9472
9990
|
/**
|
|
@@ -14045,7 +14563,6 @@ function read2DMode(reader) {
|
|
|
14045
14563
|
if (bit === 1) {
|
|
14046
14564
|
bit = reader.readBit();
|
|
14047
14565
|
if (bit < 0) return Mode2D.EOL;
|
|
14048
|
-
if (bit === 1) return Mode2D.HORIZONTAL;
|
|
14049
14566
|
if (bit === 0) return Mode2D.VERTICAL_MINUS_1;
|
|
14050
14567
|
return Mode2D.VERTICAL_PLUS_1;
|
|
14051
14568
|
}
|
|
@@ -14211,6 +14728,9 @@ function packBits(pixels, columns, blackIs1) {
|
|
|
14211
14728
|
/**
|
|
14212
14729
|
* Decode JBIG2Decode stream data.
|
|
14213
14730
|
*
|
|
14731
|
+
* Uses the pure-JS decoder (synchronous). For optional WASM
|
|
14732
|
+
* acceleration, use {@link decodeJBIG2Async}.
|
|
14733
|
+
*
|
|
14214
14734
|
* @param data - The JBIG2-encoded content stream bytes.
|
|
14215
14735
|
* @param parms - Optional `/DecodeParms` dictionary. May contain a
|
|
14216
14736
|
* `/JBIG2Globals` key with a PdfDict/stream holding
|
|
@@ -17173,9 +17693,28 @@ function hexValue(ch) {
|
|
|
17173
17693
|
* `~>` marks end-of-data.
|
|
17174
17694
|
*/
|
|
17175
17695
|
function decodeASCII85(data) {
|
|
17176
|
-
|
|
17177
|
-
|
|
17696
|
+
let out = new Uint8Array(Math.max(data.length * 4 / 5 | 0, 256));
|
|
17697
|
+
let outPos = 0;
|
|
17698
|
+
const group = new Uint8Array(5);
|
|
17699
|
+
let groupLen = 0;
|
|
17178
17700
|
let i = 0;
|
|
17701
|
+
function ensureOut(needed) {
|
|
17702
|
+
if (outPos + needed > out.length) {
|
|
17703
|
+
const newBuf = new Uint8Array(Math.max(out.length * 2, outPos + needed));
|
|
17704
|
+
newBuf.set(out.subarray(0, outPos));
|
|
17705
|
+
out = newBuf;
|
|
17706
|
+
}
|
|
17707
|
+
}
|
|
17708
|
+
function decodeGroup(count) {
|
|
17709
|
+
for (let k = count; k < 5; k++) group[k] = 84;
|
|
17710
|
+
const val = group[0] * 85 * 85 * 85 * 85 + group[1] * 85 * 85 * 85 + group[2] * 85 * 85 + group[3] * 85 + group[4];
|
|
17711
|
+
const numBytes = count === 5 ? 4 : count - 1;
|
|
17712
|
+
ensureOut(numBytes);
|
|
17713
|
+
if (numBytes >= 1) out[outPos++] = val >>> 24 & 255;
|
|
17714
|
+
if (numBytes >= 2) out[outPos++] = val >>> 16 & 255;
|
|
17715
|
+
if (numBytes >= 3) out[outPos++] = val >>> 8 & 255;
|
|
17716
|
+
if (numBytes >= 4) out[outPos++] = val & 255;
|
|
17717
|
+
}
|
|
17179
17718
|
while (i < data.length) {
|
|
17180
17719
|
const ch = data[i];
|
|
17181
17720
|
if (ch === 126) break;
|
|
@@ -17184,8 +17723,12 @@ function decodeASCII85(data) {
|
|
|
17184
17723
|
continue;
|
|
17185
17724
|
}
|
|
17186
17725
|
if (ch === 122) {
|
|
17187
|
-
if (
|
|
17188
|
-
|
|
17726
|
+
if (groupLen > 0) throw new Error("ASCII85Decode: \"z\" inside a group");
|
|
17727
|
+
ensureOut(4);
|
|
17728
|
+
out[outPos++] = 0;
|
|
17729
|
+
out[outPos++] = 0;
|
|
17730
|
+
out[outPos++] = 0;
|
|
17731
|
+
out[outPos++] = 0;
|
|
17189
17732
|
i++;
|
|
17190
17733
|
continue;
|
|
17191
17734
|
}
|
|
@@ -17193,24 +17736,15 @@ function decodeASCII85(data) {
|
|
|
17193
17736
|
i++;
|
|
17194
17737
|
continue;
|
|
17195
17738
|
}
|
|
17196
|
-
group
|
|
17197
|
-
if (
|
|
17198
|
-
|
|
17199
|
-
|
|
17200
|
-
group.length = 0;
|
|
17739
|
+
group[groupLen++] = ch - 33;
|
|
17740
|
+
if (groupLen === 5) {
|
|
17741
|
+
decodeGroup(5);
|
|
17742
|
+
groupLen = 0;
|
|
17201
17743
|
}
|
|
17202
17744
|
i++;
|
|
17203
17745
|
}
|
|
17204
|
-
if (
|
|
17205
|
-
|
|
17206
|
-
while (group.length < 5) group.push(84);
|
|
17207
|
-
const val = group[0] * 85 * 85 * 85 * 85 + group[1] * 85 * 85 * 85 + group[2] * 85 * 85 + group[3] * 85 + group[4];
|
|
17208
|
-
const numBytes = origLen - 1;
|
|
17209
|
-
if (numBytes >= 1) result.push(val >>> 24 & 255);
|
|
17210
|
-
if (numBytes >= 2) result.push(val >>> 16 & 255);
|
|
17211
|
-
if (numBytes >= 3) result.push(val >>> 8 & 255);
|
|
17212
|
-
}
|
|
17213
|
-
return new Uint8Array(result);
|
|
17746
|
+
if (groupLen >= 2) decodeGroup(groupLen);
|
|
17747
|
+
return out.subarray(0, outPos);
|
|
17214
17748
|
}
|
|
17215
17749
|
/**
|
|
17216
17750
|
* Decode an LZWDecode stream.
|
|
@@ -17230,6 +17764,10 @@ function decodeLZW(data, parms) {
|
|
|
17230
17764
|
}
|
|
17231
17765
|
/**
|
|
17232
17766
|
* Core LZW decompression.
|
|
17767
|
+
*
|
|
17768
|
+
* Uses a flat pooled buffer for the code table instead of per-entry
|
|
17769
|
+
* Uint8Array allocations, and a pre-allocated output buffer with
|
|
17770
|
+
* manual growth instead of `number[]` + push.
|
|
17233
17771
|
*/
|
|
17234
17772
|
function lzwDecompress(data, earlyChange) {
|
|
17235
17773
|
const CLEAR_TABLE = 256;
|
|
@@ -17254,71 +17792,88 @@ function lzwDecompress(data, earlyChange) {
|
|
|
17254
17792
|
}
|
|
17255
17793
|
return result;
|
|
17256
17794
|
}
|
|
17257
|
-
let
|
|
17795
|
+
let tableBuf = new Uint8Array(65536);
|
|
17796
|
+
const tableOff = new Int32Array(4096);
|
|
17797
|
+
const tableLen = new Int32Array(4096);
|
|
17798
|
+
let tableBufUsed = 256;
|
|
17258
17799
|
let codeSize = 9;
|
|
17259
17800
|
let nextCode = 258;
|
|
17801
|
+
for (let i = 0; i < 256; i++) {
|
|
17802
|
+
tableBuf[i] = i;
|
|
17803
|
+
tableOff[i] = i;
|
|
17804
|
+
tableLen[i] = 1;
|
|
17805
|
+
}
|
|
17260
17806
|
function resetTable() {
|
|
17261
|
-
|
|
17262
|
-
for (let i = 0; i < 256; i++) table[i] = new Uint8Array([i]);
|
|
17263
|
-
table[256] = new Uint8Array(0);
|
|
17264
|
-
table[257] = new Uint8Array(0);
|
|
17807
|
+
tableBufUsed = 256;
|
|
17265
17808
|
nextCode = 258;
|
|
17266
17809
|
codeSize = 9;
|
|
17267
17810
|
}
|
|
17268
|
-
|
|
17269
|
-
|
|
17270
|
-
|
|
17811
|
+
let out = new Uint8Array(Math.max(data.length * 3, 4096));
|
|
17812
|
+
let outPos = 0;
|
|
17813
|
+
function ensureOut(needed) {
|
|
17814
|
+
if (outPos + needed > out.length) {
|
|
17815
|
+
const newBuf = new Uint8Array(Math.max(out.length * 2, outPos + needed));
|
|
17816
|
+
newBuf.set(out.subarray(0, outPos));
|
|
17817
|
+
out = newBuf;
|
|
17818
|
+
}
|
|
17819
|
+
}
|
|
17820
|
+
function ensureTable(needed) {
|
|
17821
|
+
if (tableBufUsed + needed > tableBuf.length) {
|
|
17822
|
+
const newBuf = new Uint8Array(Math.max(tableBuf.length * 2, tableBufUsed + needed));
|
|
17823
|
+
newBuf.set(tableBuf.subarray(0, tableBufUsed));
|
|
17824
|
+
tableBuf = newBuf;
|
|
17825
|
+
}
|
|
17826
|
+
}
|
|
17827
|
+
function writeEntry(code) {
|
|
17828
|
+
const off = tableOff[code];
|
|
17829
|
+
const len = tableLen[code];
|
|
17830
|
+
ensureOut(len);
|
|
17831
|
+
out.set(tableBuf.subarray(off, off + len), outPos);
|
|
17832
|
+
outPos += len;
|
|
17833
|
+
}
|
|
17834
|
+
function addEntry(prevCode, firstByte) {
|
|
17835
|
+
const prevOff = tableOff[prevCode];
|
|
17836
|
+
const prevLen = tableLen[prevCode];
|
|
17837
|
+
const newLen = prevLen + 1;
|
|
17838
|
+
ensureTable(newLen);
|
|
17839
|
+
tableBuf.set(tableBuf.subarray(prevOff, prevOff + prevLen), tableBufUsed);
|
|
17840
|
+
tableBuf[tableBufUsed + prevLen] = firstByte;
|
|
17841
|
+
tableOff[nextCode] = tableBufUsed;
|
|
17842
|
+
tableLen[nextCode] = newLen;
|
|
17843
|
+
tableBufUsed += newLen;
|
|
17844
|
+
nextCode++;
|
|
17845
|
+
}
|
|
17271
17846
|
let code = readBits(codeSize);
|
|
17272
17847
|
if (code === CLEAR_TABLE) {
|
|
17273
17848
|
resetTable();
|
|
17274
17849
|
code = readBits(codeSize);
|
|
17275
17850
|
}
|
|
17276
|
-
if (code === EOD) return new Uint8Array(
|
|
17277
|
-
|
|
17278
|
-
|
|
17279
|
-
for (const b of entry) output.push(b);
|
|
17280
|
-
prevEntry = entry;
|
|
17281
|
-
}
|
|
17851
|
+
if (code === EOD) return new Uint8Array(0);
|
|
17852
|
+
writeEntry(code);
|
|
17853
|
+
let prevCode = code;
|
|
17282
17854
|
while (true) {
|
|
17283
17855
|
code = readBits(codeSize);
|
|
17284
17856
|
if (code === EOD) break;
|
|
17285
17857
|
if (code === CLEAR_TABLE) {
|
|
17286
17858
|
resetTable();
|
|
17287
|
-
prevEntry = null;
|
|
17288
17859
|
code = readBits(codeSize);
|
|
17289
17860
|
if (code === EOD) break;
|
|
17290
|
-
|
|
17291
|
-
|
|
17292
|
-
for (const b of entry) output.push(b);
|
|
17293
|
-
prevEntry = entry;
|
|
17294
|
-
}
|
|
17861
|
+
writeEntry(code);
|
|
17862
|
+
prevCode = code;
|
|
17295
17863
|
continue;
|
|
17296
17864
|
}
|
|
17297
|
-
if (code < nextCode
|
|
17298
|
-
|
|
17299
|
-
|
|
17300
|
-
if (prevEntry) {
|
|
17301
|
-
const newEntry = new Uint8Array(prevEntry.length + 1);
|
|
17302
|
-
newEntry.set(prevEntry);
|
|
17303
|
-
newEntry[prevEntry.length] = entry[0];
|
|
17304
|
-
table[nextCode] = newEntry;
|
|
17305
|
-
nextCode++;
|
|
17306
|
-
}
|
|
17865
|
+
if (code < nextCode) {
|
|
17866
|
+
writeEntry(code);
|
|
17867
|
+
addEntry(prevCode, tableBuf[tableOff[code]]);
|
|
17307
17868
|
} else {
|
|
17308
|
-
|
|
17309
|
-
|
|
17310
|
-
|
|
17311
|
-
|
|
17312
|
-
for (const b of newEntry) output.push(b);
|
|
17313
|
-
table[nextCode] = newEntry;
|
|
17314
|
-
nextCode++;
|
|
17315
|
-
entry = newEntry;
|
|
17316
|
-
}
|
|
17317
|
-
prevEntry = entry;
|
|
17869
|
+
addEntry(prevCode, tableBuf[tableOff[prevCode]]);
|
|
17870
|
+
writeEntry(nextCode - 1);
|
|
17871
|
+
}
|
|
17872
|
+
prevCode = code;
|
|
17318
17873
|
const threshold = (1 << codeSize) - earlyChange;
|
|
17319
17874
|
if (nextCode >= threshold && codeSize < 12) codeSize++;
|
|
17320
17875
|
}
|
|
17321
|
-
return
|
|
17876
|
+
return out.subarray(0, outPos);
|
|
17322
17877
|
}
|
|
17323
17878
|
/**
|
|
17324
17879
|
* Decode a RunLengthDecode stream.
|
|
@@ -17450,7 +18005,6 @@ function embedPageAsFormXObject(page, sourceRegistry, targetRegistry, xObjectNam
|
|
|
17450
18005
|
const pageWidth = page.width;
|
|
17451
18006
|
const pageHeight = page.height;
|
|
17452
18007
|
const contentChunks = [];
|
|
17453
|
-
new TextDecoder();
|
|
17454
18008
|
const originalRefs = page.getOriginalContentRefs();
|
|
17455
18009
|
for (const ref of originalRefs) {
|
|
17456
18010
|
const obj = sourceRegistry.resolve(ref);
|
|
@@ -17535,6 +18089,93 @@ function embedPageAsFormXObject(page, sourceRegistry, targetRegistry, xObjectNam
|
|
|
17535
18089
|
};
|
|
17536
18090
|
}
|
|
17537
18091
|
|
|
18092
|
+
//#endregion
|
|
18093
|
+
//#region src/core/pdfDocumentEmbed.ts
|
|
18094
|
+
/**
|
|
18095
|
+
* @module core/pdfDocumentEmbed
|
|
18096
|
+
*
|
|
18097
|
+
* Pure helper functions for font CMap generation and image format
|
|
18098
|
+
* validation/parsing. Extracted from {@link pdfDocument} to keep the
|
|
18099
|
+
* PdfDocument class focused on high-level document management.
|
|
18100
|
+
*/
|
|
18101
|
+
/**
|
|
18102
|
+
* Build a /ToUnicode CMap from a font's cmap table.
|
|
18103
|
+
* Maps glyph IDs (used as CIDs with Identity-H) to Unicode codepoints.
|
|
18104
|
+
*
|
|
18105
|
+
* @param cmapTable Mapping from Unicode codepoint to glyph ID.
|
|
18106
|
+
* @returns A CMap string suitable for a PDF /ToUnicode stream.
|
|
18107
|
+
*/
|
|
18108
|
+
function buildToUnicodeCmap(cmapTable) {
|
|
18109
|
+
const gidToUnicode = /* @__PURE__ */ new Map();
|
|
18110
|
+
for (const [codepoint, gid] of cmapTable) if (!gidToUnicode.has(gid)) gidToUnicode.set(gid, codepoint);
|
|
18111
|
+
const entries = gidToUnicode.entries().toArray().sort((a, b) => a[0] - b[0]);
|
|
18112
|
+
const lines = [];
|
|
18113
|
+
lines.push("/CIDInit /ProcSet findresource begin");
|
|
18114
|
+
lines.push("12 dict begin");
|
|
18115
|
+
lines.push("begincmap");
|
|
18116
|
+
lines.push("/CIDSystemInfo");
|
|
18117
|
+
lines.push("<< /Registry (Adobe)");
|
|
18118
|
+
lines.push("/Ordering (UCS)");
|
|
18119
|
+
lines.push("/Supplement 0");
|
|
18120
|
+
lines.push(">> def");
|
|
18121
|
+
lines.push("/CMapName /Adobe-Identity-UCS def");
|
|
18122
|
+
lines.push("/CMapType 2 def");
|
|
18123
|
+
lines.push("1 begincodespacerange");
|
|
18124
|
+
lines.push("<0000> <FFFF>");
|
|
18125
|
+
lines.push("endcodespacerange");
|
|
18126
|
+
const CHUNK_SIZE = 100;
|
|
18127
|
+
for (let i = 0; i < entries.length; i += CHUNK_SIZE) {
|
|
18128
|
+
const chunk = entries.slice(i, i + CHUNK_SIZE);
|
|
18129
|
+
lines.push(`${chunk.length} beginbfchar`);
|
|
18130
|
+
for (const [gid, codepoint] of chunk) {
|
|
18131
|
+
const gidHex = gid.toString(16).padStart(4, "0").toUpperCase();
|
|
18132
|
+
const uniHex = codepoint.toString(16).padStart(4, "0").toUpperCase();
|
|
18133
|
+
lines.push(`<${gidHex}> <${uniHex}>`);
|
|
18134
|
+
}
|
|
18135
|
+
lines.push("endbfchar");
|
|
18136
|
+
}
|
|
18137
|
+
lines.push("endcmap");
|
|
18138
|
+
lines.push("CMapName currentdict /CMap defineresource pop");
|
|
18139
|
+
lines.push("end");
|
|
18140
|
+
lines.push("end");
|
|
18141
|
+
return lines.join("\n");
|
|
18142
|
+
}
|
|
18143
|
+
/**
|
|
18144
|
+
* Validate a JPEG file signature (SOI marker).
|
|
18145
|
+
*
|
|
18146
|
+
* @param data The raw file bytes.
|
|
18147
|
+
* @throws If the data is too short or the SOI marker is invalid.
|
|
18148
|
+
*/
|
|
18149
|
+
function validateJpegSignature(data) {
|
|
18150
|
+
if (data.length < 2 || data[0] !== 255 || data[1] !== 216) throw new Error("Invalid JPEG: bad SOI marker");
|
|
18151
|
+
}
|
|
18152
|
+
/**
|
|
18153
|
+
* Parse width, height, and component count from a JPEG's SOF marker.
|
|
18154
|
+
*
|
|
18155
|
+
* @param data The raw JPEG file bytes.
|
|
18156
|
+
* @returns Width, height, and number of color components.
|
|
18157
|
+
*/
|
|
18158
|
+
function parseJpegDimensions(data) {
|
|
18159
|
+
validateJpegSignature(data);
|
|
18160
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
18161
|
+
let offset = 2;
|
|
18162
|
+
while (offset < data.length - 1) {
|
|
18163
|
+
if (data[offset] !== 255) throw new Error("Invalid JPEG: expected marker");
|
|
18164
|
+
const marker = data[offset + 1];
|
|
18165
|
+
if (marker >= 192 && marker <= 195 || marker >= 197 && marker <= 199 || marker >= 201 && marker <= 203 || marker >= 205 && marker <= 207) {
|
|
18166
|
+
const height = view.getUint16(offset + 5, false);
|
|
18167
|
+
return {
|
|
18168
|
+
width: view.getUint16(offset + 7, false),
|
|
18169
|
+
height,
|
|
18170
|
+
components: data[offset + 9]
|
|
18171
|
+
};
|
|
18172
|
+
}
|
|
18173
|
+
const segmentLength = view.getUint16(offset + 2, false);
|
|
18174
|
+
offset += 2 + segmentLength;
|
|
18175
|
+
}
|
|
18176
|
+
throw new Error("Invalid JPEG: SOF marker not found");
|
|
18177
|
+
}
|
|
18178
|
+
|
|
17538
18179
|
//#endregion
|
|
17539
18180
|
//#region src/core/pdfDocument.ts
|
|
17540
18181
|
/**
|
|
@@ -17881,7 +18522,7 @@ var PdfDocument = class PdfDocument {
|
|
|
17881
18522
|
async embedTrueTypeFont(fontData, options) {
|
|
17882
18523
|
const embeddedFont = await embedFont(fontData);
|
|
17883
18524
|
const metrics = embeddedFont.metrics;
|
|
17884
|
-
const psName = options?.customName
|
|
18525
|
+
const psName = options?.customName ?? metrics.postScriptName ?? metrics.familyName ?? "CustomFont";
|
|
17885
18526
|
const existing = this.embeddedFonts.get(`__ttf__${psName}`);
|
|
17886
18527
|
if (existing) return existing;
|
|
17887
18528
|
this.fontCounter++;
|
|
@@ -17938,7 +18579,7 @@ var PdfDocument = class PdfDocument {
|
|
|
17938
18579
|
cidFontDict.set("/DW", PdfNumber.of(Math.round(metrics.defaultWidth * scale)));
|
|
17939
18580
|
cidFontDict.set("/CIDToGIDMap", PdfName.of("Identity"));
|
|
17940
18581
|
const cidFontRef = this.registry.register(cidFontDict);
|
|
17941
|
-
const toUnicodeCmapStr =
|
|
18582
|
+
const toUnicodeCmapStr = buildToUnicodeCmap(metrics.cmapTable);
|
|
17942
18583
|
const toUnicodeStream = PdfStream.fromString(toUnicodeCmapStr);
|
|
17943
18584
|
const toUnicodeRef = this.registry.register(toUnicodeStream);
|
|
17944
18585
|
const type0Dict = new PdfDict();
|
|
@@ -17996,7 +18637,7 @@ var PdfDocument = class PdfDocument {
|
|
|
17996
18637
|
async embedCffFont(fontData, options) {
|
|
17997
18638
|
const embeddedFont = await embedFont(fontData);
|
|
17998
18639
|
const metrics = embeddedFont.metrics;
|
|
17999
|
-
const psName = options?.customName
|
|
18640
|
+
const psName = options?.customName ?? metrics.postScriptName ?? metrics.familyName ?? "CFFFont";
|
|
18000
18641
|
const existing = this.embeddedFonts.get(`__cff__${psName}`);
|
|
18001
18642
|
if (existing) return existing;
|
|
18002
18643
|
this.fontCounter++;
|
|
@@ -18055,7 +18696,7 @@ var PdfDocument = class PdfDocument {
|
|
|
18055
18696
|
cidFontDict.set("/W", wArray);
|
|
18056
18697
|
cidFontDict.set("/DW", PdfNumber.of(Math.round(metrics.defaultWidth * scale)));
|
|
18057
18698
|
const cidFontRef = this.registry.register(cidFontDict);
|
|
18058
|
-
const toUnicodeCmapStr =
|
|
18699
|
+
const toUnicodeCmapStr = buildToUnicodeCmap(metrics.cmapTable);
|
|
18059
18700
|
const toUnicodeStream = PdfStream.fromString(toUnicodeCmapStr);
|
|
18060
18701
|
const toUnicodeRef = this.registry.register(toUnicodeStream);
|
|
18061
18702
|
const type0Dict = new PdfDict();
|
|
@@ -18101,46 +18742,6 @@ var PdfDocument = class PdfDocument {
|
|
|
18101
18742
|
return fontRef;
|
|
18102
18743
|
}
|
|
18103
18744
|
/**
|
|
18104
|
-
* Build a /ToUnicode CMap from the font's cmap table.
|
|
18105
|
-
* Maps glyph IDs (used as CIDs with Identity-H) to Unicode codepoints.
|
|
18106
|
-
* @internal
|
|
18107
|
-
*/
|
|
18108
|
-
buildToUnicodeCmap(cmapTable) {
|
|
18109
|
-
const gidToUnicode = /* @__PURE__ */ new Map();
|
|
18110
|
-
for (const [codepoint, gid] of cmapTable) if (!gidToUnicode.has(gid)) gidToUnicode.set(gid, codepoint);
|
|
18111
|
-
const entries = gidToUnicode.entries().toArray().sort((a, b) => a[0] - b[0]);
|
|
18112
|
-
const lines = [];
|
|
18113
|
-
lines.push("/CIDInit /ProcSet findresource begin");
|
|
18114
|
-
lines.push("12 dict begin");
|
|
18115
|
-
lines.push("begincmap");
|
|
18116
|
-
lines.push("/CIDSystemInfo");
|
|
18117
|
-
lines.push("<< /Registry (Adobe)");
|
|
18118
|
-
lines.push("/Ordering (UCS)");
|
|
18119
|
-
lines.push("/Supplement 0");
|
|
18120
|
-
lines.push(">> def");
|
|
18121
|
-
lines.push("/CMapName /Adobe-Identity-UCS def");
|
|
18122
|
-
lines.push("/CMapType 2 def");
|
|
18123
|
-
lines.push("1 begincodespacerange");
|
|
18124
|
-
lines.push("<0000> <FFFF>");
|
|
18125
|
-
lines.push("endcodespacerange");
|
|
18126
|
-
const CHUNK_SIZE = 100;
|
|
18127
|
-
for (let i = 0; i < entries.length; i += CHUNK_SIZE) {
|
|
18128
|
-
const chunk = entries.slice(i, i + CHUNK_SIZE);
|
|
18129
|
-
lines.push(`${chunk.length} beginbfchar`);
|
|
18130
|
-
for (const [gid, codepoint] of chunk) {
|
|
18131
|
-
const gidHex = gid.toString(16).padStart(4, "0").toUpperCase();
|
|
18132
|
-
const uniHex = codepoint.toString(16).padStart(4, "0").toUpperCase();
|
|
18133
|
-
lines.push(`<${gidHex}> <${uniHex}>`);
|
|
18134
|
-
}
|
|
18135
|
-
lines.push("endbfchar");
|
|
18136
|
-
}
|
|
18137
|
-
lines.push("endcmap");
|
|
18138
|
-
lines.push("CMapName currentdict /CMap defineresource pop");
|
|
18139
|
-
lines.push("end");
|
|
18140
|
-
lines.push("end");
|
|
18141
|
-
return lines.join("\n");
|
|
18142
|
-
}
|
|
18143
|
-
/**
|
|
18144
18745
|
* Embed a PNG image.
|
|
18145
18746
|
*
|
|
18146
18747
|
* Fully decodes the PNG (including filter reconstruction and alpha
|
|
@@ -18326,7 +18927,7 @@ var PdfDocument = class PdfDocument {
|
|
|
18326
18927
|
* @param pages Array of PdfPage instances to embed.
|
|
18327
18928
|
* @returns Array of {@link EmbeddedPdfPage} handles, one per input page.
|
|
18328
18929
|
*/
|
|
18329
|
-
|
|
18930
|
+
embedPages(pages) {
|
|
18330
18931
|
return pages.map((page) => this.embedPage(page));
|
|
18331
18932
|
}
|
|
18332
18933
|
/** Set the document title. */
|
|
@@ -18809,6 +19410,79 @@ var PdfDocument = class PdfDocument {
|
|
|
18809
19410
|
addWatermark(this, options);
|
|
18810
19411
|
}
|
|
18811
19412
|
/**
|
|
19413
|
+
* Create a soft mask Form XObject that can be used with
|
|
19414
|
+
* {@link PdfPage.applySoftMask}.
|
|
19415
|
+
*
|
|
19416
|
+
* The builder callback receives a {@link SoftMaskBuilder} with methods
|
|
19417
|
+
* for generating grayscale content where white (`1`) represents fully
|
|
19418
|
+
* opaque regions and black (`0`) represents fully transparent regions.
|
|
19419
|
+
*
|
|
19420
|
+
* The returned {@link SoftMaskRef} is passed to
|
|
19421
|
+
* {@link PdfPage.applySoftMask} to activate the mask for subsequent
|
|
19422
|
+
* drawing operations on that page.
|
|
19423
|
+
*
|
|
19424
|
+
* @param width Width of the mask in points.
|
|
19425
|
+
* @param height Height of the mask in points.
|
|
19426
|
+
* @param builder Callback that draws the mask content.
|
|
19427
|
+
* @returns A reference to the soft mask Form XObject.
|
|
19428
|
+
*
|
|
19429
|
+
* @example
|
|
19430
|
+
* ```ts
|
|
19431
|
+
* const mask = doc.createSoftMask(200, 200, (b) => {
|
|
19432
|
+
* // White background = fully opaque
|
|
19433
|
+
* b.drawRectangle(0, 0, 200, 200, 1);
|
|
19434
|
+
* // Black circle = fully transparent hole
|
|
19435
|
+
* b.drawCircle(100, 100, 80, 0);
|
|
19436
|
+
* });
|
|
19437
|
+
* page.applySoftMask(mask);
|
|
19438
|
+
* page.drawRectangle({ x: 50, y: 50, width: 200, height: 200, color: rgb(1, 0, 0) });
|
|
19439
|
+
* page.clearSoftMask();
|
|
19440
|
+
* ```
|
|
19441
|
+
*/
|
|
19442
|
+
createSoftMask(width, height, builder) {
|
|
19443
|
+
const maskOps = [];
|
|
19444
|
+
const kappa = .5522847498;
|
|
19445
|
+
builder({
|
|
19446
|
+
drawRectangle(x, y, w, h, gray) {
|
|
19447
|
+
maskOps.push(`${gray} g`);
|
|
19448
|
+
maskOps.push(`${x} ${y} ${w} ${h} re`);
|
|
19449
|
+
maskOps.push("f");
|
|
19450
|
+
},
|
|
19451
|
+
drawCircle(cx, cy, r, gray) {
|
|
19452
|
+
maskOps.push(`${gray} g`);
|
|
19453
|
+
const ox = r * kappa;
|
|
19454
|
+
const oy = r * kappa;
|
|
19455
|
+
maskOps.push(`${cx - r} ${cy} m`);
|
|
19456
|
+
maskOps.push(`${cx - r} ${cy + oy} ${cx - ox} ${cy + r} ${cx} ${cy + r} c`);
|
|
19457
|
+
maskOps.push(`${cx + ox} ${cy + r} ${cx + r} ${cy + oy} ${cx + r} ${cy} c`);
|
|
19458
|
+
maskOps.push(`${cx + r} ${cy - oy} ${cx + ox} ${cy - r} ${cx} ${cy - r} c`);
|
|
19459
|
+
maskOps.push(`${cx - ox} ${cy - r} ${cx - r} ${cy - oy} ${cx - r} ${cy} c`);
|
|
19460
|
+
maskOps.push("f");
|
|
19461
|
+
},
|
|
19462
|
+
pushRawOperators(ops) {
|
|
19463
|
+
maskOps.push(ops);
|
|
19464
|
+
}
|
|
19465
|
+
});
|
|
19466
|
+
const groupDict = new PdfDict();
|
|
19467
|
+
groupDict.set("/S", PdfName.of("Transparency"));
|
|
19468
|
+
groupDict.set("/CS", PdfName.of("DeviceGray"));
|
|
19469
|
+
const formDict = new PdfDict();
|
|
19470
|
+
formDict.set("/Type", PdfName.of("XObject"));
|
|
19471
|
+
formDict.set("/Subtype", PdfName.of("Form"));
|
|
19472
|
+
formDict.set("/BBox", PdfArray.fromNumbers([
|
|
19473
|
+
0,
|
|
19474
|
+
0,
|
|
19475
|
+
width,
|
|
19476
|
+
height
|
|
19477
|
+
]));
|
|
19478
|
+
formDict.set("/Group", groupDict);
|
|
19479
|
+
const stream = PdfStream.fromString(maskOps.join("\n"), formDict);
|
|
19480
|
+
return {
|
|
19481
|
+
_tag: "softMask",
|
|
19482
|
+
ref: this.registry.register(stream)
|
|
19483
|
+
};
|
|
19484
|
+
}
|
|
19485
|
+
/**
|
|
18812
19486
|
* Apply all pending redactions across all pages.
|
|
18813
19487
|
*
|
|
18814
19488
|
* Redaction marks are added to individual pages using
|
|
@@ -19043,30 +19717,6 @@ var PdfDocument = class PdfDocument {
|
|
|
19043
19717
|
function createPdf() {
|
|
19044
19718
|
return new PdfDocument();
|
|
19045
19719
|
}
|
|
19046
|
-
/**
|
|
19047
|
-
* Parse width, height, and component count from a JPEG's SOF marker.
|
|
19048
|
-
* @internal
|
|
19049
|
-
*/
|
|
19050
|
-
function parseJpegDimensions(data) {
|
|
19051
|
-
if (data.length < 2 || data[0] !== 255 || data[1] !== 216) throw new Error("Invalid JPEG: bad SOI marker");
|
|
19052
|
-
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
19053
|
-
let offset = 2;
|
|
19054
|
-
while (offset < data.length - 1) {
|
|
19055
|
-
if (data[offset] !== 255) throw new Error("Invalid JPEG: expected marker");
|
|
19056
|
-
const marker = data[offset + 1];
|
|
19057
|
-
if (marker >= 192 && marker <= 195 || marker >= 197 && marker <= 199 || marker >= 201 && marker <= 203 || marker >= 205 && marker <= 207) {
|
|
19058
|
-
const height = view.getUint16(offset + 5, false);
|
|
19059
|
-
return {
|
|
19060
|
-
width: view.getUint16(offset + 7, false),
|
|
19061
|
-
height,
|
|
19062
|
-
components: data[offset + 9]
|
|
19063
|
-
};
|
|
19064
|
-
}
|
|
19065
|
-
const segmentLength = view.getUint16(offset + 2, false);
|
|
19066
|
-
offset += 2 + segmentLength;
|
|
19067
|
-
}
|
|
19068
|
-
throw new Error("Invalid JPEG: SOF marker not found");
|
|
19069
|
-
}
|
|
19070
19720
|
|
|
19071
19721
|
//#endregion
|
|
19072
19722
|
//#region src/utils/pdfValueHelpers.ts
|
|
@@ -19809,8 +20459,8 @@ function compressStream(stream, level) {
|
|
|
19809
20459
|
* @returns The incremental save result.
|
|
19810
20460
|
*/
|
|
19811
20461
|
async function saveDocumentIncremental(originalBytes, doc, options) {
|
|
19812
|
-
const { buildDocumentStructure } = await import("./pdfCatalog-
|
|
19813
|
-
const { PdfPage: _PdfPage } = await import("./pdfPage-
|
|
20462
|
+
const { buildDocumentStructure } = await import("./pdfCatalog-BB2Wnmud.mjs").then((n) => n.o);
|
|
20463
|
+
const { PdfPage: _PdfPage } = await import("./pdfPage-N1K2U3jI.mjs").then((n) => n.r);
|
|
19814
20464
|
const registry = doc.getRegistry();
|
|
19815
20465
|
const structure = buildDocumentStructure(doc.getInternalPages().map((p) => p.finalize()), {
|
|
19816
20466
|
producer: doc.getProducer(),
|
|
@@ -21917,6 +22567,19 @@ var TokenType = /* @__PURE__ */ function(TokenType) {
|
|
|
21917
22567
|
return TokenType;
|
|
21918
22568
|
}(TokenType || {});
|
|
21919
22569
|
/**
|
|
22570
|
+
* `hexVal[b]` is the numeric value (0-15) of a hex character, or -1 if
|
|
22571
|
+
* the byte is not a valid hex digit.
|
|
22572
|
+
*/
|
|
22573
|
+
const hexVal = /* @__PURE__ */ (() => {
|
|
22574
|
+
const t = new Int8Array(256).fill(-1);
|
|
22575
|
+
for (let i = 0; i <= 9; i++) t[48 + i] = i;
|
|
22576
|
+
for (let i = 0; i < 6; i++) {
|
|
22577
|
+
t[65 + i] = 10 + i;
|
|
22578
|
+
t[97 + i] = 10 + i;
|
|
22579
|
+
}
|
|
22580
|
+
return t;
|
|
22581
|
+
})();
|
|
22582
|
+
/**
|
|
21920
22583
|
* Combined lexer + parser for PDF content streams.
|
|
21921
22584
|
*
|
|
21922
22585
|
* Content streams are simpler than full PDF object syntax — there are no
|
|
@@ -22035,20 +22698,22 @@ var ContentStreamLexer = class {
|
|
|
22035
22698
|
}
|
|
22036
22699
|
const dataStart = this.pos;
|
|
22037
22700
|
let dataEnd = this.pos;
|
|
22038
|
-
|
|
22039
|
-
|
|
22040
|
-
|
|
22041
|
-
|
|
22042
|
-
|
|
22043
|
-
|
|
22044
|
-
|
|
22045
|
-
|
|
22046
|
-
|
|
22047
|
-
|
|
22048
|
-
|
|
22701
|
+
let searchFrom = this.pos;
|
|
22702
|
+
while (searchFrom < this.data.length) {
|
|
22703
|
+
const eIdx = this.data.indexOf(69, searchFrom);
|
|
22704
|
+
if (eIdx === -1 || eIdx + 1 >= this.data.length) {
|
|
22705
|
+
this.pos = this.data.length;
|
|
22706
|
+
break;
|
|
22707
|
+
}
|
|
22708
|
+
if (eIdx > dataStart && this.isWhitespace(this.data[eIdx - 1]) && this.data[eIdx + 1] === 73) {
|
|
22709
|
+
const afterEI = eIdx + 2;
|
|
22710
|
+
if (afterEI >= this.data.length || this.isWhitespace(this.data[afterEI])) {
|
|
22711
|
+
dataEnd = eIdx - 1;
|
|
22712
|
+
this.pos = afterEI;
|
|
22713
|
+
break;
|
|
22049
22714
|
}
|
|
22050
22715
|
}
|
|
22051
|
-
|
|
22716
|
+
searchFrom = eIdx + 1;
|
|
22052
22717
|
}
|
|
22053
22718
|
return {
|
|
22054
22719
|
dict,
|
|
@@ -22116,7 +22781,7 @@ var ContentStreamLexer = class {
|
|
|
22116
22781
|
*/
|
|
22117
22782
|
readLiteralString() {
|
|
22118
22783
|
this.pos++;
|
|
22119
|
-
|
|
22784
|
+
const parts = [];
|
|
22120
22785
|
let depth = 1;
|
|
22121
22786
|
while (this.pos < this.data.length && depth > 0) {
|
|
22122
22787
|
const ch = this.data[this.pos];
|
|
@@ -22126,35 +22791,35 @@ var ContentStreamLexer = class {
|
|
|
22126
22791
|
const esc = this.data[this.pos];
|
|
22127
22792
|
switch (esc) {
|
|
22128
22793
|
case 110:
|
|
22129
|
-
|
|
22794
|
+
parts.push("\n");
|
|
22130
22795
|
this.pos++;
|
|
22131
22796
|
break;
|
|
22132
22797
|
case 114:
|
|
22133
|
-
|
|
22798
|
+
parts.push("\r");
|
|
22134
22799
|
this.pos++;
|
|
22135
22800
|
break;
|
|
22136
22801
|
case 116:
|
|
22137
|
-
|
|
22802
|
+
parts.push(" ");
|
|
22138
22803
|
this.pos++;
|
|
22139
22804
|
break;
|
|
22140
22805
|
case 98:
|
|
22141
|
-
|
|
22806
|
+
parts.push("\b");
|
|
22142
22807
|
this.pos++;
|
|
22143
22808
|
break;
|
|
22144
22809
|
case 102:
|
|
22145
|
-
|
|
22810
|
+
parts.push("\f");
|
|
22146
22811
|
this.pos++;
|
|
22147
22812
|
break;
|
|
22148
22813
|
case 40:
|
|
22149
|
-
|
|
22814
|
+
parts.push("(");
|
|
22150
22815
|
this.pos++;
|
|
22151
22816
|
break;
|
|
22152
22817
|
case 41:
|
|
22153
|
-
|
|
22818
|
+
parts.push(")");
|
|
22154
22819
|
this.pos++;
|
|
22155
22820
|
break;
|
|
22156
22821
|
case 92:
|
|
22157
|
-
|
|
22822
|
+
parts.push("\\");
|
|
22158
22823
|
this.pos++;
|
|
22159
22824
|
break;
|
|
22160
22825
|
case 10:
|
|
@@ -22182,29 +22847,29 @@ var ContentStreamLexer = class {
|
|
|
22182
22847
|
}
|
|
22183
22848
|
}
|
|
22184
22849
|
}
|
|
22185
|
-
|
|
22850
|
+
parts.push(String.fromCharCode(octal & 255));
|
|
22186
22851
|
} else {
|
|
22187
|
-
|
|
22852
|
+
parts.push(String.fromCharCode(esc));
|
|
22188
22853
|
this.pos++;
|
|
22189
22854
|
}
|
|
22190
22855
|
break;
|
|
22191
22856
|
}
|
|
22192
22857
|
} else if (ch === 40) {
|
|
22193
22858
|
depth++;
|
|
22194
|
-
|
|
22859
|
+
parts.push("(");
|
|
22195
22860
|
this.pos++;
|
|
22196
22861
|
} else if (ch === 41) {
|
|
22197
22862
|
depth--;
|
|
22198
|
-
if (depth > 0)
|
|
22863
|
+
if (depth > 0) parts.push(")");
|
|
22199
22864
|
this.pos++;
|
|
22200
22865
|
} else {
|
|
22201
|
-
|
|
22866
|
+
parts.push(String.fromCharCode(ch));
|
|
22202
22867
|
this.pos++;
|
|
22203
22868
|
}
|
|
22204
22869
|
}
|
|
22205
22870
|
return {
|
|
22206
22871
|
type: TokenType.String,
|
|
22207
|
-
value:
|
|
22872
|
+
value: parts.join("")
|
|
22208
22873
|
};
|
|
22209
22874
|
}
|
|
22210
22875
|
/**
|
|
@@ -22212,7 +22877,8 @@ var ContentStreamLexer = class {
|
|
|
22212
22877
|
*/
|
|
22213
22878
|
readHexString() {
|
|
22214
22879
|
this.pos++;
|
|
22215
|
-
|
|
22880
|
+
const bytes = [];
|
|
22881
|
+
let hi = -1;
|
|
22216
22882
|
while (this.pos < this.data.length) {
|
|
22217
22883
|
const ch = this.data[this.pos];
|
|
22218
22884
|
if (ch === 62) {
|
|
@@ -22223,18 +22889,22 @@ var ContentStreamLexer = class {
|
|
|
22223
22889
|
this.pos++;
|
|
22224
22890
|
continue;
|
|
22225
22891
|
}
|
|
22226
|
-
|
|
22892
|
+
const v = hexVal[ch];
|
|
22893
|
+
if (v === -1) {
|
|
22894
|
+
this.pos++;
|
|
22895
|
+
continue;
|
|
22896
|
+
}
|
|
22897
|
+
if (hi === -1) hi = v;
|
|
22898
|
+
else {
|
|
22899
|
+
bytes.push(hi << 4 | v);
|
|
22900
|
+
hi = -1;
|
|
22901
|
+
}
|
|
22227
22902
|
this.pos++;
|
|
22228
22903
|
}
|
|
22229
|
-
if (
|
|
22230
|
-
let result = "";
|
|
22231
|
-
for (let i = 0; i < hex.length; i += 2) {
|
|
22232
|
-
const byte = parseInt(hex.substring(i, i + 2), 16);
|
|
22233
|
-
if (!isNaN(byte)) result += String.fromCharCode(byte);
|
|
22234
|
-
}
|
|
22904
|
+
if (hi !== -1) bytes.push(hi << 4);
|
|
22235
22905
|
return {
|
|
22236
22906
|
type: TokenType.HexString,
|
|
22237
|
-
value:
|
|
22907
|
+
value: String.fromCharCode.apply(null, bytes)
|
|
22238
22908
|
};
|
|
22239
22909
|
}
|
|
22240
22910
|
/**
|
|
@@ -22242,27 +22912,25 @@ var ContentStreamLexer = class {
|
|
|
22242
22912
|
*/
|
|
22243
22913
|
readName() {
|
|
22244
22914
|
this.pos++;
|
|
22245
|
-
|
|
22915
|
+
const parts = ["/"];
|
|
22246
22916
|
while (this.pos < this.data.length) {
|
|
22247
22917
|
const ch = this.data[this.pos];
|
|
22248
22918
|
if (this.isWhitespace(ch) || this.isDelimiter(ch)) break;
|
|
22249
22919
|
if (ch === 35 && this.pos + 2 < this.data.length) {
|
|
22250
|
-
const hi = this.data[this.pos + 1];
|
|
22251
|
-
const lo = this.data[this.pos + 2];
|
|
22252
|
-
|
|
22253
|
-
|
|
22254
|
-
if (!isNaN(code)) {
|
|
22255
|
-
name += String.fromCharCode(code);
|
|
22920
|
+
const hi = hexVal[this.data[this.pos + 1]];
|
|
22921
|
+
const lo = hexVal[this.data[this.pos + 2]];
|
|
22922
|
+
if (hi !== -1 && lo !== -1) {
|
|
22923
|
+
parts.push(String.fromCharCode(hi << 4 | lo));
|
|
22256
22924
|
this.pos += 3;
|
|
22257
22925
|
continue;
|
|
22258
22926
|
}
|
|
22259
22927
|
}
|
|
22260
|
-
|
|
22928
|
+
parts.push(String.fromCharCode(ch));
|
|
22261
22929
|
this.pos++;
|
|
22262
22930
|
}
|
|
22263
22931
|
return {
|
|
22264
22932
|
type: TokenType.Name,
|
|
22265
|
-
value: PdfName.of(
|
|
22933
|
+
value: PdfName.of(parts.join(""))
|
|
22266
22934
|
};
|
|
22267
22935
|
}
|
|
22268
22936
|
/**
|
|
@@ -22356,9 +23024,7 @@ var ContentStreamLexer = class {
|
|
|
22356
23024
|
* Decode a slice of the data as ASCII text.
|
|
22357
23025
|
*/
|
|
22358
23026
|
decodeAscii(start, end) {
|
|
22359
|
-
|
|
22360
|
-
for (let i = start; i < end; i++) s += String.fromCharCode(this.data[i]);
|
|
22361
|
-
return s;
|
|
23027
|
+
return String.fromCharCode.apply(null, this.data.subarray(start, end));
|
|
22362
23028
|
}
|
|
22363
23029
|
};
|
|
22364
23030
|
|
|
@@ -23354,10 +24020,10 @@ async function initWasm(options) {
|
|
|
23354
24020
|
if (options === void 0 || typeof options === "string" || options instanceof URL) return;
|
|
23355
24021
|
if (wasmInitialized) return;
|
|
23356
24022
|
const inits = [];
|
|
23357
|
-
if (options.deflate || options.deflateWasm) inits.push(import("./libdeflateWasm-
|
|
24023
|
+
if (options.deflate || options.deflateWasm) inits.push(import("./libdeflateWasm-DlHgU5oy.mjs").then((n) => n.r).then(async ({ initDeflateWasm }) => {
|
|
23358
24024
|
await initDeflateWasm(options.deflateWasm);
|
|
23359
24025
|
}));
|
|
23360
|
-
if (options.png || options.pngWasm) inits.push(import("./pngEmbed-
|
|
24026
|
+
if (options.png || options.pngWasm) inits.push(import("./pngEmbed-DTOqgEUC.mjs").then((n) => n.n).then(async ({ initPngWasm }) => {
|
|
23361
24027
|
await initPngWasm(options.pngWasm);
|
|
23362
24028
|
}));
|
|
23363
24029
|
if (options.fonts || options.fontWasm) inits.push(import("./fontSubset-ZpLoOZ2e.mjs").then((n) => n.r).then(async ({ initSubsetWasm }) => {
|
|
@@ -23368,5 +24034,5 @@ async function initWasm(options) {
|
|
|
23368
24034
|
}
|
|
23369
24035
|
|
|
23370
24036
|
//#endregion
|
|
23371
|
-
export { AnnotationFlags, BlendMode, ChangeTracker, CombedTextLayoutError, EmbeddedFont, EncryptedPdfError, ExceededMaxLengthError, FieldAlreadyExistsError, FieldExistsAsNonTerminalError, FieldFlags, FontNotEmbeddedError, ForeignPageError, ImageAlignment, InvalidFieldNamePartError, LineCapStyle, LineJoinStyle, MissingOnValueCheckError, NoSuchFieldError, PDFOperator, PageSizes, ParseSpeeds, PdfAnnotation, PdfArray, PdfBool, PdfButtonField, PdfCheckboxField, PdfCircleAnnotation, PdfDict, PdfDocument, PdfDropdownField, PdfEncryptionHandler, PdfField, PdfForm, PdfFreeTextAnnotation, PdfHighlightAnnotation, PdfInkAnnotation, PdfLayer, PdfLayerManager, PdfLineAnnotation, PdfLinkAnnotation, PdfListboxField, PdfName, PdfNull, PdfNumber, PdfObjectRegistry, PdfOutlineItem, PdfOutlineTree, PdfPage, PdfPolyLineAnnotation, PdfPolygonAnnotation, PdfRadioGroup, PdfRedactAnnotation, PdfRef, PdfSignatureField, PdfSquareAnnotation, PdfSquigglyAnnotation, PdfStampAnnotation, PdfStream, PdfStreamWriter, PdfStrikeOutAnnotation, PdfString, PdfStructureElement, PdfStructureTree, PdfTextAnnotation, PdfTextField, PdfUnderlineAnnotation, PdfViewerPreferences, PdfWriter, RemovePageFromEmptyDocumentError, RichTextFieldReadError, StandardFonts, TextAlignment, TextRenderingMode, UnexpectedFieldTypeError, addWatermark, addWatermarkToPage, aesDecryptCBC, aesEncryptCBC, annotationFromDict, applyFillColor, applyRedactions, applyStrokeColor, asNumber, asPDFName, asPDFNumber, attachFile, base64Decode, base64Encode, beginArtifact, beginArtifactWithType, beginLayerContent, beginMarkedContent, beginMarkedContentSequence, beginMarkedContentWithProperties, beginText, buildAnnotationDict, buildCatalog, buildDocumentStructure, buildEmbeddedFilesNameTree, buildInfoDict, buildPageTree, buildPkcs7Signature, buildTimestampRequest, buildViewerPreferencesDict, buildXmpMetadata, checkAccessibility, circlePath, clipEvenOdd, clip as clipOp, closeAndStroke, closeFillAndStroke, closeFillEvenOddAndStroke, closePath as closePathOp, cmyk, colorToComponents, componentsToColor, computeFileEncryptionKey, computeFontSize, computeSignatureHash, concatMatrix, concatMatrix as concatTransformationMatrix, copyPages, createAnnotation, createMarkedContentScope, createPdf, createXmpStream, cropPage, curveToFinal, curveToInitial, curveTo as curveToOp, decodePermissions, decodeStream, degrees, degreesToRadians, drawImageWithMatrix, drawImageXObject, drawXObject as drawObject, drawXObject, drawSvgOnPage, ellipsePath, embedPageAsFormXObject, embedSignature, encodeContextTag, encodeInteger, encodeLength, encodeOID, encodeOctetString, encodePermissions, encodePrintableString, encodeSequence, encodeSet, encodeUTCTime, encodeUtf8String, endArtifact, endLayerContent, endMarkedContent, endPath as endPathOp, endText, enforcePdfA, extractMetrics, extractText, extractTextWithPositions, fillAndStroke as fillAndStrokeOp, fillEvenOdd, fillEvenOddAndStroke, fill as fillOp, findSignatures, formatPdfDate, generateButtonAppearance, generateCheckboxAppearance, generateCircleAppearance, generateDropdownAppearance, generateFreeTextAppearance, generateHighlightAppearance, generateInkAppearance, generateLineAppearance, generateListboxAppearance, generateRadioAppearance, generateSignatureAppearance, generateSquareAppearance, generateSquigglyAppearance, generateStrikeOutAppearance, generateTextAppearance, generateUnderlineAppearance, getAttachments, getPageSize, getRedactionMarks, getSignatures, grayscale, initWasm, insertPage, isAccessible, isLinearized, isOpenTypeCFF, isTrueType, layoutCombedText, layoutMultilineText, layoutSinglelineText, lineTo as lineToOp, linearizePdf, loadPdf, markForRedaction, md5, mergePdfs, movePage, moveText as moveTextOp, moveTextSetLeading, moveTo as moveToOp, nextLine as nextLineOp, parseContentStream, parseSvg, parseSvgColor, parseSvgPath, parseSvgTransform, parseTimestampResponse, parseViewerPreferences, parseXmpMetadata, restoreState as popGraphicsState, restoreState, prepareForSigning, saveState as pushGraphicsState, saveState, radians, radiansToDegrees, rc4, rectangle as rectangleOp, removePage, removePages, requestTimestamp, resizePage, reversePages, rgb, rotateAllPages, rotate as rotateOp, rotatePage, rotationMatrix, saveDocumentIncremental, saveIncremental, scale as scaleOp, serializePdf, setCharacterSpacing as setCharacterSpacingOp, setCharacterSpacing as setCharacterSqueeze, setColorSpace, setDashPattern as setDashPatternOp, setFillColor, setFillColorCmyk, setFillColorGray, setFillColorRgb, setFillingColor, setFlatness, setFont as setFontAndSize, setFont as setFontOp, setFontSize as setFontSizeOp, setGraphicsState as setGraphicsStateOp, setLeading as setLeadingOp, setLeading as setLineHeight, setLineCap as setLineCapOp, setLineJoin as setLineJoinOp, setLineWidth as setLineWidthOp, setMiterLimit, setStrokeColor, setStrokeColorCmyk, setStrokeColorGray, setStrokeColorRgb, setStrokeColorSpace, setStrokingColor, setTextMatrix as setTextMatrixOp, setTextRenderingMode as setTextRenderingModeOp, setTextRise as setTextRiseOp, setWordSpacing as setWordSpacingOp, sha256, sha384, sha512, showTextArray, showTextHex, showTextNextLine, showText as showTextOp, showTextWithSpacing, signPdf, skew as skewOp, splitPdf, stroke as strokeOp, summarizeIssues, svgToPdfOperators, translate as translateOp, validatePdfA, verifyOwnerPassword, verifySignature, verifySignatures, verifyUserPassword, wrapInMarkedContent };
|
|
24037
|
+
export { AnnotationFlags, BlendMode, ChangeTracker, CombedTextLayoutError, EmbeddedFont, EncryptedPdfError, ExceededMaxLengthError, FieldAlreadyExistsError, FieldExistsAsNonTerminalError, FieldFlags, FontNotEmbeddedError, ForeignPageError, ImageAlignment, InvalidFieldNamePartError, LineCapStyle, LineJoinStyle, MissingOnValueCheckError, NoSuchFieldError, PDFOperator, PageSizes, ParseSpeeds, PdfAnnotation, PdfArray, PdfBool, PdfButtonField, PdfCheckboxField, PdfCircleAnnotation, PdfDict, PdfDocument, PdfDropdownField, PdfEncryptionHandler, PdfField, PdfForm, PdfFreeTextAnnotation, PdfHighlightAnnotation, PdfInkAnnotation, PdfLayer, PdfLayerManager, PdfLineAnnotation, PdfLinkAnnotation, PdfListboxField, PdfName, PdfNull, PdfNumber, PdfObjectRegistry, PdfOutlineItem, PdfOutlineTree, PdfPage, PdfParseError, PdfPolyLineAnnotation, PdfPolygonAnnotation, PdfRadioGroup, PdfRedactAnnotation, PdfRef, PdfSignatureField, PdfSquareAnnotation, PdfSquigglyAnnotation, PdfStampAnnotation, PdfStream, PdfStreamWriter, PdfStrikeOutAnnotation, PdfString, PdfStructureElement, PdfStructureTree, PdfTextAnnotation, PdfTextField, PdfUnderlineAnnotation, PdfViewerPreferences, PdfWriter, RemovePageFromEmptyDocumentError, RichTextFieldReadError, StandardFonts, TextAlignment, TextRenderingMode, UnexpectedFieldTypeError, addWatermark, addWatermarkToPage, aesDecryptCBC, aesEncryptCBC, annotationFromDict, applyFillColor, applyRedactions, applyStrokeColor, asNumber, asPDFName, asPDFNumber, attachFile, base64Decode, base64Encode, beginArtifact, beginArtifactWithType, beginLayerContent, beginMarkedContent, beginMarkedContentSequence, beginMarkedContentWithProperties, beginText, buildAnnotationDict, buildCatalog, buildDocumentStructure, buildEmbeddedFilesNameTree, buildGradientObjects, buildInfoDict, buildPageTree, buildPatternObjects, buildPkcs7Signature, buildTimestampRequest, buildViewerPreferencesDict, buildXmpMetadata, checkAccessibility, circlePath, clipEvenOdd, clip as clipOp, closeAndStroke, closeFillAndStroke, closeFillEvenOddAndStroke, closePath as closePathOp, cmyk, colorToComponents, componentsToColor, computeFileEncryptionKey, computeFontSize, computeSignatureHash, concatMatrix, concatMatrix as concatTransformationMatrix, copyPages, createAnnotation, createMarkedContentScope, createPdf, createXmpStream, cropPage, curveToFinal, curveToInitial, curveTo as curveToOp, decodePermissions, decodeStream, degrees, degreesToRadians, drawImageWithMatrix, drawImageXObject, drawXObject as drawObject, drawXObject, drawSvgOnPage, ellipsePath, embedPageAsFormXObject, embedSignature, encodeContextTag, encodeInteger, encodeLength, encodeOID, encodeOctetString, encodePermissions, encodePrintableString, encodeSequence, encodeSet, encodeUTCTime, encodeUtf8String, endArtifact, endLayerContent, endMarkedContent, endPath as endPathOp, endText, enforcePdfA, extractMetrics, extractText, extractTextWithPositions, fillAndStroke as fillAndStrokeOp, fillEvenOdd, fillEvenOddAndStroke, fill as fillOp, findSignatures, formatHexContext, formatPdfDate, generateButtonAppearance, generateCheckboxAppearance, generateCircleAppearance, generateDropdownAppearance, generateFreeTextAppearance, generateHighlightAppearance, generateInkAppearance, generateLineAppearance, generateListboxAppearance, generateRadioAppearance, generateSignatureAppearance, generateSquareAppearance, generateSquigglyAppearance, generateStrikeOutAppearance, generateTextAppearance, generateUnderlineAppearance, getAttachments, getPageSize, getRedactionMarks, getSignatures, grayscale, initWasm, insertPage, isAccessible, isLinearized, isOpenTypeCFF, isTrueType, layoutCombedText, layoutMultilineText, layoutSinglelineText, lineTo as lineToOp, linearGradient, linearizePdf, loadPdf, markForRedaction, md5, mergePdfs, movePage, moveText as moveTextOp, moveTextSetLeading, moveTo as moveToOp, nextLine as nextLineOp, parseContentStream, parseSvg, parseSvgColor, parseSvgPath, parseSvgTransform, parseTimestampResponse, parseViewerPreferences, parseXmpMetadata, restoreState as popGraphicsState, restoreState, prepareForSigning, saveState as pushGraphicsState, saveState, radialGradient, radians, radiansToDegrees, rc4, rectangle as rectangleOp, removePage, removePages, requestTimestamp, resizePage, reversePages, rgb, rotateAllPages, rotate as rotateOp, rotatePage, rotationMatrix, saveDocumentIncremental, saveIncremental, scale as scaleOp, serializePdf, setCharacterSpacing as setCharacterSpacingOp, setCharacterSpacing as setCharacterSqueeze, setColorSpace, setDashPattern as setDashPatternOp, setFillColor, setFillColorCmyk, setFillColorGray, setFillColorRgb, setFillingColor, setFlatness, setFont as setFontAndSize, setFont as setFontOp, setFontSize as setFontSizeOp, setGraphicsState as setGraphicsStateOp, setLeading as setLeadingOp, setLeading as setLineHeight, setLineCap as setLineCapOp, setLineJoin as setLineJoinOp, setLineWidth as setLineWidthOp, setMiterLimit, setStrokeColor, setStrokeColorCmyk, setStrokeColorGray, setStrokeColorRgb, setStrokeColorSpace, setStrokingColor, setTextMatrix as setTextMatrixOp, setTextRenderingMode as setTextRenderingModeOp, setTextRise as setTextRiseOp, setWordSpacing as setWordSpacingOp, sha256, sha384, sha512, showTextArray, showTextHex, showTextNextLine, showText as showTextOp, showTextWithSpacing, signPdf, skew as skewOp, splitPdf, stroke as strokeOp, summarizeIssues, svgToPdfOperators, tilingPattern, translate as translateOp, validatePdfA, verifyOwnerPassword, verifySignature, verifySignatures, verifyUserPassword, wrapInMarkedContent };
|
|
23372
24038
|
//# sourceMappingURL=index.mjs.map
|