modern-pdf-lib 0.12.0 → 0.13.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/{fflateAdapter-cT4YeY_h.cjs → fflateAdapter-AHC_S3cb.cjs} +1 -1
- package/dist/{fflateAdapter-D2mv_ttM.mjs → fflateAdapter-DX0VqT5k.mjs} +1 -1
- package/dist/{fontSubset-ClyTXlhY.mjs → fontSubset-ZpLoOZ2e.mjs} +1 -1
- package/dist/{fontSubset-BxsF9Tu5.cjs → fontSubset-pFc8Dueu.cjs} +1 -1
- package/dist/index.cjs +19696 -96
- package/dist/index.d.cts +393 -10
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +393 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +19601 -8
- package/dist/{libdeflateWasm-QVHmuzw-.mjs → libdeflateWasm-DlHgU5oy.mjs} +2 -2
- package/dist/{libdeflateWasm-to2bG6NG.cjs → libdeflateWasm-OkNoqBnO.cjs} +2 -2
- package/dist/{loader-D9LTYmrX.mjs → loader-CQfoGFp9.mjs} +4 -3
- package/dist/{loader-mwt5wRJz.cjs → loader-_fqS-TmT.cjs} +4 -3
- package/dist/{pdfPage-JiCJLV3x.mjs → pdfPage-B7vA518n.mjs} +644 -216
- package/dist/{pdfPage-BMGFx7Xd.cjs → pdfPage-BebMv6fN.cjs} +672 -214
- package/dist/{pngEmbed-D4Uig1LV.mjs → pngEmbed-DTOqgEUC.mjs} +2 -2
- package/dist/{pngEmbed-BogDTEfL.cjs → pngEmbed-OYyOe_W0.cjs} +2 -2
- package/package.json +2 -2
- package/dist/documentMerge-F1EwwhJP.mjs +0 -19081
- package/dist/documentMerge-SGckZBSb.cjs +0 -19608
|
@@ -2705,6 +2705,162 @@ function drawSvgOnPage(page, svgString, options) {
|
|
|
2705
2705
|
page.pushOperators(ops);
|
|
2706
2706
|
}
|
|
2707
2707
|
|
|
2708
|
+
//#endregion
|
|
2709
|
+
//#region src/core/pdfPageSvg.ts
|
|
2710
|
+
/** Format a number for PDF output. */
|
|
2711
|
+
function fmtN(value) {
|
|
2712
|
+
if (Number.isInteger(value)) return value.toString();
|
|
2713
|
+
const s = value.toFixed(6).replace(/\.?0+$/, "");
|
|
2714
|
+
return s === "-0" ? "0" : s;
|
|
2715
|
+
}
|
|
2716
|
+
/** Magic constant for circular arc approximation: 4*(sqrt(2)-1)/3. */
|
|
2717
|
+
const KAPPA = .5522847498;
|
|
2718
|
+
/**
|
|
2719
|
+
* Approximate an SVG arc command as cubic Bezier curve(s) (PDF operators).
|
|
2720
|
+
*
|
|
2721
|
+
* SVG arcs use endpoint parameterization; PDF has no native arc command.
|
|
2722
|
+
*/
|
|
2723
|
+
function svgArcToPdfOps(fromX, fromY, rx0, ry0, rotationDeg, largeArcFlag, sweepFlag, toX, toY) {
|
|
2724
|
+
let rx = Math.abs(rx0);
|
|
2725
|
+
let ry = Math.abs(ry0);
|
|
2726
|
+
if (rx === 0 || ry === 0) return `${fmtN(toX)} ${fmtN(toY)} l\n`;
|
|
2727
|
+
const phi = rotationDeg * Math.PI / 180;
|
|
2728
|
+
const cosPhi = Math.cos(phi);
|
|
2729
|
+
const sinPhi = Math.sin(phi);
|
|
2730
|
+
const dx2 = (fromX - toX) / 2;
|
|
2731
|
+
const dy2 = (fromY - toY) / 2;
|
|
2732
|
+
const x1p = cosPhi * dx2 + sinPhi * dy2;
|
|
2733
|
+
const y1p = -sinPhi * dx2 + cosPhi * dy2;
|
|
2734
|
+
let rxSq = rx * rx;
|
|
2735
|
+
let rySq = ry * ry;
|
|
2736
|
+
const x1pSq = x1p * x1p;
|
|
2737
|
+
const y1pSq = y1p * y1p;
|
|
2738
|
+
const lambda = x1pSq / rxSq + y1pSq / rySq;
|
|
2739
|
+
if (lambda > 1) {
|
|
2740
|
+
const s = Math.sqrt(lambda);
|
|
2741
|
+
rx *= s;
|
|
2742
|
+
ry *= s;
|
|
2743
|
+
rxSq = rx * rx;
|
|
2744
|
+
rySq = ry * ry;
|
|
2745
|
+
}
|
|
2746
|
+
let sq = (rxSq * rySq - rxSq * y1pSq - rySq * x1pSq) / (rxSq * y1pSq + rySq * x1pSq);
|
|
2747
|
+
if (sq < 0) sq = 0;
|
|
2748
|
+
sq = Math.sqrt(sq);
|
|
2749
|
+
if (largeArcFlag === sweepFlag) sq = -sq;
|
|
2750
|
+
const cxp = sq * rx * y1p / ry;
|
|
2751
|
+
const cyp = -sq * ry * x1p / rx;
|
|
2752
|
+
const cx = cosPhi * cxp - sinPhi * cyp + (fromX + toX) / 2;
|
|
2753
|
+
const cy = sinPhi * cxp + cosPhi * cyp + (fromY + toY) / 2;
|
|
2754
|
+
function vecAngle(ux, uy, vx, vy) {
|
|
2755
|
+
const sign = ux * vy - uy * vx < 0 ? -1 : 1;
|
|
2756
|
+
let r = (ux * vx + uy * vy) / (Math.sqrt(ux * ux + uy * uy) * Math.sqrt(vx * vx + vy * vy));
|
|
2757
|
+
if (r < -1) r = -1;
|
|
2758
|
+
if (r > 1) r = 1;
|
|
2759
|
+
return sign * Math.acos(r);
|
|
2760
|
+
}
|
|
2761
|
+
const theta1 = vecAngle(1, 0, (x1p - cxp) / rx, (y1p - cyp) / ry);
|
|
2762
|
+
let dTheta = vecAngle((x1p - cxp) / rx, (y1p - cyp) / ry, (-x1p - cxp) / rx, (-y1p - cyp) / ry);
|
|
2763
|
+
if (sweepFlag === 0 && dTheta > 0) dTheta -= 2 * Math.PI;
|
|
2764
|
+
if (sweepFlag === 1 && dTheta < 0) dTheta += 2 * Math.PI;
|
|
2765
|
+
const segs = Math.ceil(Math.abs(dTheta) / (Math.PI / 2));
|
|
2766
|
+
const segAngle = dTheta / segs;
|
|
2767
|
+
let ops = "";
|
|
2768
|
+
let angle = theta1;
|
|
2769
|
+
for (let i = 0; i < segs; i++) {
|
|
2770
|
+
const a1 = angle;
|
|
2771
|
+
const a2 = angle + segAngle;
|
|
2772
|
+
const alpha = 4 / 3 * Math.tan((a2 - a1) / 4);
|
|
2773
|
+
const cos1 = Math.cos(a1), sin1 = Math.sin(a1);
|
|
2774
|
+
const cos2 = Math.cos(a2), sin2 = Math.sin(a2);
|
|
2775
|
+
const ep1x = cosPhi * rx * cos1 - sinPhi * ry * sin1 + cx;
|
|
2776
|
+
const ep1y = sinPhi * rx * cos1 + cosPhi * ry * sin1 + cy;
|
|
2777
|
+
const cp1x = ep1x + alpha * (-cosPhi * rx * sin1 - sinPhi * ry * cos1);
|
|
2778
|
+
const cp1y = ep1y + alpha * (-sinPhi * rx * sin1 + cosPhi * ry * cos1);
|
|
2779
|
+
const ep2x = cosPhi * rx * cos2 - sinPhi * ry * sin2 + cx;
|
|
2780
|
+
const ep2y = sinPhi * rx * cos2 + cosPhi * ry * sin2 + cy;
|
|
2781
|
+
const cp2x = ep2x - alpha * (-cosPhi * rx * sin2 - sinPhi * ry * cos2);
|
|
2782
|
+
const cp2y = ep2y - alpha * (-sinPhi * rx * sin2 + cosPhi * ry * cos2);
|
|
2783
|
+
ops += `${fmtN(cp1x)} ${fmtN(cp1y)} ${fmtN(cp2x)} ${fmtN(cp2y)} ${fmtN(ep2x)} ${fmtN(ep2y)} c\n`;
|
|
2784
|
+
angle = a2;
|
|
2785
|
+
}
|
|
2786
|
+
return ops;
|
|
2787
|
+
}
|
|
2788
|
+
/**
|
|
2789
|
+
* Convert parsed SVG draw commands into PDF path construction operators.
|
|
2790
|
+
*
|
|
2791
|
+
* Does **not** emit painting operators (fill / stroke) -- the caller
|
|
2792
|
+
* is responsible for that.
|
|
2793
|
+
*/
|
|
2794
|
+
function svgCommandsToPdfOps(commands) {
|
|
2795
|
+
let ops = "";
|
|
2796
|
+
let curX = 0;
|
|
2797
|
+
let curY = 0;
|
|
2798
|
+
for (const cmd of commands) switch (cmd.type) {
|
|
2799
|
+
case "moveTo":
|
|
2800
|
+
curX = cmd.params[0];
|
|
2801
|
+
curY = cmd.params[1];
|
|
2802
|
+
ops += `${fmtN(curX)} ${fmtN(curY)} m\n`;
|
|
2803
|
+
break;
|
|
2804
|
+
case "lineTo":
|
|
2805
|
+
curX = cmd.params[0];
|
|
2806
|
+
curY = cmd.params[1];
|
|
2807
|
+
ops += `${fmtN(curX)} ${fmtN(curY)} l\n`;
|
|
2808
|
+
break;
|
|
2809
|
+
case "curveTo":
|
|
2810
|
+
ops += `${fmtN(cmd.params[0])} ${fmtN(cmd.params[1])} ${fmtN(cmd.params[2])} ${fmtN(cmd.params[3])} ${fmtN(cmd.params[4])} ${fmtN(cmd.params[5])} c\n`;
|
|
2811
|
+
curX = cmd.params[4];
|
|
2812
|
+
curY = cmd.params[5];
|
|
2813
|
+
break;
|
|
2814
|
+
case "quadCurveTo": {
|
|
2815
|
+
const cpx = cmd.params[0];
|
|
2816
|
+
const cpy = cmd.params[1];
|
|
2817
|
+
const toX = cmd.params[2];
|
|
2818
|
+
const toY = cmd.params[3];
|
|
2819
|
+
const cp1x = curX + 2 / 3 * (cpx - curX);
|
|
2820
|
+
const cp1y = curY + 2 / 3 * (cpy - curY);
|
|
2821
|
+
const cp2x = toX + 2 / 3 * (cpx - toX);
|
|
2822
|
+
const cp2y = toY + 2 / 3 * (cpy - toY);
|
|
2823
|
+
ops += `${fmtN(cp1x)} ${fmtN(cp1y)} ${fmtN(cp2x)} ${fmtN(cp2y)} ${fmtN(toX)} ${fmtN(toY)} c\n`;
|
|
2824
|
+
curX = toX;
|
|
2825
|
+
curY = toY;
|
|
2826
|
+
break;
|
|
2827
|
+
}
|
|
2828
|
+
case "closePath":
|
|
2829
|
+
ops += "h\n";
|
|
2830
|
+
break;
|
|
2831
|
+
case "rect":
|
|
2832
|
+
ops += `${fmtN(cmd.params[0])} ${fmtN(cmd.params[1])} ${fmtN(cmd.params[2])} ${fmtN(cmd.params[3])} re\n`;
|
|
2833
|
+
break;
|
|
2834
|
+
case "circle": {
|
|
2835
|
+
const ccx = cmd.params[0], ccy = cmd.params[1], r = cmd.params[2];
|
|
2836
|
+
const ox = r * KAPPA, oy = r * KAPPA;
|
|
2837
|
+
ops += `${fmtN(ccx)} ${fmtN(ccy + r)} m\n`;
|
|
2838
|
+
ops += `${fmtN(ccx + ox)} ${fmtN(ccy + r)} ${fmtN(ccx + r)} ${fmtN(ccy + oy)} ${fmtN(ccx + r)} ${fmtN(ccy)} c\n`;
|
|
2839
|
+
ops += `${fmtN(ccx + r)} ${fmtN(ccy - oy)} ${fmtN(ccx + ox)} ${fmtN(ccy - r)} ${fmtN(ccx)} ${fmtN(ccy - r)} c\n`;
|
|
2840
|
+
ops += `${fmtN(ccx - ox)} ${fmtN(ccy - r)} ${fmtN(ccx - r)} ${fmtN(ccy - oy)} ${fmtN(ccx - r)} ${fmtN(ccy)} c\n`;
|
|
2841
|
+
ops += `${fmtN(ccx - r)} ${fmtN(ccy + oy)} ${fmtN(ccx - ox)} ${fmtN(ccy + r)} ${fmtN(ccx)} ${fmtN(ccy + r)} c\n`;
|
|
2842
|
+
break;
|
|
2843
|
+
}
|
|
2844
|
+
case "ellipse": {
|
|
2845
|
+
const ecx = cmd.params[0], ecy = cmd.params[1];
|
|
2846
|
+
const erx = cmd.params[2], ery = cmd.params[3];
|
|
2847
|
+
const eox = erx * KAPPA, eoy = ery * KAPPA;
|
|
2848
|
+
ops += `${fmtN(ecx)} ${fmtN(ecy + ery)} m\n`;
|
|
2849
|
+
ops += `${fmtN(ecx + eox)} ${fmtN(ecy + ery)} ${fmtN(ecx + erx)} ${fmtN(ecy + eoy)} ${fmtN(ecx + erx)} ${fmtN(ecy)} c\n`;
|
|
2850
|
+
ops += `${fmtN(ecx + erx)} ${fmtN(ecy - eoy)} ${fmtN(ecx + eox)} ${fmtN(ecy - ery)} ${fmtN(ecx)} ${fmtN(ecy - ery)} c\n`;
|
|
2851
|
+
ops += `${fmtN(ecx - eox)} ${fmtN(ecy - ery)} ${fmtN(ecx - erx)} ${fmtN(ecy - eoy)} ${fmtN(ecx - erx)} ${fmtN(ecy)} c\n`;
|
|
2852
|
+
ops += `${fmtN(ecx - erx)} ${fmtN(ecy + eoy)} ${fmtN(ecx - eox)} ${fmtN(ecy + ery)} ${fmtN(ecx)} ${fmtN(ecy + ery)} c\n`;
|
|
2853
|
+
break;
|
|
2854
|
+
}
|
|
2855
|
+
case "arc":
|
|
2856
|
+
ops += svgArcToPdfOps(curX, curY, cmd.params[0], cmd.params[1], cmd.params[2], cmd.params[3], cmd.params[4], cmd.params[5], cmd.params[6]);
|
|
2857
|
+
curX = cmd.params[5];
|
|
2858
|
+
curY = cmd.params[6];
|
|
2859
|
+
break;
|
|
2860
|
+
}
|
|
2861
|
+
return ops;
|
|
2862
|
+
}
|
|
2863
|
+
|
|
2708
2864
|
//#endregion
|
|
2709
2865
|
//#region src/layers/optionalContent.ts
|
|
2710
2866
|
/**
|
|
@@ -3009,66 +3165,238 @@ function getRedactionMarks(page) {
|
|
|
3009
3165
|
}
|
|
3010
3166
|
|
|
3011
3167
|
//#endregion
|
|
3012
|
-
//#region src/core/
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3168
|
+
//#region src/core/patterns.ts
|
|
3169
|
+
/** Convert a Color to RGB components (0..1). CMYK/gray are converted. */
|
|
3170
|
+
function colorToRgb(c) {
|
|
3171
|
+
switch (c.type) {
|
|
3172
|
+
case "rgb": return {
|
|
3173
|
+
r: c.r,
|
|
3174
|
+
g: c.g,
|
|
3175
|
+
b: c.b
|
|
3176
|
+
};
|
|
3177
|
+
case "grayscale": return {
|
|
3178
|
+
r: c.gray,
|
|
3179
|
+
g: c.gray,
|
|
3180
|
+
b: c.gray
|
|
3181
|
+
};
|
|
3182
|
+
case "cmyk": return {
|
|
3183
|
+
r: (1 - c.c) * (1 - c.k),
|
|
3184
|
+
g: (1 - c.m) * (1 - c.k),
|
|
3185
|
+
b: (1 - c.y) * (1 - c.k)
|
|
3186
|
+
};
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
/** Check if a stop is a ColorStop (has `offset` property). */
|
|
3190
|
+
function isColorStop(stop) {
|
|
3191
|
+
return "offset" in stop && "color" in stop;
|
|
3192
|
+
}
|
|
3193
|
+
/**
|
|
3194
|
+
* Normalise an array of stops into sorted, explicit-offset RGB stops.
|
|
3195
|
+
* Bare Color values get evenly-distributed offsets.
|
|
3196
|
+
*/
|
|
3197
|
+
function normalizeStops(stops) {
|
|
3198
|
+
if (stops.length < 2) throw new Error("Gradient requires at least 2 colour stops");
|
|
3199
|
+
const result = [];
|
|
3200
|
+
for (let i = 0; i < stops.length; i++) {
|
|
3201
|
+
const stop = stops[i];
|
|
3202
|
+
let offset;
|
|
3203
|
+
let color;
|
|
3204
|
+
if (isColorStop(stop)) {
|
|
3205
|
+
offset = stop.offset;
|
|
3206
|
+
color = stop.color;
|
|
3207
|
+
} else {
|
|
3208
|
+
offset = i / (stops.length - 1);
|
|
3209
|
+
color = stop;
|
|
3210
|
+
}
|
|
3211
|
+
const { r, g, b } = colorToRgb(color);
|
|
3212
|
+
result.push({
|
|
3213
|
+
offset,
|
|
3214
|
+
r,
|
|
3215
|
+
g,
|
|
3216
|
+
b
|
|
3217
|
+
});
|
|
3218
|
+
}
|
|
3219
|
+
result.sort((a, b) => a.offset - b.offset);
|
|
3220
|
+
return result;
|
|
3221
|
+
}
|
|
3222
|
+
/**
|
|
3223
|
+
* Create a linear (axial) gradient descriptor.
|
|
3224
|
+
*
|
|
3225
|
+
* The gradient runs from `(x1, y1)` to `(x2, y2)` through the given
|
|
3226
|
+
* colour stops. By default the gradient extends beyond its endpoints.
|
|
3227
|
+
*
|
|
3228
|
+
* @param options Gradient parameters.
|
|
3229
|
+
* @returns A {@link GradientFill} descriptor.
|
|
3230
|
+
*/
|
|
3231
|
+
function linearGradient(options) {
|
|
3232
|
+
const normalizedStops = normalizeStops(options.stops);
|
|
3233
|
+
return {
|
|
3234
|
+
kind: "gradient",
|
|
3235
|
+
shadingType: 2,
|
|
3236
|
+
coords: [
|
|
3237
|
+
options.x1,
|
|
3238
|
+
options.y1,
|
|
3239
|
+
options.x2,
|
|
3240
|
+
options.y2
|
|
3241
|
+
],
|
|
3242
|
+
normalizedStops,
|
|
3243
|
+
extend: options.extend ?? true
|
|
3244
|
+
};
|
|
3245
|
+
}
|
|
3246
|
+
/**
|
|
3247
|
+
* Create a radial gradient descriptor.
|
|
3248
|
+
*
|
|
3249
|
+
* The gradient interpolates between two circles: the start circle at
|
|
3250
|
+
* `(x0, y0)` with radius `r0` and the end circle at `(x1, y1)` with
|
|
3251
|
+
* radius `r1`.
|
|
3252
|
+
*
|
|
3253
|
+
* @param options Gradient parameters.
|
|
3254
|
+
* @returns A {@link GradientFill} descriptor (with `shadingType: 3`).
|
|
3255
|
+
*/
|
|
3256
|
+
function radialGradient(options) {
|
|
3257
|
+
const normalizedStops = normalizeStops(options.stops);
|
|
3258
|
+
return {
|
|
3259
|
+
kind: "gradient",
|
|
3260
|
+
shadingType: 3,
|
|
3261
|
+
coords: [
|
|
3262
|
+
options.x0,
|
|
3263
|
+
options.y0,
|
|
3264
|
+
options.r0,
|
|
3265
|
+
options.x1,
|
|
3266
|
+
options.y1,
|
|
3267
|
+
options.r1
|
|
3268
|
+
],
|
|
3269
|
+
normalizedStops,
|
|
3270
|
+
extend: options.extend ?? true
|
|
3271
|
+
};
|
|
3272
|
+
}
|
|
3273
|
+
/**
|
|
3274
|
+
* Create a tiling pattern descriptor.
|
|
3275
|
+
*
|
|
3276
|
+
* @param options Pattern parameters including the tile content stream.
|
|
3277
|
+
* @returns A {@link PatternFill} descriptor.
|
|
3278
|
+
*/
|
|
3279
|
+
function tilingPattern(options) {
|
|
3280
|
+
return {
|
|
3281
|
+
kind: "pattern",
|
|
3282
|
+
width: options.width,
|
|
3283
|
+
height: options.height,
|
|
3284
|
+
paintType: options.paintType ?? 1,
|
|
3285
|
+
tilingType: options.tilingType ?? 1,
|
|
3286
|
+
ops: options.ops
|
|
3287
|
+
};
|
|
3288
|
+
}
|
|
3289
|
+
/**
|
|
3290
|
+
* Build a Type 2 (exponential interpolation) function for a single
|
|
3291
|
+
* colour-transition segment between two RGB stops.
|
|
3292
|
+
*/
|
|
3293
|
+
function buildType2Function(c0, c1) {
|
|
3294
|
+
const fn = new require_pdfCatalog.PdfDict();
|
|
3295
|
+
fn.set("/FunctionType", require_pdfCatalog.PdfNumber.of(2));
|
|
3296
|
+
fn.set("/Domain", require_pdfCatalog.PdfArray.fromNumbers([0, 1]));
|
|
3297
|
+
fn.set("/C0", require_pdfCatalog.PdfArray.fromNumbers([
|
|
3298
|
+
c0.r,
|
|
3299
|
+
c0.g,
|
|
3300
|
+
c0.b
|
|
3301
|
+
]));
|
|
3302
|
+
fn.set("/C1", require_pdfCatalog.PdfArray.fromNumbers([
|
|
3303
|
+
c1.r,
|
|
3304
|
+
c1.g,
|
|
3305
|
+
c1.b
|
|
3306
|
+
]));
|
|
3307
|
+
fn.set("/N", require_pdfCatalog.PdfNumber.of(1));
|
|
3308
|
+
return fn;
|
|
3309
|
+
}
|
|
3310
|
+
/**
|
|
3311
|
+
* Build the shading function for a gradient.
|
|
3312
|
+
*
|
|
3313
|
+
* - 2 stops → single Type 2 (exponential interpolation) function.
|
|
3314
|
+
* - 3+ stops → Type 3 (stitching) function wrapping one Type 2 per segment.
|
|
3315
|
+
*/
|
|
3316
|
+
function buildShadingFunction(stops, registry) {
|
|
3317
|
+
if (stops.length === 2) {
|
|
3318
|
+
const fn = buildType2Function(stops[0], stops[1]);
|
|
3319
|
+
return registry.register(fn);
|
|
3320
|
+
}
|
|
3321
|
+
const stitchDict = new require_pdfCatalog.PdfDict();
|
|
3322
|
+
stitchDict.set("/FunctionType", require_pdfCatalog.PdfNumber.of(3));
|
|
3323
|
+
stitchDict.set("/Domain", require_pdfCatalog.PdfArray.fromNumbers([0, 1]));
|
|
3324
|
+
const subFunctions = [];
|
|
3325
|
+
const bounds = [];
|
|
3326
|
+
const encode = [];
|
|
3327
|
+
for (let i = 0; i < stops.length - 1; i++) {
|
|
3328
|
+
const fn = buildType2Function(stops[i], stops[i + 1]);
|
|
3329
|
+
subFunctions.push(registry.register(fn));
|
|
3330
|
+
if (i > 0) bounds.push(stops[i].offset);
|
|
3331
|
+
encode.push(0, 1);
|
|
3332
|
+
}
|
|
3333
|
+
stitchDict.set("/Functions", require_pdfCatalog.PdfArray.of(subFunctions));
|
|
3334
|
+
stitchDict.set("/Bounds", require_pdfCatalog.PdfArray.fromNumbers(bounds));
|
|
3335
|
+
stitchDict.set("/Encode", require_pdfCatalog.PdfArray.fromNumbers(encode));
|
|
3336
|
+
return registry.register(stitchDict);
|
|
3337
|
+
}
|
|
3338
|
+
/**
|
|
3339
|
+
* Materialise a {@link GradientFill} descriptor into actual PDF objects
|
|
3340
|
+
* in the given registry.
|
|
3341
|
+
*
|
|
3342
|
+
* @param gradient The gradient descriptor.
|
|
3343
|
+
* @param registry The document's object registry.
|
|
3344
|
+
* @returns An object with the pattern's indirect reference and a unique
|
|
3345
|
+
* resource name.
|
|
3346
|
+
*/
|
|
3347
|
+
function buildGradientObjects(gradient, registry) {
|
|
3348
|
+
const fnRef = buildShadingFunction(gradient.normalizedStops, registry);
|
|
3349
|
+
const shadingDict = new require_pdfCatalog.PdfDict();
|
|
3350
|
+
shadingDict.set("/ShadingType", require_pdfCatalog.PdfNumber.of(gradient.shadingType));
|
|
3351
|
+
shadingDict.set("/ColorSpace", require_pdfCatalog.PdfName.of("DeviceRGB"));
|
|
3352
|
+
shadingDict.set("/Coords", require_pdfCatalog.PdfArray.fromNumbers([...gradient.coords]));
|
|
3353
|
+
shadingDict.set("/Function", fnRef);
|
|
3354
|
+
shadingDict.set("/Extend", require_pdfCatalog.PdfArray.of([require_pdfCatalog.PdfBool.of(gradient.extend), require_pdfCatalog.PdfBool.of(gradient.extend)]));
|
|
3355
|
+
const shadingRef = registry.register(shadingDict);
|
|
3356
|
+
const patternDict = new require_pdfCatalog.PdfDict();
|
|
3357
|
+
patternDict.set("/Type", require_pdfCatalog.PdfName.of("Pattern"));
|
|
3358
|
+
patternDict.set("/PatternType", require_pdfCatalog.PdfNumber.of(2));
|
|
3359
|
+
patternDict.set("/Shading", shadingRef);
|
|
3360
|
+
const patternRef = registry.register(patternDict);
|
|
3361
|
+
return {
|
|
3362
|
+
patternRef,
|
|
3363
|
+
patternName: `Pat${patternRef.objectNumber}`
|
|
3364
|
+
};
|
|
3365
|
+
}
|
|
3366
|
+
/**
|
|
3367
|
+
* Materialise a {@link PatternFill} descriptor into actual PDF objects
|
|
3368
|
+
* in the given registry.
|
|
3369
|
+
*
|
|
3370
|
+
* @param pattern The tiling pattern descriptor.
|
|
3371
|
+
* @param registry The document's object registry.
|
|
3372
|
+
* @returns An object with the pattern's indirect reference and a unique
|
|
3373
|
+
* resource name.
|
|
3374
|
+
*/
|
|
3375
|
+
function buildPatternObjects(pattern, registry) {
|
|
3376
|
+
const dict = new require_pdfCatalog.PdfDict();
|
|
3377
|
+
dict.set("/Type", require_pdfCatalog.PdfName.of("Pattern"));
|
|
3378
|
+
dict.set("/PatternType", require_pdfCatalog.PdfNumber.of(1));
|
|
3379
|
+
dict.set("/PaintType", require_pdfCatalog.PdfNumber.of(pattern.paintType));
|
|
3380
|
+
dict.set("/TilingType", require_pdfCatalog.PdfNumber.of(pattern.tilingType));
|
|
3381
|
+
dict.set("/BBox", require_pdfCatalog.PdfArray.fromNumbers([
|
|
3382
|
+
0,
|
|
3383
|
+
0,
|
|
3384
|
+
pattern.width,
|
|
3385
|
+
pattern.height
|
|
3386
|
+
]));
|
|
3387
|
+
dict.set("/XStep", require_pdfCatalog.PdfNumber.of(pattern.width));
|
|
3388
|
+
dict.set("/YStep", require_pdfCatalog.PdfNumber.of(pattern.height));
|
|
3389
|
+
dict.set("/Resources", new require_pdfCatalog.PdfDict());
|
|
3390
|
+
const stream = require_pdfCatalog.PdfStream.fromString(pattern.ops, dict);
|
|
3391
|
+
const patternRef = registry.register(stream);
|
|
3392
|
+
return {
|
|
3393
|
+
patternRef,
|
|
3394
|
+
patternName: `Pat${patternRef.objectNumber}`
|
|
3395
|
+
};
|
|
3396
|
+
}
|
|
3397
|
+
|
|
3398
|
+
//#endregion
|
|
3399
|
+
//#region src/core/pdfPageText.ts
|
|
3072
3400
|
/**
|
|
3073
3401
|
* Break a single line of text into multiple lines that fit within `maxWidth`.
|
|
3074
3402
|
*
|
|
@@ -3153,6 +3481,67 @@ function breakWord(word, maxWidth, font, size) {
|
|
|
3153
3481
|
if (current !== "") fragments.push(current);
|
|
3154
3482
|
return fragments;
|
|
3155
3483
|
}
|
|
3484
|
+
|
|
3485
|
+
//#endregion
|
|
3486
|
+
//#region src/core/pdfPage.ts
|
|
3487
|
+
var pdfPage_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
3488
|
+
PageSizes: () => PageSizes,
|
|
3489
|
+
PdfPage: () => PdfPage
|
|
3490
|
+
});
|
|
3491
|
+
/** Pre-defined page sizes as `[width, height]` tuples in PDF points. */
|
|
3492
|
+
const PageSizes = {
|
|
3493
|
+
"4A0": [4767.87, 6740.79],
|
|
3494
|
+
"2A0": [3370.39, 4767.87],
|
|
3495
|
+
A0: [2383.94, 3370.39],
|
|
3496
|
+
A1: [1683.78, 2383.94],
|
|
3497
|
+
A2: [1190.55, 1683.78],
|
|
3498
|
+
A3: [841.89, 1190.55],
|
|
3499
|
+
A4: [595.28, 841.89],
|
|
3500
|
+
A5: [419.53, 595.28],
|
|
3501
|
+
A6: [297.64, 419.53],
|
|
3502
|
+
A7: [209.76, 297.64],
|
|
3503
|
+
A8: [147.4, 209.76],
|
|
3504
|
+
A9: [104.88, 147.4],
|
|
3505
|
+
A10: [73.7, 104.88],
|
|
3506
|
+
B0: [2834.65, 4008.19],
|
|
3507
|
+
B1: [2004.09, 2834.65],
|
|
3508
|
+
B2: [1417.32, 2004.09],
|
|
3509
|
+
B3: [1000.63, 1417.32],
|
|
3510
|
+
B4: [708.66, 1000.63],
|
|
3511
|
+
B5: [498.9, 708.66],
|
|
3512
|
+
B6: [354.33, 498.9],
|
|
3513
|
+
B7: [249.45, 354.33],
|
|
3514
|
+
B8: [175.75, 249.45],
|
|
3515
|
+
B9: [124.72, 175.75],
|
|
3516
|
+
B10: [87.87, 124.72],
|
|
3517
|
+
Letter: [612, 792],
|
|
3518
|
+
Legal: [612, 1008],
|
|
3519
|
+
Tabloid: [792, 1224],
|
|
3520
|
+
Ledger: [1224, 792],
|
|
3521
|
+
Executive: [521.86, 756],
|
|
3522
|
+
Folio: [612, 936],
|
|
3523
|
+
C0: [2599.37, 3676.54],
|
|
3524
|
+
C1: [1836.85, 2599.37],
|
|
3525
|
+
C2: [1298.27, 1836.85],
|
|
3526
|
+
C3: [918.43, 1298.27],
|
|
3527
|
+
C4: [649.13, 918.43],
|
|
3528
|
+
C5: [459.21, 649.13],
|
|
3529
|
+
C6: [323.15, 459.21],
|
|
3530
|
+
C7: [229.61, 323.15],
|
|
3531
|
+
C8: [161.57, 229.61],
|
|
3532
|
+
C9: [113.39, 161.57],
|
|
3533
|
+
C10: [79.37, 113.39],
|
|
3534
|
+
RA0: [2437.8, 3458.27],
|
|
3535
|
+
RA1: [1729.13, 2437.8],
|
|
3536
|
+
RA2: [1218.9, 1729.13],
|
|
3537
|
+
RA3: [864.57, 1218.9],
|
|
3538
|
+
RA4: [609.45, 864.57],
|
|
3539
|
+
SRA0: [2551.18, 3628.35],
|
|
3540
|
+
SRA1: [1814.17, 2551.18],
|
|
3541
|
+
SRA2: [1275.59, 1814.17],
|
|
3542
|
+
SRA3: [907.09, 1275.59],
|
|
3543
|
+
SRA4: [637.8, 907.09]
|
|
3544
|
+
};
|
|
3156
3545
|
/**
|
|
3157
3546
|
* A single page in a PDF document.
|
|
3158
3547
|
*
|
|
@@ -3180,10 +3569,25 @@ var PdfPage = class PdfPage {
|
|
|
3180
3569
|
*/
|
|
3181
3570
|
extGStates = /* @__PURE__ */ new Map();
|
|
3182
3571
|
/**
|
|
3572
|
+
* Pattern resources referenced by this page.
|
|
3573
|
+
* Maps a resource name (e.g. `Pat5`) to its indirect reference.
|
|
3574
|
+
* Used for gradient fills and tiling patterns.
|
|
3575
|
+
*/
|
|
3576
|
+
patterns = /* @__PURE__ */ new Map();
|
|
3577
|
+
/**
|
|
3183
3578
|
* Counter for ExtGState resource names (`GS1`, `GS2`, ...).
|
|
3184
3579
|
*/
|
|
3185
3580
|
extGStateCounter = 0;
|
|
3186
3581
|
/**
|
|
3582
|
+
* Counter for transparency group XObject resource names (`TG1`, `TG2`, ...).
|
|
3583
|
+
*/
|
|
3584
|
+
transparencyGroupCounter = 0;
|
|
3585
|
+
/**
|
|
3586
|
+
* Stack of transparency group state. Each entry records the ops length
|
|
3587
|
+
* at the time `beginTransparencyGroup()` was called, plus the options.
|
|
3588
|
+
*/
|
|
3589
|
+
transparencyGroupStack = [];
|
|
3590
|
+
/**
|
|
3187
3591
|
* Cache mapping composite keys (opacity + blend mode) to their ExtGState
|
|
3188
3592
|
* resource names, so the same combination reuses the same graphics state
|
|
3189
3593
|
* dictionary.
|
|
@@ -3323,6 +3727,10 @@ var PdfPage = class PdfPage {
|
|
|
3323
3727
|
registerExtGState(name, ref) {
|
|
3324
3728
|
this.extGStates.set(name, ref);
|
|
3325
3729
|
}
|
|
3730
|
+
/** @internal Register a Pattern resource on this page. */
|
|
3731
|
+
registerPattern(name, ref) {
|
|
3732
|
+
this.patterns.set(name, ref);
|
|
3733
|
+
}
|
|
3326
3734
|
/**
|
|
3327
3735
|
* Set the default font used by {@link drawText} when the `font` option
|
|
3328
3736
|
* is not provided.
|
|
@@ -4224,6 +4632,51 @@ var PdfPage = class PdfPage {
|
|
|
4224
4632
|
this.ops += restoreState();
|
|
4225
4633
|
}
|
|
4226
4634
|
/**
|
|
4635
|
+
* Draw a gradient fill (linear or radial) clipped to a rectangle.
|
|
4636
|
+
*
|
|
4637
|
+
* The gradient is registered as a `/Pattern` resource on this page
|
|
4638
|
+
* and painted within the specified rectangular region.
|
|
4639
|
+
*
|
|
4640
|
+
* @param gradient A gradient descriptor from {@link linearGradient}
|
|
4641
|
+
* or {@link radialGradient}.
|
|
4642
|
+
* @param rect The rectangle to fill.
|
|
4643
|
+
*/
|
|
4644
|
+
drawGradient(gradient, rect) {
|
|
4645
|
+
const { patternRef, patternName } = buildGradientObjects(gradient, this.registry);
|
|
4646
|
+
this.patterns.set(patternName, patternRef);
|
|
4647
|
+
this.ops += saveState();
|
|
4648
|
+
this.ops += rectangle(rect.x, rect.y, rect.width, rect.height);
|
|
4649
|
+
this.ops += clip();
|
|
4650
|
+
this.ops += endPath();
|
|
4651
|
+
this.ops += setColorSpace("Pattern");
|
|
4652
|
+
this.ops += `/${patternName} scn\n`;
|
|
4653
|
+
this.ops += rectangle(rect.x, rect.y, rect.width, rect.height);
|
|
4654
|
+
this.ops += fill();
|
|
4655
|
+
this.ops += restoreState();
|
|
4656
|
+
}
|
|
4657
|
+
/**
|
|
4658
|
+
* Draw a tiling pattern fill clipped to a rectangle.
|
|
4659
|
+
*
|
|
4660
|
+
* The pattern is registered as a `/Pattern` resource on this page
|
|
4661
|
+
* and painted within the specified rectangular region.
|
|
4662
|
+
*
|
|
4663
|
+
* @param pattern A pattern descriptor from {@link tilingPattern}.
|
|
4664
|
+
* @param rect The rectangle to fill.
|
|
4665
|
+
*/
|
|
4666
|
+
drawPattern(pattern, rect) {
|
|
4667
|
+
const { patternRef, patternName } = buildPatternObjects(pattern, this.registry);
|
|
4668
|
+
this.patterns.set(patternName, patternRef);
|
|
4669
|
+
this.ops += saveState();
|
|
4670
|
+
this.ops += rectangle(rect.x, rect.y, rect.width, rect.height);
|
|
4671
|
+
this.ops += clip();
|
|
4672
|
+
this.ops += endPath();
|
|
4673
|
+
this.ops += setColorSpace("Pattern");
|
|
4674
|
+
this.ops += `/${patternName} scn\n`;
|
|
4675
|
+
this.ops += rectangle(rect.x, rect.y, rect.width, rect.height);
|
|
4676
|
+
this.ops += fill();
|
|
4677
|
+
this.ops += restoreState();
|
|
4678
|
+
}
|
|
4679
|
+
/**
|
|
4227
4680
|
* Begin layer-specific content.
|
|
4228
4681
|
*
|
|
4229
4682
|
* Content drawn after this call and before {@link endLayer} will be
|
|
@@ -4244,6 +4697,120 @@ var PdfPage = class PdfPage {
|
|
|
4244
4697
|
this.ops += endLayerContent();
|
|
4245
4698
|
}
|
|
4246
4699
|
/**
|
|
4700
|
+
* Begin a transparency group. All drawing operations until
|
|
4701
|
+
* {@link endTransparencyGroup} will be captured and composited as a
|
|
4702
|
+
* single Form XObject with a `/Group` transparency dictionary.
|
|
4703
|
+
*
|
|
4704
|
+
* Transparency groups enable isolated and knockout compositing effects
|
|
4705
|
+
* that are not possible with simple opacity settings.
|
|
4706
|
+
*
|
|
4707
|
+
* Groups can be nested — each call must be paired with a matching
|
|
4708
|
+
* {@link endTransparencyGroup}.
|
|
4709
|
+
*
|
|
4710
|
+
* @param options Isolation, knockout, and color-space settings.
|
|
4711
|
+
*
|
|
4712
|
+
* @example
|
|
4713
|
+
* ```ts
|
|
4714
|
+
* page.beginTransparencyGroup({ isolated: true });
|
|
4715
|
+
* page.drawRectangle({ x: 50, y: 50, width: 100, height: 100, opacity: 0.5 });
|
|
4716
|
+
* page.drawCircle({ x: 100, y: 100, size: 60, opacity: 0.5 });
|
|
4717
|
+
* page.endTransparencyGroup();
|
|
4718
|
+
* ```
|
|
4719
|
+
*/
|
|
4720
|
+
beginTransparencyGroup(options) {
|
|
4721
|
+
this.transparencyGroupStack.push({
|
|
4722
|
+
opsStart: this.ops.length,
|
|
4723
|
+
options: options ?? {}
|
|
4724
|
+
});
|
|
4725
|
+
}
|
|
4726
|
+
/**
|
|
4727
|
+
* End the current transparency group and composite it onto the page
|
|
4728
|
+
* as a Form XObject.
|
|
4729
|
+
*
|
|
4730
|
+
* @throws {Error} If there is no matching {@link beginTransparencyGroup}.
|
|
4731
|
+
*/
|
|
4732
|
+
endTransparencyGroup() {
|
|
4733
|
+
const group = this.transparencyGroupStack.pop();
|
|
4734
|
+
if (!group) throw new Error("No transparency group to end — call beginTransparencyGroup() first");
|
|
4735
|
+
const groupOps = this.ops.slice(group.opsStart);
|
|
4736
|
+
this.ops = this.ops.slice(0, group.opsStart);
|
|
4737
|
+
const colorSpace = group.options.colorSpace ?? "DeviceRGB";
|
|
4738
|
+
const groupDict = new require_pdfCatalog.PdfDict();
|
|
4739
|
+
groupDict.set("/S", require_pdfCatalog.PdfName.of("Transparency"));
|
|
4740
|
+
groupDict.set("/I", require_pdfCatalog.PdfBool.of(group.options.isolated ?? true));
|
|
4741
|
+
groupDict.set("/K", require_pdfCatalog.PdfBool.of(group.options.knockout ?? false));
|
|
4742
|
+
groupDict.set("/CS", require_pdfCatalog.PdfName.of(colorSpace));
|
|
4743
|
+
const bbox = require_pdfCatalog.PdfArray.fromNumbers([
|
|
4744
|
+
this.mediaX,
|
|
4745
|
+
this.mediaY,
|
|
4746
|
+
this.mediaX + this.mediaWidth,
|
|
4747
|
+
this.mediaY + this.mediaHeight
|
|
4748
|
+
]);
|
|
4749
|
+
const formDict = new require_pdfCatalog.PdfDict();
|
|
4750
|
+
formDict.set("/Type", require_pdfCatalog.PdfName.of("XObject"));
|
|
4751
|
+
formDict.set("/Subtype", require_pdfCatalog.PdfName.of("Form"));
|
|
4752
|
+
formDict.set("/BBox", bbox);
|
|
4753
|
+
formDict.set("/Group", groupDict);
|
|
4754
|
+
const formStream = require_pdfCatalog.PdfStream.fromString(groupOps, formDict);
|
|
4755
|
+
const formRef = this.registry.register(formStream);
|
|
4756
|
+
this.transparencyGroupCounter++;
|
|
4757
|
+
const name = `TG${this.transparencyGroupCounter}`;
|
|
4758
|
+
this.registerXObject(name, formRef);
|
|
4759
|
+
this.ops += saveState();
|
|
4760
|
+
this.ops += drawXObject(name);
|
|
4761
|
+
this.ops += restoreState();
|
|
4762
|
+
}
|
|
4763
|
+
/**
|
|
4764
|
+
* Apply a soft mask (luminosity-based) for subsequent drawing operations.
|
|
4765
|
+
*
|
|
4766
|
+
* White regions in the mask are fully opaque; black regions are fully
|
|
4767
|
+
* transparent. The mask stays active until {@link clearSoftMask} is
|
|
4768
|
+
* called or the graphics state is restored.
|
|
4769
|
+
*
|
|
4770
|
+
* @param mask A soft mask reference created by
|
|
4771
|
+
* {@link PdfDocument.createSoftMask}.
|
|
4772
|
+
*
|
|
4773
|
+
* @example
|
|
4774
|
+
* ```ts
|
|
4775
|
+
* const mask = doc.createSoftMask(200, 200, (b) => {
|
|
4776
|
+
* b.drawRectangle(0, 0, 200, 200, 1); // white = opaque
|
|
4777
|
+
* b.drawCircle(100, 100, 80, 0); // black = transparent
|
|
4778
|
+
* });
|
|
4779
|
+
* page.applySoftMask(mask);
|
|
4780
|
+
* page.drawImage(image, { x: 50, y: 50, width: 200, height: 200 });
|
|
4781
|
+
* page.clearSoftMask();
|
|
4782
|
+
* ```
|
|
4783
|
+
*/
|
|
4784
|
+
applySoftMask(mask) {
|
|
4785
|
+
const smaskDict = new require_pdfCatalog.PdfDict();
|
|
4786
|
+
smaskDict.set("/S", require_pdfCatalog.PdfName.of("Luminosity"));
|
|
4787
|
+
smaskDict.set("/G", mask.ref);
|
|
4788
|
+
const gsDict = new require_pdfCatalog.PdfDict();
|
|
4789
|
+
gsDict.set("/Type", require_pdfCatalog.PdfName.of("ExtGState"));
|
|
4790
|
+
gsDict.set("/SMask", smaskDict);
|
|
4791
|
+
const gsRef = this.registry.register(gsDict);
|
|
4792
|
+
this.extGStateCounter++;
|
|
4793
|
+
const gsName = `GS${this.extGStateCounter}`;
|
|
4794
|
+
this.extGStates.set(gsName, gsRef);
|
|
4795
|
+
this.ops += setGraphicsState(gsName);
|
|
4796
|
+
}
|
|
4797
|
+
/**
|
|
4798
|
+
* Clear the current soft mask, resetting to no masking.
|
|
4799
|
+
*
|
|
4800
|
+
* This emits an ExtGState with `/SMask /None`, which removes any
|
|
4801
|
+
* previously applied soft mask for subsequent drawing operations.
|
|
4802
|
+
*/
|
|
4803
|
+
clearSoftMask() {
|
|
4804
|
+
const gsDict = new require_pdfCatalog.PdfDict();
|
|
4805
|
+
gsDict.set("/Type", require_pdfCatalog.PdfName.of("ExtGState"));
|
|
4806
|
+
gsDict.set("/SMask", require_pdfCatalog.PdfName.of("None"));
|
|
4807
|
+
const gsRef = this.registry.register(gsDict);
|
|
4808
|
+
this.extGStateCounter++;
|
|
4809
|
+
const gsName = `GS${this.extGStateCounter}`;
|
|
4810
|
+
this.extGStates.set(gsName, gsRef);
|
|
4811
|
+
this.ops += setGraphicsState(gsName);
|
|
4812
|
+
}
|
|
4813
|
+
/**
|
|
4247
4814
|
* Mark a rectangular region on this page for redaction.
|
|
4248
4815
|
*
|
|
4249
4816
|
* The mark is stored but not applied until `doc.applyRedactions()`
|
|
@@ -4296,6 +4863,11 @@ var PdfPage = class PdfPage {
|
|
|
4296
4863
|
for (const [name, ref] of this.extGStates) gsDict.set(name, ref);
|
|
4297
4864
|
resources.set("/ExtGState", gsDict);
|
|
4298
4865
|
}
|
|
4866
|
+
if (this.patterns.size > 0) {
|
|
4867
|
+
const patDict = new require_pdfCatalog.PdfDict();
|
|
4868
|
+
for (const [name, ref] of this.patterns) patDict.set(name, ref);
|
|
4869
|
+
resources.set("/Pattern", patDict);
|
|
4870
|
+
}
|
|
4299
4871
|
resources.set("/ProcSet", require_pdfCatalog.PdfArray.of([
|
|
4300
4872
|
require_pdfCatalog.PdfName.of("PDF"),
|
|
4301
4873
|
require_pdfCatalog.PdfName.of("Text"),
|
|
@@ -4341,6 +4913,15 @@ var PdfPage = class PdfPage {
|
|
|
4341
4913
|
const gsDict = gsObj;
|
|
4342
4914
|
for (const [name, ref] of this.extGStates) gsDict.set(name, ref);
|
|
4343
4915
|
}
|
|
4916
|
+
if (this.patterns.size > 0) {
|
|
4917
|
+
let patObj = resources.get("/Pattern");
|
|
4918
|
+
if (patObj === void 0 || patObj.kind !== "dict") {
|
|
4919
|
+
patObj = new require_pdfCatalog.PdfDict();
|
|
4920
|
+
resources.set("/Pattern", patObj);
|
|
4921
|
+
}
|
|
4922
|
+
const patDict = patObj;
|
|
4923
|
+
for (const [name, ref] of this.patterns) patDict.set(name, ref);
|
|
4924
|
+
}
|
|
4344
4925
|
return resources;
|
|
4345
4926
|
}
|
|
4346
4927
|
/**
|
|
@@ -4385,159 +4966,6 @@ var PdfPage = class PdfPage {
|
|
|
4385
4966
|
};
|
|
4386
4967
|
}
|
|
4387
4968
|
};
|
|
4388
|
-
/** Format a number for PDF output. */
|
|
4389
|
-
function fmtN(value) {
|
|
4390
|
-
if (Number.isInteger(value)) return value.toString();
|
|
4391
|
-
const s = value.toFixed(6).replace(/\.?0+$/, "");
|
|
4392
|
-
return s === "-0" ? "0" : s;
|
|
4393
|
-
}
|
|
4394
|
-
/** Magic constant for circular arc approximation: 4*(sqrt(2)-1)/3. */
|
|
4395
|
-
const KAPPA = .5522847498;
|
|
4396
|
-
/**
|
|
4397
|
-
* Approximate an SVG arc command as cubic Bezier curve(s) (PDF operators).
|
|
4398
|
-
*
|
|
4399
|
-
* SVG arcs use endpoint parameterization; PDF has no native arc command.
|
|
4400
|
-
*/
|
|
4401
|
-
function svgArcToPdfOps(fromX, fromY, rx0, ry0, rotationDeg, largeArcFlag, sweepFlag, toX, toY) {
|
|
4402
|
-
let rx = Math.abs(rx0);
|
|
4403
|
-
let ry = Math.abs(ry0);
|
|
4404
|
-
if (rx === 0 || ry === 0) return `${fmtN(toX)} ${fmtN(toY)} l\n`;
|
|
4405
|
-
const phi = rotationDeg * Math.PI / 180;
|
|
4406
|
-
const cosPhi = Math.cos(phi);
|
|
4407
|
-
const sinPhi = Math.sin(phi);
|
|
4408
|
-
const dx2 = (fromX - toX) / 2;
|
|
4409
|
-
const dy2 = (fromY - toY) / 2;
|
|
4410
|
-
const x1p = cosPhi * dx2 + sinPhi * dy2;
|
|
4411
|
-
const y1p = -sinPhi * dx2 + cosPhi * dy2;
|
|
4412
|
-
let rxSq = rx * rx;
|
|
4413
|
-
let rySq = ry * ry;
|
|
4414
|
-
const x1pSq = x1p * x1p;
|
|
4415
|
-
const y1pSq = y1p * y1p;
|
|
4416
|
-
const lambda = x1pSq / rxSq + y1pSq / rySq;
|
|
4417
|
-
if (lambda > 1) {
|
|
4418
|
-
const s = Math.sqrt(lambda);
|
|
4419
|
-
rx *= s;
|
|
4420
|
-
ry *= s;
|
|
4421
|
-
rxSq = rx * rx;
|
|
4422
|
-
rySq = ry * ry;
|
|
4423
|
-
}
|
|
4424
|
-
let sq = (rxSq * rySq - rxSq * y1pSq - rySq * x1pSq) / (rxSq * y1pSq + rySq * x1pSq);
|
|
4425
|
-
if (sq < 0) sq = 0;
|
|
4426
|
-
sq = Math.sqrt(sq);
|
|
4427
|
-
if (largeArcFlag === sweepFlag) sq = -sq;
|
|
4428
|
-
const cxp = sq * rx * y1p / ry;
|
|
4429
|
-
const cyp = -sq * ry * x1p / rx;
|
|
4430
|
-
const cx = cosPhi * cxp - sinPhi * cyp + (fromX + toX) / 2;
|
|
4431
|
-
const cy = sinPhi * cxp + cosPhi * cyp + (fromY + toY) / 2;
|
|
4432
|
-
function vecAngle(ux, uy, vx, vy) {
|
|
4433
|
-
const sign = ux * vy - uy * vx < 0 ? -1 : 1;
|
|
4434
|
-
let r = (ux * vx + uy * vy) / (Math.sqrt(ux * ux + uy * uy) * Math.sqrt(vx * vx + vy * vy));
|
|
4435
|
-
if (r < -1) r = -1;
|
|
4436
|
-
if (r > 1) r = 1;
|
|
4437
|
-
return sign * Math.acos(r);
|
|
4438
|
-
}
|
|
4439
|
-
const theta1 = vecAngle(1, 0, (x1p - cxp) / rx, (y1p - cyp) / ry);
|
|
4440
|
-
let dTheta = vecAngle((x1p - cxp) / rx, (y1p - cyp) / ry, (-x1p - cxp) / rx, (-y1p - cyp) / ry);
|
|
4441
|
-
if (sweepFlag === 0 && dTheta > 0) dTheta -= 2 * Math.PI;
|
|
4442
|
-
if (sweepFlag === 1 && dTheta < 0) dTheta += 2 * Math.PI;
|
|
4443
|
-
const segs = Math.ceil(Math.abs(dTheta) / (Math.PI / 2));
|
|
4444
|
-
const segAngle = dTheta / segs;
|
|
4445
|
-
let ops = "";
|
|
4446
|
-
let angle = theta1;
|
|
4447
|
-
for (let i = 0; i < segs; i++) {
|
|
4448
|
-
const a1 = angle;
|
|
4449
|
-
const a2 = angle + segAngle;
|
|
4450
|
-
const alpha = 4 / 3 * Math.tan((a2 - a1) / 4);
|
|
4451
|
-
const cos1 = Math.cos(a1), sin1 = Math.sin(a1);
|
|
4452
|
-
const cos2 = Math.cos(a2), sin2 = Math.sin(a2);
|
|
4453
|
-
const ep1x = cosPhi * rx * cos1 - sinPhi * ry * sin1 + cx;
|
|
4454
|
-
const ep1y = sinPhi * rx * cos1 + cosPhi * ry * sin1 + cy;
|
|
4455
|
-
const cp1x = ep1x + alpha * (-cosPhi * rx * sin1 - sinPhi * ry * cos1);
|
|
4456
|
-
const cp1y = ep1y + alpha * (-sinPhi * rx * sin1 + cosPhi * ry * cos1);
|
|
4457
|
-
const ep2x = cosPhi * rx * cos2 - sinPhi * ry * sin2 + cx;
|
|
4458
|
-
const ep2y = sinPhi * rx * cos2 + cosPhi * ry * sin2 + cy;
|
|
4459
|
-
const cp2x = ep2x - alpha * (-cosPhi * rx * sin2 - sinPhi * ry * cos2);
|
|
4460
|
-
const cp2y = ep2y - alpha * (-sinPhi * rx * sin2 + cosPhi * ry * cos2);
|
|
4461
|
-
ops += `${fmtN(cp1x)} ${fmtN(cp1y)} ${fmtN(cp2x)} ${fmtN(cp2y)} ${fmtN(ep2x)} ${fmtN(ep2y)} c\n`;
|
|
4462
|
-
angle = a2;
|
|
4463
|
-
}
|
|
4464
|
-
return ops;
|
|
4465
|
-
}
|
|
4466
|
-
/**
|
|
4467
|
-
* Convert parsed SVG draw commands into PDF path construction operators.
|
|
4468
|
-
*
|
|
4469
|
-
* Does **not** emit painting operators (fill / stroke) -- the caller
|
|
4470
|
-
* is responsible for that.
|
|
4471
|
-
*/
|
|
4472
|
-
function svgCommandsToPdfOps(commands) {
|
|
4473
|
-
let ops = "";
|
|
4474
|
-
let curX = 0;
|
|
4475
|
-
let curY = 0;
|
|
4476
|
-
for (const cmd of commands) switch (cmd.type) {
|
|
4477
|
-
case "moveTo":
|
|
4478
|
-
curX = cmd.params[0];
|
|
4479
|
-
curY = cmd.params[1];
|
|
4480
|
-
ops += `${fmtN(curX)} ${fmtN(curY)} m\n`;
|
|
4481
|
-
break;
|
|
4482
|
-
case "lineTo":
|
|
4483
|
-
curX = cmd.params[0];
|
|
4484
|
-
curY = cmd.params[1];
|
|
4485
|
-
ops += `${fmtN(curX)} ${fmtN(curY)} l\n`;
|
|
4486
|
-
break;
|
|
4487
|
-
case "curveTo":
|
|
4488
|
-
ops += `${fmtN(cmd.params[0])} ${fmtN(cmd.params[1])} ${fmtN(cmd.params[2])} ${fmtN(cmd.params[3])} ${fmtN(cmd.params[4])} ${fmtN(cmd.params[5])} c\n`;
|
|
4489
|
-
curX = cmd.params[4];
|
|
4490
|
-
curY = cmd.params[5];
|
|
4491
|
-
break;
|
|
4492
|
-
case "quadCurveTo": {
|
|
4493
|
-
const cpx = cmd.params[0];
|
|
4494
|
-
const cpy = cmd.params[1];
|
|
4495
|
-
const toX = cmd.params[2];
|
|
4496
|
-
const toY = cmd.params[3];
|
|
4497
|
-
const cp1x = curX + 2 / 3 * (cpx - curX);
|
|
4498
|
-
const cp1y = curY + 2 / 3 * (cpy - curY);
|
|
4499
|
-
const cp2x = toX + 2 / 3 * (cpx - toX);
|
|
4500
|
-
const cp2y = toY + 2 / 3 * (cpy - toY);
|
|
4501
|
-
ops += `${fmtN(cp1x)} ${fmtN(cp1y)} ${fmtN(cp2x)} ${fmtN(cp2y)} ${fmtN(toX)} ${fmtN(toY)} c\n`;
|
|
4502
|
-
curX = toX;
|
|
4503
|
-
curY = toY;
|
|
4504
|
-
break;
|
|
4505
|
-
}
|
|
4506
|
-
case "closePath":
|
|
4507
|
-
ops += "h\n";
|
|
4508
|
-
break;
|
|
4509
|
-
case "rect":
|
|
4510
|
-
ops += `${fmtN(cmd.params[0])} ${fmtN(cmd.params[1])} ${fmtN(cmd.params[2])} ${fmtN(cmd.params[3])} re\n`;
|
|
4511
|
-
break;
|
|
4512
|
-
case "circle": {
|
|
4513
|
-
const ccx = cmd.params[0], ccy = cmd.params[1], r = cmd.params[2];
|
|
4514
|
-
const ox = r * KAPPA, oy = r * KAPPA;
|
|
4515
|
-
ops += `${fmtN(ccx)} ${fmtN(ccy + r)} m\n`;
|
|
4516
|
-
ops += `${fmtN(ccx + ox)} ${fmtN(ccy + r)} ${fmtN(ccx + r)} ${fmtN(ccy + oy)} ${fmtN(ccx + r)} ${fmtN(ccy)} c\n`;
|
|
4517
|
-
ops += `${fmtN(ccx + r)} ${fmtN(ccy - oy)} ${fmtN(ccx + ox)} ${fmtN(ccy - r)} ${fmtN(ccx)} ${fmtN(ccy - r)} c\n`;
|
|
4518
|
-
ops += `${fmtN(ccx - ox)} ${fmtN(ccy - r)} ${fmtN(ccx - r)} ${fmtN(ccy - oy)} ${fmtN(ccx - r)} ${fmtN(ccy)} c\n`;
|
|
4519
|
-
ops += `${fmtN(ccx - r)} ${fmtN(ccy + oy)} ${fmtN(ccx - ox)} ${fmtN(ccy + r)} ${fmtN(ccx)} ${fmtN(ccy + r)} c\n`;
|
|
4520
|
-
break;
|
|
4521
|
-
}
|
|
4522
|
-
case "ellipse": {
|
|
4523
|
-
const ecx = cmd.params[0], ecy = cmd.params[1];
|
|
4524
|
-
const erx = cmd.params[2], ery = cmd.params[3];
|
|
4525
|
-
const eox = erx * KAPPA, eoy = ery * KAPPA;
|
|
4526
|
-
ops += `${fmtN(ecx)} ${fmtN(ecy + ery)} m\n`;
|
|
4527
|
-
ops += `${fmtN(ecx + eox)} ${fmtN(ecy + ery)} ${fmtN(ecx + erx)} ${fmtN(ecy + eoy)} ${fmtN(ecx + erx)} ${fmtN(ecy)} c\n`;
|
|
4528
|
-
ops += `${fmtN(ecx + erx)} ${fmtN(ecy - eoy)} ${fmtN(ecx + eox)} ${fmtN(ecy - ery)} ${fmtN(ecx)} ${fmtN(ecy - ery)} c\n`;
|
|
4529
|
-
ops += `${fmtN(ecx - eox)} ${fmtN(ecy - ery)} ${fmtN(ecx - erx)} ${fmtN(ecy - eoy)} ${fmtN(ecx - erx)} ${fmtN(ecy)} c\n`;
|
|
4530
|
-
ops += `${fmtN(ecx - erx)} ${fmtN(ecy + eoy)} ${fmtN(ecx - eox)} ${fmtN(ecy + ery)} ${fmtN(ecx)} ${fmtN(ecy + ery)} c\n`;
|
|
4531
|
-
break;
|
|
4532
|
-
}
|
|
4533
|
-
case "arc":
|
|
4534
|
-
ops += svgArcToPdfOps(curX, curY, cmd.params[0], cmd.params[1], cmd.params[2], cmd.params[3], cmd.params[4], cmd.params[5], cmd.params[6]);
|
|
4535
|
-
curX = cmd.params[5];
|
|
4536
|
-
curY = cmd.params[6];
|
|
4537
|
-
break;
|
|
4538
|
-
}
|
|
4539
|
-
return ops;
|
|
4540
|
-
}
|
|
4541
4969
|
|
|
4542
4970
|
//#endregion
|
|
4543
4971
|
Object.defineProperty(exports, 'AnnotationFlags', {
|
|
@@ -4648,6 +5076,18 @@ Object.defineProperty(exports, 'buildAnnotationDict', {
|
|
|
4648
5076
|
return buildAnnotationDict;
|
|
4649
5077
|
}
|
|
4650
5078
|
});
|
|
5079
|
+
Object.defineProperty(exports, 'buildGradientObjects', {
|
|
5080
|
+
enumerable: true,
|
|
5081
|
+
get: function () {
|
|
5082
|
+
return buildGradientObjects;
|
|
5083
|
+
}
|
|
5084
|
+
});
|
|
5085
|
+
Object.defineProperty(exports, 'buildPatternObjects', {
|
|
5086
|
+
enumerable: true,
|
|
5087
|
+
get: function () {
|
|
5088
|
+
return buildPatternObjects;
|
|
5089
|
+
}
|
|
5090
|
+
});
|
|
4651
5091
|
Object.defineProperty(exports, 'circlePath', {
|
|
4652
5092
|
enumerable: true,
|
|
4653
5093
|
get: function () {
|
|
@@ -4858,6 +5298,12 @@ Object.defineProperty(exports, 'lineTo', {
|
|
|
4858
5298
|
return lineTo;
|
|
4859
5299
|
}
|
|
4860
5300
|
});
|
|
5301
|
+
Object.defineProperty(exports, 'linearGradient', {
|
|
5302
|
+
enumerable: true,
|
|
5303
|
+
get: function () {
|
|
5304
|
+
return linearGradient;
|
|
5305
|
+
}
|
|
5306
|
+
});
|
|
4861
5307
|
Object.defineProperty(exports, 'markForRedaction', {
|
|
4862
5308
|
enumerable: true,
|
|
4863
5309
|
get: function () {
|
|
@@ -4918,6 +5364,12 @@ Object.defineProperty(exports, 'pdfPage_exports', {
|
|
|
4918
5364
|
return pdfPage_exports;
|
|
4919
5365
|
}
|
|
4920
5366
|
});
|
|
5367
|
+
Object.defineProperty(exports, 'radialGradient', {
|
|
5368
|
+
enumerable: true,
|
|
5369
|
+
get: function () {
|
|
5370
|
+
return radialGradient;
|
|
5371
|
+
}
|
|
5372
|
+
});
|
|
4921
5373
|
Object.defineProperty(exports, 'radians', {
|
|
4922
5374
|
enumerable: true,
|
|
4923
5375
|
get: function () {
|
|
@@ -5182,6 +5634,12 @@ Object.defineProperty(exports, 'svgToPdfOperators', {
|
|
|
5182
5634
|
return svgToPdfOperators;
|
|
5183
5635
|
}
|
|
5184
5636
|
});
|
|
5637
|
+
Object.defineProperty(exports, 'tilingPattern', {
|
|
5638
|
+
enumerable: true,
|
|
5639
|
+
get: function () {
|
|
5640
|
+
return tilingPattern;
|
|
5641
|
+
}
|
|
5642
|
+
});
|
|
5185
5643
|
Object.defineProperty(exports, 'translate', {
|
|
5186
5644
|
enumerable: true,
|
|
5187
5645
|
get: function () {
|
|
@@ -5200,4 +5658,4 @@ Object.defineProperty(exports, 'wrapText', {
|
|
|
5200
5658
|
return wrapText;
|
|
5201
5659
|
}
|
|
5202
5660
|
});
|
|
5203
|
-
//# sourceMappingURL=pdfPage-
|
|
5661
|
+
//# sourceMappingURL=pdfPage-BebMv6fN.cjs.map
|