@poe-platform/safe-bash 0.1.761 → 0.1.763
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/image-ast/index.browser.js +255 -62
- package/dist/image-ast/index.js +255 -62
- package/dist/pdf-ast/ast.d.ts +23 -0
- package/dist/pdf-ast/index.js +344 -98
- package/dist/safe-bash/command-chunks/{chunk-6VX5ZQL5.js → chunk-4XHONGIU.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-OSMLVM7P.js → chunk-S3G2B4OX.js} +258 -62
- package/dist/safe-bash/command-chunks/{chunk-GR725WRX.js → chunk-S5EX6UP5.js} +1 -1
- package/dist/safe-bash/commands/csvcut/index.d.ts +1 -1
- package/dist/safe-bash/commands/csvcut/index.js +3 -1
- package/dist/safe-bash/commands/csvgrep/index.d.ts +1 -1
- package/dist/safe-bash/commands/csvgrep/index.js +3 -1
- package/dist/safe-bash/core.browser.js +8 -6
- package/dist/safe-bash/shell/runtime.js +5 -5
- package/dist/safe-bash-checksum-engine/index.d.ts +1 -1
- package/dist/safe-bash-checksum-engine/index.js +5 -1
- package/dist/safe-bash-command-ffmpeg/index.js +7942 -7853
- package/dist/safe-bash-command-gh/index.js +174 -105
- package/dist/safe-bash-command-imagemagick/index.js +2 -2
- package/dist/safe-bash-command-pandoc/command.js +3 -3
- package/dist/safe-bash-command-pandoc/index.js +3 -3
- package/dist/safe-bash-command-pdfimages/index.js +255 -62
- package/dist/safe-bash-command-pdfinfo/index.js +342 -98
- package/dist/safe-bash-command-pdftk/index.js +255 -62
- package/dist/safe-bash-command-pdftoppm/index.js +342 -98
- package/dist/safe-bash-command-pdftotext/index.js +255 -62
- package/dist/safe-bash-command-qpdf/index.js +255 -62
- package/dist/safe-bash-command-sips/index.js +2 -2
- package/dist/safe-bash-command-soffice/index.js +1 -1
- package/dist/safe-bash-command-ssconvert/index.js +318 -65
- package/dist/safe-bash-command-wkhtmltopdf/index.js +255 -62
- package/package.json +2 -2
- package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +23 -0
package/dist/pdf-ast/index.js
CHANGED
|
@@ -36281,14 +36281,18 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36281
36281
|
const paths = [];
|
|
36282
36282
|
const images = [];
|
|
36283
36283
|
const operations = [];
|
|
36284
|
+
let capturedOperations;
|
|
36285
|
+
let insideSoftMask = false;
|
|
36284
36286
|
const emit = (operation) => {
|
|
36285
|
-
const { clipPaths, clipImages } = curState();
|
|
36286
|
-
if (clipPaths || clipImages) operation = { ...operation, value: {
|
|
36287
|
+
const { clipPaths, clipImages, softMask } = curState();
|
|
36288
|
+
if (clipPaths || clipImages || softMask) operation = { ...operation, value: {
|
|
36287
36289
|
...operation.value,
|
|
36288
36290
|
...clipPaths ? { clipPaths } : {},
|
|
36289
|
-
...clipImages ? { clipImages } : {}
|
|
36291
|
+
...clipImages ? { clipImages } : {},
|
|
36292
|
+
...softMask ? { softMask } : {}
|
|
36290
36293
|
} };
|
|
36291
|
-
operations.push(operation);
|
|
36294
|
+
(capturedOperations ?? operations).push(operation);
|
|
36295
|
+
if (insideSoftMask) return;
|
|
36292
36296
|
switch (operation.kind) {
|
|
36293
36297
|
case "path":
|
|
36294
36298
|
paths.push(operation.value);
|
|
@@ -36394,7 +36398,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36394
36398
|
);
|
|
36395
36399
|
return { r: kClamp(r), g: kClamp(g), b: kClamp(b) };
|
|
36396
36400
|
};
|
|
36397
|
-
const applyStateOperator = (st, operator, ops, activeResources) => {
|
|
36401
|
+
const applyStateOperator = (st, operator, ops, activeResources, activeFonts, depth) => {
|
|
36398
36402
|
const num = (i, fb = 0) => ops[i]?.kind === "number" ? ops[i].value : fb;
|
|
36399
36403
|
if (operator === "cm") {
|
|
36400
36404
|
const m = [num(0, 1), num(1, 0), num(2, 0), num(3, 1), num(4, 0), num(5, 0)];
|
|
@@ -36477,6 +36481,46 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36477
36481
|
const extDict = params.cosDoc.resolveDict(dictGet(activeResources, "ExtGState"));
|
|
36478
36482
|
const gsDict = extDict ? params.cosDoc.resolveDict(dictGet(extDict, ops[0].decoded)) : void 0;
|
|
36479
36483
|
if (gsDict) {
|
|
36484
|
+
const mask = params.cosDoc.resolve(dictGet(gsDict, "SMask"));
|
|
36485
|
+
if (mask?.kind === "name" && mask.decoded === "None") {
|
|
36486
|
+
st.softMask = void 0;
|
|
36487
|
+
} else if (mask?.kind === "dict") {
|
|
36488
|
+
const subtype = params.cosDoc.resolve(dictGet(mask, "S"));
|
|
36489
|
+
const form = params.cosDoc.resolve(dictGet(mask, "G"));
|
|
36490
|
+
if (form?.kind === "stream" && subtype?.kind === "name" && (subtype.decoded === "Alpha" || subtype.decoded === "Luminosity")) {
|
|
36491
|
+
if (depth >= 8) throw new PdfError("E_LIMIT", "Soft-mask nesting exceeds the form depth limit");
|
|
36492
|
+
const parentOperations = capturedOperations;
|
|
36493
|
+
const parentInsideSoftMask = insideSoftMask;
|
|
36494
|
+
const savedTextState = { pendingTextClip, hasTextClip, activeTm, activeTlm };
|
|
36495
|
+
const captured = [];
|
|
36496
|
+
capturedOperations = captured;
|
|
36497
|
+
insideSoftMask = true;
|
|
36498
|
+
const maskState = { ...st, softMask: void 0, fillAlpha: 1, strokeAlpha: 1, blendMode: "Normal" };
|
|
36499
|
+
delete maskState.clipPaths;
|
|
36500
|
+
delete maskState.clipImages;
|
|
36501
|
+
delete maskState.clipRect;
|
|
36502
|
+
stateStack.push(maskState);
|
|
36503
|
+
try {
|
|
36504
|
+
paintForm(form, activeResources, activeFonts, depth, void 0, void 0, true);
|
|
36505
|
+
} finally {
|
|
36506
|
+
stateStack.pop();
|
|
36507
|
+
capturedOperations = parentOperations;
|
|
36508
|
+
insideSoftMask = parentInsideSoftMask;
|
|
36509
|
+
({ pendingTextClip, hasTextClip, activeTm, activeTlm } = savedTextState);
|
|
36510
|
+
}
|
|
36511
|
+
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
36512
|
+
const colorSpace = group ? dictGet(group, "CS") : void 0;
|
|
36513
|
+
const bc = params.cosDoc.resolveArray(dictGet(mask, "BC"));
|
|
36514
|
+
const components = bc?.items.map((item) => {
|
|
36515
|
+
const value = params.cosDoc.resolve(item);
|
|
36516
|
+
return value?.kind === "number" ? value.value : 0;
|
|
36517
|
+
});
|
|
36518
|
+
const [r, g, b] = components ? convertColorSpaceComponentsToRgb(params.cosDoc, colorSpace, "DeviceRGB", components, activeResources) : [0, 0, 0];
|
|
36519
|
+
const transfer = params.cosDoc.resolve(dictGet(mask, "TR"));
|
|
36520
|
+
const transferMap = transfer?.kind === "dict" || transfer?.kind === "stream" ? Uint8Array.from({ length: 256 }, (_, i) => Math.floor(kClamp(Math.fround(evalShadingFunctionToComponents(params.cosDoc, transfer, Math.fround(i / 255))[0] ?? 0)) * 255)) : void 0;
|
|
36521
|
+
st.softMask = { subtype: subtype.decoded, operations: captured, backdrop: { r, g, b }, transferMap };
|
|
36522
|
+
}
|
|
36523
|
+
}
|
|
36480
36524
|
const bmNode = params.cosDoc.resolve(dictGet(gsDict, "BM"));
|
|
36481
36525
|
if (bmNode?.kind === "name") {
|
|
36482
36526
|
st.blendMode = bmNode.decoded === "Compatible" ? "Normal" : bmNode.decoded;
|
|
@@ -36563,6 +36607,84 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36563
36607
|
] }], void 0, void 0, resources, activeFonts, depth);
|
|
36564
36608
|
stateStack.pop();
|
|
36565
36609
|
};
|
|
36610
|
+
const paintForm = (form, activeResources, activeFonts, depth, mcid, actualText, maskGroup = false) => {
|
|
36611
|
+
const st = curState();
|
|
36612
|
+
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
36613
|
+
const groupType = group ? params.cosDoc.resolve(dictGet(group, "S")) : void 0;
|
|
36614
|
+
const isolated = group ? params.cosDoc.resolve(dictGet(group, "I")) : void 0;
|
|
36615
|
+
const isolate = !maskGroup && groupType?.kind === "name" && groupType.decoded === "Transparency" && isolated?.kind === "boolean" && isolated.value;
|
|
36616
|
+
const formStreamBytes = params.cosDoc.decodeStream(form);
|
|
36617
|
+
const formNodes = parseContentStream(formStreamBytes);
|
|
36618
|
+
const formResDict = params.cosDoc.resolveDict(dictGet(form.dict, "Resources")) ?? activeResources;
|
|
36619
|
+
const formFonts = new Map(activeFonts);
|
|
36620
|
+
for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
|
|
36621
|
+
formFonts.set(k, v);
|
|
36622
|
+
}
|
|
36623
|
+
let nextCtm = [...st.ctm];
|
|
36624
|
+
const matArr = params.cosDoc.resolveArray(dictGet(form.dict, "Matrix"));
|
|
36625
|
+
if (matArr && matArr.items.length >= 6) {
|
|
36626
|
+
const mn = (idx, fb = 0) => {
|
|
36627
|
+
const resolved = params.cosDoc.resolve(matArr.items[idx]);
|
|
36628
|
+
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36629
|
+
};
|
|
36630
|
+
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36631
|
+
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36632
|
+
}
|
|
36633
|
+
let nextClip = !isolate && st.clipRect ? [...st.clipRect] : void 0;
|
|
36634
|
+
let nextClipPaths = isolate ? void 0 : st.clipPaths;
|
|
36635
|
+
const bboxArr = params.cosDoc.resolveArray(dictGet(form.dict, "BBox"));
|
|
36636
|
+
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36637
|
+
const bn = (idx, fb = 0) => {
|
|
36638
|
+
const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
|
|
36639
|
+
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36640
|
+
};
|
|
36641
|
+
const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
|
|
36642
|
+
const pts = [
|
|
36643
|
+
transformPoint(nextCtm, bx0, by0),
|
|
36644
|
+
transformPoint(nextCtm, bx1, by0),
|
|
36645
|
+
transformPoint(nextCtm, bx1, by1),
|
|
36646
|
+
transformPoint(nextCtm, bx0, by1)
|
|
36647
|
+
];
|
|
36648
|
+
nextClipPaths = [...nextClipPaths ?? [], [
|
|
36649
|
+
...pts.map(([x, y], index) => ({ kind: index === 0 ? "move" : "line", x, y })),
|
|
36650
|
+
{ kind: "close" }
|
|
36651
|
+
]];
|
|
36652
|
+
const fMinX = Math.min(...pts.map((p) => p[0]));
|
|
36653
|
+
const fMinY = Math.min(...pts.map((p) => p[1]));
|
|
36654
|
+
const fMaxX = Math.max(...pts.map((p) => p[0]));
|
|
36655
|
+
const fMaxY = Math.max(...pts.map((p) => p[1]));
|
|
36656
|
+
if (fMaxX > fMinX && fMaxY > fMinY) {
|
|
36657
|
+
nextClip = nextClip ? [
|
|
36658
|
+
Math.max(nextClip[0], fMinX),
|
|
36659
|
+
Math.max(nextClip[1], fMinY),
|
|
36660
|
+
Math.min(nextClip[2], fMaxX),
|
|
36661
|
+
Math.min(nextClip[3], fMaxY)
|
|
36662
|
+
] : [fMinX, fMinY, fMaxX, fMaxY];
|
|
36663
|
+
}
|
|
36664
|
+
}
|
|
36665
|
+
const parentOperations = capturedOperations;
|
|
36666
|
+
const children = [];
|
|
36667
|
+
const nextState = { ...st, ctm: nextCtm };
|
|
36668
|
+
if (isolate) {
|
|
36669
|
+
capturedOperations = children;
|
|
36670
|
+
nextState.fillAlpha = nextState.strokeAlpha = 1;
|
|
36671
|
+
nextState.blendMode = "Normal";
|
|
36672
|
+
nextState.softMask = void 0;
|
|
36673
|
+
delete nextState.clipImages;
|
|
36674
|
+
delete nextState.clipPaths;
|
|
36675
|
+
delete nextState.clipRect;
|
|
36676
|
+
}
|
|
36677
|
+
if (nextClip) nextState.clipRect = nextClip;
|
|
36678
|
+
if (nextClipPaths) nextState.clipPaths = nextClipPaths;
|
|
36679
|
+
stateStack.push(nextState);
|
|
36680
|
+
try {
|
|
36681
|
+
walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
|
|
36682
|
+
} finally {
|
|
36683
|
+
stateStack.pop();
|
|
36684
|
+
capturedOperations = parentOperations;
|
|
36685
|
+
}
|
|
36686
|
+
if (isolate) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
|
|
36687
|
+
};
|
|
36566
36688
|
const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
|
|
36567
36689
|
for (const node of nodes) {
|
|
36568
36690
|
switch (node.kind) {
|
|
@@ -36607,7 +36729,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36607
36729
|
break;
|
|
36608
36730
|
}
|
|
36609
36731
|
case "state-op": {
|
|
36610
|
-
applyStateOperator(curState(), node.operator, node.operands, activeResources);
|
|
36732
|
+
applyStateOperator(curState(), node.operator, node.operands, activeResources, activeFonts, depth);
|
|
36611
36733
|
break;
|
|
36612
36734
|
}
|
|
36613
36735
|
case "path-op": {
|
|
@@ -36893,53 +37015,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36893
37015
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
36894
37016
|
}, patternMask, activeResources, activeFonts, depth);
|
|
36895
37017
|
} else if (sub === "Form" && depth < 8) {
|
|
36896
|
-
|
|
36897
|
-
const formNodes = parseContentStream(formStreamBytes);
|
|
36898
|
-
const formResDict = params.cosDoc.resolveDict(dictGet(xobjNode.dict, "Resources")) ?? activeResources;
|
|
36899
|
-
const formFonts = new Map(activeFonts);
|
|
36900
|
-
for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
|
|
36901
|
-
formFonts.set(k, v);
|
|
36902
|
-
}
|
|
36903
|
-
let nextCtm = [...st.ctm];
|
|
36904
|
-
const matArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "Matrix"));
|
|
36905
|
-
if (matArr && matArr.items.length >= 6) {
|
|
36906
|
-
const mn = (idx, fb = 0) => {
|
|
36907
|
-
const resolved = params.cosDoc.resolve(matArr.items[idx]);
|
|
36908
|
-
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36909
|
-
};
|
|
36910
|
-
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36911
|
-
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36912
|
-
}
|
|
36913
|
-
let nextClip = st.clipRect ? [...st.clipRect] : void 0;
|
|
36914
|
-
const bboxArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "BBox"));
|
|
36915
|
-
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36916
|
-
const bn = (idx, fb = 0) => {
|
|
36917
|
-
const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
|
|
36918
|
-
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36919
|
-
};
|
|
36920
|
-
const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
|
|
36921
|
-
const pts = [
|
|
36922
|
-
transformPoint(nextCtm, bx0, by0),
|
|
36923
|
-
transformPoint(nextCtm, bx1, by0),
|
|
36924
|
-
transformPoint(nextCtm, bx0, by1),
|
|
36925
|
-
transformPoint(nextCtm, bx1, by1)
|
|
36926
|
-
];
|
|
36927
|
-
const fMinX = Math.min(...pts.map((p) => p[0]));
|
|
36928
|
-
const fMinY = Math.min(...pts.map((p) => p[1]));
|
|
36929
|
-
const fMaxX = Math.max(...pts.map((p) => p[0]));
|
|
36930
|
-
const fMaxY = Math.max(...pts.map((p) => p[1]));
|
|
36931
|
-
if (fMaxX > fMinX && fMaxY > fMinY) {
|
|
36932
|
-
nextClip = nextClip ? [
|
|
36933
|
-
Math.max(nextClip[0], fMinX),
|
|
36934
|
-
Math.max(nextClip[1], fMinY),
|
|
36935
|
-
Math.min(nextClip[2], fMaxX),
|
|
36936
|
-
Math.min(nextClip[3], fMaxY)
|
|
36937
|
-
] : [fMinX, fMinY, fMaxX, fMaxY];
|
|
36938
|
-
}
|
|
36939
|
-
}
|
|
36940
|
-
stateStack.push({ ...st, ctm: nextCtm, ...nextClip ? { clipRect: nextClip } : {} });
|
|
36941
|
-
walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
|
|
36942
|
-
if (stateStack.length > 1) stateStack.pop();
|
|
37018
|
+
paintForm(xobjNode, activeResources, activeFonts, depth, mcid, actualText);
|
|
36943
37019
|
}
|
|
36944
37020
|
}
|
|
36945
37021
|
}
|
|
@@ -37158,7 +37234,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
37158
37234
|
st.textRenderMode = cmd.mode;
|
|
37159
37235
|
break;
|
|
37160
37236
|
case "state-op":
|
|
37161
|
-
applyStateOperator(st, cmd.operator, cmd.operands, activeResources);
|
|
37237
|
+
applyStateOperator(st, cmd.operator, cmd.operands, activeResources, activeFonts, depth);
|
|
37162
37238
|
break;
|
|
37163
37239
|
case "show-text":
|
|
37164
37240
|
emitTokenBytes(cmd.token.bytes);
|
|
@@ -40113,6 +40189,49 @@ function flattenCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
|
|
|
40113
40189
|
return points;
|
|
40114
40190
|
}
|
|
40115
40191
|
|
|
40192
|
+
// src/render/image-sampling.ts
|
|
40193
|
+
function sampleImageLinear(image, x, y, out) {
|
|
40194
|
+
x = Math.max(0, Math.min(image.width - 1, x));
|
|
40195
|
+
y = Math.max(0, Math.min(image.height - 1, y));
|
|
40196
|
+
const x0 = Math.floor(x), y0 = Math.floor(y);
|
|
40197
|
+
const fx = x - x0, fy = y - y0;
|
|
40198
|
+
out.fill(0);
|
|
40199
|
+
for (let j = 0; j < 2; j++) {
|
|
40200
|
+
for (let i = 0; i < 2; i++) {
|
|
40201
|
+
const offset = (Math.min(image.height - 1, y0 + j) * image.width + Math.min(image.width - 1, x0 + i)) * 4;
|
|
40202
|
+
const alpha = image.data[offset + 3] * (i ? fx : 1 - fx) * (j ? fy : 1 - fy);
|
|
40203
|
+
out[0] = out[0] + image.data[offset] * alpha;
|
|
40204
|
+
out[1] = out[1] + image.data[offset + 1] * alpha;
|
|
40205
|
+
out[2] = out[2] + image.data[offset + 2] * alpha;
|
|
40206
|
+
out[3] = out[3] + alpha;
|
|
40207
|
+
}
|
|
40208
|
+
}
|
|
40209
|
+
if (out[3] > 0) {
|
|
40210
|
+
out[0] = out[0] / out[3];
|
|
40211
|
+
out[1] = out[1] / out[3];
|
|
40212
|
+
out[2] = out[2] / out[3];
|
|
40213
|
+
}
|
|
40214
|
+
}
|
|
40215
|
+
function downscaleImage(image, widthScale, heightScale) {
|
|
40216
|
+
const sample = new Float64Array(4);
|
|
40217
|
+
while (widthScale > 2 && image.width > 1 || heightScale > 2 && image.height > 1) {
|
|
40218
|
+
const width = widthScale > 2 ? Math.ceil(image.width / 2) : image.width;
|
|
40219
|
+
const height = heightScale > 2 ? Math.ceil(image.height / 2) : image.height;
|
|
40220
|
+
const data = new Uint8Array(width * height * 4);
|
|
40221
|
+
for (let y = 0; y < height; y++) {
|
|
40222
|
+
for (let x = 0; x < width; x++) {
|
|
40223
|
+
sampleImageLinear(image, (x + 0.5) * image.width / width - 0.5, (y + 0.5) * image.height / height - 0.5, sample);
|
|
40224
|
+
const offset = (y * width + x) * 4;
|
|
40225
|
+
for (let c = 0; c < 4; c++) data[offset + c] = Math.round(sample[c]);
|
|
40226
|
+
}
|
|
40227
|
+
}
|
|
40228
|
+
widthScale /= image.width / width;
|
|
40229
|
+
heightScale /= image.height / height;
|
|
40230
|
+
image = { width, height, data };
|
|
40231
|
+
}
|
|
40232
|
+
return image;
|
|
40233
|
+
}
|
|
40234
|
+
|
|
40116
40235
|
// src/render/raster.ts
|
|
40117
40236
|
function encodePng(bitmap) {
|
|
40118
40237
|
return encodeRgbaToPng(bitmap.width, bitmap.height, bitmap.data);
|
|
@@ -41419,6 +41538,30 @@ function paintOperations(displayList) {
|
|
|
41419
41538
|
...displayList.glyphs.map((value) => ({ kind: "glyph", value }))
|
|
41420
41539
|
];
|
|
41421
41540
|
}
|
|
41541
|
+
function renderSoftMask(mask, displayList, scale) {
|
|
41542
|
+
const bitmap = renderDisplayListToBitmap({
|
|
41543
|
+
...displayList,
|
|
41544
|
+
rotation: 0,
|
|
41545
|
+
glyphs: [],
|
|
41546
|
+
paths: [],
|
|
41547
|
+
images: [],
|
|
41548
|
+
operations: mask.operations
|
|
41549
|
+
}, { scale, transparent: true });
|
|
41550
|
+
const { data } = bitmap;
|
|
41551
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
41552
|
+
let value = data[i + 3];
|
|
41553
|
+
if (mask.subtype === "Luminosity") {
|
|
41554
|
+
const alpha = value / 255;
|
|
41555
|
+
const r = Math.round(data[i] * alpha + mask.backdrop.r * 255 * (1 - alpha));
|
|
41556
|
+
const g = Math.round(data[i + 1] * alpha + mask.backdrop.g * 255 * (1 - alpha));
|
|
41557
|
+
const b = Math.round(data[i + 2] * alpha + mask.backdrop.b * 255 * (1 - alpha));
|
|
41558
|
+
value = Math.round(pdfLum(r, g, b));
|
|
41559
|
+
}
|
|
41560
|
+
data[i] = data[i + 1] = data[i + 2] = 0;
|
|
41561
|
+
data[i + 3] = mask.transferMap?.[value] ?? value;
|
|
41562
|
+
}
|
|
41563
|
+
return bitmap;
|
|
41564
|
+
}
|
|
41422
41565
|
function renderDisplayListToBitmap(displayList, options = {}) {
|
|
41423
41566
|
const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
|
|
41424
41567
|
const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
|
|
@@ -41442,10 +41585,28 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41442
41585
|
const aaTxt = options.antialiasText !== false;
|
|
41443
41586
|
let cachedClips;
|
|
41444
41587
|
let cachedClipMask;
|
|
41588
|
+
let cachedSoftMask;
|
|
41589
|
+
let cachedSoftMaskPixels;
|
|
41445
41590
|
const imageClipMasks = /* @__PURE__ */ new Map();
|
|
41446
41591
|
for (const original of paintOperations(displayList)) {
|
|
41447
41592
|
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
41448
|
-
|
|
41593
|
+
let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
41594
|
+
if (operation.kind === "group") {
|
|
41595
|
+
const group = operation.value;
|
|
41596
|
+
const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations: group.operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, transparent: true });
|
|
41597
|
+
for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
|
|
41598
|
+
operation = { kind: "image", value: {
|
|
41599
|
+
name: "TransparencyGroup",
|
|
41600
|
+
width: bitmap.width,
|
|
41601
|
+
height: bitmap.height,
|
|
41602
|
+
decodedRgba: bitmap.data,
|
|
41603
|
+
matrix: [bitmap.width / scale, 0, 0, bitmap.height / scale, 0, displayList.height - bitmap.height / scale],
|
|
41604
|
+
colorSpace: "DeviceRGB",
|
|
41605
|
+
bitsPerComponent: 8,
|
|
41606
|
+
blendMode: group.blendMode,
|
|
41607
|
+
clipRect: group.clipRect
|
|
41608
|
+
} };
|
|
41609
|
+
}
|
|
41449
41610
|
const clips = original.value.clipPaths;
|
|
41450
41611
|
let clipMask = clips && clips === cachedClips ? cachedClipMask : void 0;
|
|
41451
41612
|
if (clips && !clipMask) {
|
|
@@ -41459,6 +41620,19 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41459
41620
|
cachedClips = clips;
|
|
41460
41621
|
cachedClipMask = clipMask;
|
|
41461
41622
|
}
|
|
41623
|
+
const softMask = original.value.softMask;
|
|
41624
|
+
if (softMask) {
|
|
41625
|
+
if (softMask !== cachedSoftMask) {
|
|
41626
|
+
cachedSoftMaskPixels = renderSoftMask(softMask, displayList, scale).data;
|
|
41627
|
+
cachedSoftMask = softMask;
|
|
41628
|
+
}
|
|
41629
|
+
if (clipMask) {
|
|
41630
|
+
clipMask = clipMask.slice();
|
|
41631
|
+
for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * cachedSoftMaskPixels[i] / 255);
|
|
41632
|
+
} else {
|
|
41633
|
+
clipMask = cachedSoftMaskPixels;
|
|
41634
|
+
}
|
|
41635
|
+
}
|
|
41462
41636
|
const imageClips = original.value.clipImages;
|
|
41463
41637
|
if (imageClips) {
|
|
41464
41638
|
let imageMask = imageClipMasks.get(imageClips);
|
|
@@ -41562,6 +41736,17 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41562
41736
|
const maxPx = Math.min(width - 1, clipMaxPx, Math.ceil(Math.max(...cornersPx)) - 1);
|
|
41563
41737
|
const minPy = Math.max(0, clipMinPy, Math.floor(Math.min(...cornersPy)));
|
|
41564
41738
|
const maxPy = Math.min(height - 1, clipMaxPy, Math.ceil(Math.max(...cornersPy)) - 1);
|
|
41739
|
+
if (minPx > maxPx || minPy > maxPy) continue;
|
|
41740
|
+
const source = downscaleImage(
|
|
41741
|
+
{ width: img.width, height: img.height, data: img.decodedRgba },
|
|
41742
|
+
Math.hypot(d, c) * img.width / Math.abs(det * scale),
|
|
41743
|
+
Math.hypot(b, a) * img.height / Math.abs(det * scale)
|
|
41744
|
+
);
|
|
41745
|
+
const ax = a * scale / img.width, ay = b * scale / img.width;
|
|
41746
|
+
const bx = c * scale / img.height, by = d * scale / img.height;
|
|
41747
|
+
const s1 = ax * ax + ay * ay, s2 = bx * bx + by * by, cross = ax * bx + ay * by;
|
|
41748
|
+
const smooth = Math.fround((s1 + s2 + Math.hypot(s1 - s2, 2 * cross)) / 2) <= 1;
|
|
41749
|
+
const sample = new Float64Array(4);
|
|
41565
41750
|
for (let py = minPy; py <= maxPy; py++) {
|
|
41566
41751
|
const yPdf = displayList.height - (py + 0.5) / scale;
|
|
41567
41752
|
if (img.clipRect && (yPdf < img.clipRect[1] || yPdf > img.clipRect[3])) continue;
|
|
@@ -41573,9 +41758,14 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41573
41758
|
const u = (d * dxPdf - c * dyPdf) / det;
|
|
41574
41759
|
const v = (-b * dxPdf + a * dyPdf) / det;
|
|
41575
41760
|
if (u < 0 || u > 1 || v < 0 || v > 1) continue;
|
|
41576
|
-
|
|
41577
|
-
|
|
41578
|
-
|
|
41761
|
+
if (smooth) {
|
|
41762
|
+
sampleImageLinear(source, u * source.width - 0.5, (1 - v) * source.height - 0.5, sample);
|
|
41763
|
+
} else {
|
|
41764
|
+
const sx = Math.min(source.width - 1, Math.max(0, Math.floor(u * source.width)));
|
|
41765
|
+
const sy = Math.min(source.height - 1, Math.max(0, Math.floor((1 - v) * source.height)));
|
|
41766
|
+
const sIdx = (sy * source.width + sx) * 4;
|
|
41767
|
+
for (let c2 = 0; c2 < 4; c2++) sample[c2] = source.data[sIdx + c2];
|
|
41768
|
+
}
|
|
41579
41769
|
blendPixel(
|
|
41580
41770
|
rgba,
|
|
41581
41771
|
width,
|
|
@@ -41583,11 +41773,11 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41583
41773
|
px,
|
|
41584
41774
|
py,
|
|
41585
41775
|
{
|
|
41586
|
-
r:
|
|
41587
|
-
g:
|
|
41588
|
-
b:
|
|
41776
|
+
r: sample[0] / 255,
|
|
41777
|
+
g: sample[1] / 255,
|
|
41778
|
+
b: sample[2] / 255
|
|
41589
41779
|
},
|
|
41590
|
-
|
|
41780
|
+
sample[3] / 255,
|
|
41591
41781
|
img.blendMode,
|
|
41592
41782
|
clipMask
|
|
41593
41783
|
);
|
|
@@ -41624,6 +41814,27 @@ function renderDisplayListToPng(displayList, options = {}) {
|
|
|
41624
41814
|
const bmp = renderDisplayListToBitmap(displayList, options);
|
|
41625
41815
|
return encodeRgbaToPng(bmp.width, bmp.height, bmp.data);
|
|
41626
41816
|
}
|
|
41817
|
+
function pdfBlendModeToCss(mode) {
|
|
41818
|
+
if (!mode || mode === "Normal" || mode === "Compatible") return void 0;
|
|
41819
|
+
const map = {
|
|
41820
|
+
Multiply: "multiply",
|
|
41821
|
+
Screen: "screen",
|
|
41822
|
+
Overlay: "overlay",
|
|
41823
|
+
Darken: "darken",
|
|
41824
|
+
Lighten: "lighten",
|
|
41825
|
+
ColorDodge: "color-dodge",
|
|
41826
|
+
ColorBurn: "color-burn",
|
|
41827
|
+
HardLight: "hard-light",
|
|
41828
|
+
SoftLight: "soft-light",
|
|
41829
|
+
Difference: "difference",
|
|
41830
|
+
Exclusion: "exclusion",
|
|
41831
|
+
Hue: "hue",
|
|
41832
|
+
Saturation: "saturation",
|
|
41833
|
+
Color: "color",
|
|
41834
|
+
Luminosity: "luminosity"
|
|
41835
|
+
};
|
|
41836
|
+
return map[mode];
|
|
41837
|
+
}
|
|
41627
41838
|
function escapeXmlText(str) {
|
|
41628
41839
|
let valid = "";
|
|
41629
41840
|
for (const char of str) {
|
|
@@ -41685,44 +41896,74 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
41685
41896
|
parts.push(`<g transform="matrix(${a} ${b} ${-c} ${-d} ${e + c * displayList.height} ${f + d * displayList.height})">`);
|
|
41686
41897
|
}
|
|
41687
41898
|
let clipId = 0;
|
|
41688
|
-
|
|
41689
|
-
|
|
41690
|
-
const
|
|
41691
|
-
|
|
41692
|
-
|
|
41693
|
-
|
|
41694
|
-
const
|
|
41695
|
-
const
|
|
41696
|
-
|
|
41697
|
-
|
|
41698
|
-
|
|
41699
|
-
|
|
41700
|
-
|
|
41701
|
-
|
|
41702
|
-
|
|
41703
|
-
|
|
41704
|
-
|
|
41705
|
-
|
|
41706
|
-
|
|
41707
|
-
|
|
41708
|
-
|
|
41709
|
-
|
|
41710
|
-
|
|
41711
|
-
|
|
41712
|
-
|
|
41713
|
-
|
|
41714
|
-
|
|
41715
|
-
|
|
41716
|
-
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
41717
|
-
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
41718
|
-
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
41719
|
-
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
41899
|
+
const softMaskIds = /* @__PURE__ */ new Map();
|
|
41900
|
+
const appendOperations = (operations) => {
|
|
41901
|
+
for (const original of operations) {
|
|
41902
|
+
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
41903
|
+
const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
41904
|
+
const clips = original.value.clipPaths ?? [];
|
|
41905
|
+
const imageClips = original.value.clipImages ?? [];
|
|
41906
|
+
const blend = pdfBlendModeToCss(original.value.blendMode);
|
|
41907
|
+
if (blend) parts.push(`<g style="mix-blend-mode:${blend}">`);
|
|
41908
|
+
const softMask = original.value.softMask;
|
|
41909
|
+
if (softMask) {
|
|
41910
|
+
let id = softMaskIds.get(softMask);
|
|
41911
|
+
if (!id) {
|
|
41912
|
+
id = `soft-mask-${clipId++}`;
|
|
41913
|
+
softMaskIds.set(softMask, id);
|
|
41914
|
+
const bitmap = renderSoftMask(softMask, displayList, Math.max(scaleX, scaleY));
|
|
41915
|
+
const image = {
|
|
41916
|
+
name: id,
|
|
41917
|
+
width: bitmap.width,
|
|
41918
|
+
height: bitmap.height,
|
|
41919
|
+
decodedRgba: bitmap.data,
|
|
41920
|
+
matrix: [displayList.width, 0, 0, displayList.height, 0, 0],
|
|
41921
|
+
colorSpace: "DeviceGray",
|
|
41922
|
+
bitsPerComponent: 8
|
|
41923
|
+
};
|
|
41924
|
+
parts.push(`<defs><mask id="${id}" maskUnits="userSpaceOnUse" x="0" y="0" width="${displayList.width}" height="${displayList.height}" style="mask-type:alpha">${svgImage(image, displayList.height)}</mask></defs>`);
|
|
41925
|
+
}
|
|
41926
|
+
parts.push(`<g mask="url(#${id})">`);
|
|
41720
41927
|
}
|
|
41721
|
-
|
|
41722
|
-
|
|
41928
|
+
for (const clip of clips) {
|
|
41929
|
+
const { segments, fillRule } = "segments" in clip ? clip : { segments: clip, fillRule: "nonzero" };
|
|
41930
|
+
const id = `text-clip-${clipId++}`;
|
|
41931
|
+
const path = `<path d="${svgPathData(segments, displayList.height)}" clip-rule="${fillRule}"/>`;
|
|
41932
|
+
parts.push(`<defs><clipPath id="${id}" clipPathUnits="userSpaceOnUse">${path}</clipPath></defs><g clip-path="url(#${id})">`);
|
|
41933
|
+
}
|
|
41934
|
+
for (const image of imageClips) {
|
|
41935
|
+
const id = `image-clip-${clipId++}`;
|
|
41936
|
+
parts.push(`<defs><mask id="${id}" maskUnits="userSpaceOnUse" x="0" y="0" width="${displayList.width}" height="${displayList.height}" style="mask-type:alpha">${svgImage(image, displayList.height)}</mask></defs><g mask="url(#${id})">`);
|
|
41937
|
+
}
|
|
41938
|
+
if (operation.kind === "group") {
|
|
41939
|
+
parts.push(`<g opacity="${operation.value.alpha}" style="isolation:isolate">`);
|
|
41940
|
+
appendOperations(operation.value.operations);
|
|
41941
|
+
parts.push("</g>");
|
|
41942
|
+
} else if (operation.kind === "path") {
|
|
41943
|
+
const p = operation.value;
|
|
41944
|
+
const pathData = svgPathData(p.segments, displayList.height);
|
|
41945
|
+
if (pathData) {
|
|
41946
|
+
const fill = p.fillColor ? `rgb(${Math.round(p.fillColor.r * 255)},${Math.round(p.fillColor.g * 255)},${Math.round(p.fillColor.b * 255)})` : "none";
|
|
41947
|
+
const stroke = p.strokeColor ? `rgb(${Math.round(p.strokeColor.r * 255)},${Math.round(p.strokeColor.g * 255)},${Math.round(p.strokeColor.b * 255)})` : "none";
|
|
41948
|
+
const fillRuleAttr = p.fillRule === "evenodd" ? ` fill-rule="evenodd"` : "";
|
|
41949
|
+
const fillOpacityAttr = p.fillAlpha !== void 0 && p.fillAlpha < 1 ? ` fill-opacity="${p.fillAlpha}"` : "";
|
|
41950
|
+
const strokeOpacityAttr = p.strokeAlpha !== void 0 && p.strokeAlpha < 1 ? ` stroke-opacity="${p.strokeAlpha}"` : "";
|
|
41951
|
+
const strokeWidthAttr = p.strokeWidth <= 0 ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${p.strokeWidth}"`;
|
|
41952
|
+
const lineCapAttr = p.lineCap === 1 ? ` stroke-linecap="round"` : p.lineCap === 2 ? ` stroke-linecap="square"` : "";
|
|
41953
|
+
const lineJoinAttr = p.lineJoin === 1 ? ` stroke-linejoin="round"` : p.lineJoin === 2 ? ` stroke-linejoin="bevel"` : "";
|
|
41954
|
+
const miterLimitAttr = p.miterLimit !== void 0 && p.miterLimit !== 10 ? ` stroke-miterlimit="${p.miterLimit}"` : "";
|
|
41955
|
+
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
41956
|
+
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
41957
|
+
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
41958
|
+
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
41959
|
+
}
|
|
41960
|
+
} else if (operation.kind === "image") {
|
|
41961
|
+
parts.push(` ${svgImage(operation.value, displayList.height)}`);
|
|
41962
|
+
}
|
|
41963
|
+
for (let i = 0; i < clips.length + imageClips.length + (softMask ? 1 : 0) + (blend ? 1 : 0); i++) parts.push("</g>");
|
|
41723
41964
|
}
|
|
41724
|
-
|
|
41725
|
-
|
|
41965
|
+
};
|
|
41966
|
+
appendOperations(paintOperations(displayList));
|
|
41726
41967
|
if (displayList.rotation) parts.push("</g>");
|
|
41727
41968
|
parts.push("</svg>\n");
|
|
41728
41969
|
return parts.join("\n");
|
|
@@ -42682,3 +42923,8 @@ export {
|
|
|
42682
42923
|
* Adapted from PDFium third_party/agg23/agg_curves.cpp, curve4_div.
|
|
42683
42924
|
* See THIRD_PARTY_NOTICES.md for the pinned revision and adaptations.
|
|
42684
42925
|
*/
|
|
42926
|
+
/*!
|
|
42927
|
+
* Staged image reduction adapted from Mozilla PDF.js CanvasGraphics._scaleImage.
|
|
42928
|
+
* Copyright 2012 Mozilla Foundation. Licensed under Apache-2.0.
|
|
42929
|
+
* See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
|
|
42930
|
+
*/
|
|
@@ -48,11 +48,11 @@ import {
|
|
|
48
48
|
trimImage,
|
|
49
49
|
unflattenImage,
|
|
50
50
|
unpremultiplyRgbaImage
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-S5EX6UP5.js";
|
|
52
52
|
import {
|
|
53
53
|
PdfDocument,
|
|
54
54
|
encodePng
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-S3G2B4OX.js";
|
|
56
56
|
import {
|
|
57
57
|
createLuaFilterCapability
|
|
58
58
|
} from "./chunk-Y2KHC6TZ.js";
|