@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
|
@@ -36107,14 +36107,18 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36107
36107
|
const paths = [];
|
|
36108
36108
|
const images = [];
|
|
36109
36109
|
const operations = [];
|
|
36110
|
+
let capturedOperations;
|
|
36111
|
+
let insideSoftMask = false;
|
|
36110
36112
|
const emit = (operation) => {
|
|
36111
|
-
const { clipPaths, clipImages } = curState();
|
|
36112
|
-
if (clipPaths || clipImages) operation = { ...operation, value: {
|
|
36113
|
+
const { clipPaths, clipImages, softMask } = curState();
|
|
36114
|
+
if (clipPaths || clipImages || softMask) operation = { ...operation, value: {
|
|
36113
36115
|
...operation.value,
|
|
36114
36116
|
...clipPaths ? { clipPaths } : {},
|
|
36115
|
-
...clipImages ? { clipImages } : {}
|
|
36117
|
+
...clipImages ? { clipImages } : {},
|
|
36118
|
+
...softMask ? { softMask } : {}
|
|
36116
36119
|
} };
|
|
36117
|
-
operations.push(operation);
|
|
36120
|
+
(capturedOperations ?? operations).push(operation);
|
|
36121
|
+
if (insideSoftMask) return;
|
|
36118
36122
|
switch (operation.kind) {
|
|
36119
36123
|
case "path":
|
|
36120
36124
|
paths.push(operation.value);
|
|
@@ -36220,7 +36224,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36220
36224
|
);
|
|
36221
36225
|
return { r: kClamp(r), g: kClamp(g), b: kClamp(b) };
|
|
36222
36226
|
};
|
|
36223
|
-
const applyStateOperator = (st, operator, ops, activeResources) => {
|
|
36227
|
+
const applyStateOperator = (st, operator, ops, activeResources, activeFonts, depth) => {
|
|
36224
36228
|
const num = (i, fb = 0) => ops[i]?.kind === "number" ? ops[i].value : fb;
|
|
36225
36229
|
if (operator === "cm") {
|
|
36226
36230
|
const m = [num(0, 1), num(1, 0), num(2, 0), num(3, 1), num(4, 0), num(5, 0)];
|
|
@@ -36303,6 +36307,46 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36303
36307
|
const extDict = params.cosDoc.resolveDict(dictGet(activeResources, "ExtGState"));
|
|
36304
36308
|
const gsDict = extDict ? params.cosDoc.resolveDict(dictGet(extDict, ops[0].decoded)) : void 0;
|
|
36305
36309
|
if (gsDict) {
|
|
36310
|
+
const mask = params.cosDoc.resolve(dictGet(gsDict, "SMask"));
|
|
36311
|
+
if (mask?.kind === "name" && mask.decoded === "None") {
|
|
36312
|
+
st.softMask = void 0;
|
|
36313
|
+
} else if (mask?.kind === "dict") {
|
|
36314
|
+
const subtype = params.cosDoc.resolve(dictGet(mask, "S"));
|
|
36315
|
+
const form = params.cosDoc.resolve(dictGet(mask, "G"));
|
|
36316
|
+
if (form?.kind === "stream" && subtype?.kind === "name" && (subtype.decoded === "Alpha" || subtype.decoded === "Luminosity")) {
|
|
36317
|
+
if (depth >= 8) throw new PdfError("E_LIMIT", "Soft-mask nesting exceeds the form depth limit");
|
|
36318
|
+
const parentOperations = capturedOperations;
|
|
36319
|
+
const parentInsideSoftMask = insideSoftMask;
|
|
36320
|
+
const savedTextState = { pendingTextClip, hasTextClip, activeTm, activeTlm };
|
|
36321
|
+
const captured = [];
|
|
36322
|
+
capturedOperations = captured;
|
|
36323
|
+
insideSoftMask = true;
|
|
36324
|
+
const maskState = { ...st, softMask: void 0, fillAlpha: 1, strokeAlpha: 1, blendMode: "Normal" };
|
|
36325
|
+
delete maskState.clipPaths;
|
|
36326
|
+
delete maskState.clipImages;
|
|
36327
|
+
delete maskState.clipRect;
|
|
36328
|
+
stateStack.push(maskState);
|
|
36329
|
+
try {
|
|
36330
|
+
paintForm(form, activeResources, activeFonts, depth, void 0, void 0, true);
|
|
36331
|
+
} finally {
|
|
36332
|
+
stateStack.pop();
|
|
36333
|
+
capturedOperations = parentOperations;
|
|
36334
|
+
insideSoftMask = parentInsideSoftMask;
|
|
36335
|
+
({ pendingTextClip, hasTextClip, activeTm, activeTlm } = savedTextState);
|
|
36336
|
+
}
|
|
36337
|
+
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
36338
|
+
const colorSpace = group ? dictGet(group, "CS") : void 0;
|
|
36339
|
+
const bc = params.cosDoc.resolveArray(dictGet(mask, "BC"));
|
|
36340
|
+
const components = bc?.items.map((item) => {
|
|
36341
|
+
const value = params.cosDoc.resolve(item);
|
|
36342
|
+
return value?.kind === "number" ? value.value : 0;
|
|
36343
|
+
});
|
|
36344
|
+
const [r, g, b] = components ? convertColorSpaceComponentsToRgb(params.cosDoc, colorSpace, "DeviceRGB", components, activeResources) : [0, 0, 0];
|
|
36345
|
+
const transfer = params.cosDoc.resolve(dictGet(mask, "TR"));
|
|
36346
|
+
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;
|
|
36347
|
+
st.softMask = { subtype: subtype.decoded, operations: captured, backdrop: { r, g, b }, transferMap };
|
|
36348
|
+
}
|
|
36349
|
+
}
|
|
36306
36350
|
const bmNode = params.cosDoc.resolve(dictGet(gsDict, "BM"));
|
|
36307
36351
|
if (bmNode?.kind === "name") {
|
|
36308
36352
|
st.blendMode = bmNode.decoded === "Compatible" ? "Normal" : bmNode.decoded;
|
|
@@ -36389,6 +36433,84 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36389
36433
|
] }], void 0, void 0, resources, activeFonts, depth);
|
|
36390
36434
|
stateStack.pop();
|
|
36391
36435
|
};
|
|
36436
|
+
const paintForm = (form, activeResources, activeFonts, depth, mcid, actualText, maskGroup = false) => {
|
|
36437
|
+
const st = curState();
|
|
36438
|
+
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
36439
|
+
const groupType = group ? params.cosDoc.resolve(dictGet(group, "S")) : void 0;
|
|
36440
|
+
const isolated = group ? params.cosDoc.resolve(dictGet(group, "I")) : void 0;
|
|
36441
|
+
const isolate = !maskGroup && groupType?.kind === "name" && groupType.decoded === "Transparency" && isolated?.kind === "boolean" && isolated.value;
|
|
36442
|
+
const formStreamBytes = params.cosDoc.decodeStream(form);
|
|
36443
|
+
const formNodes = parseContentStream(formStreamBytes);
|
|
36444
|
+
const formResDict = params.cosDoc.resolveDict(dictGet(form.dict, "Resources")) ?? activeResources;
|
|
36445
|
+
const formFonts = new Map(activeFonts);
|
|
36446
|
+
for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
|
|
36447
|
+
formFonts.set(k, v);
|
|
36448
|
+
}
|
|
36449
|
+
let nextCtm = [...st.ctm];
|
|
36450
|
+
const matArr = params.cosDoc.resolveArray(dictGet(form.dict, "Matrix"));
|
|
36451
|
+
if (matArr && matArr.items.length >= 6) {
|
|
36452
|
+
const mn = (idx, fb = 0) => {
|
|
36453
|
+
const resolved = params.cosDoc.resolve(matArr.items[idx]);
|
|
36454
|
+
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36455
|
+
};
|
|
36456
|
+
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36457
|
+
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36458
|
+
}
|
|
36459
|
+
let nextClip = !isolate && st.clipRect ? [...st.clipRect] : void 0;
|
|
36460
|
+
let nextClipPaths = isolate ? void 0 : st.clipPaths;
|
|
36461
|
+
const bboxArr = params.cosDoc.resolveArray(dictGet(form.dict, "BBox"));
|
|
36462
|
+
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36463
|
+
const bn = (idx, fb = 0) => {
|
|
36464
|
+
const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
|
|
36465
|
+
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36466
|
+
};
|
|
36467
|
+
const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
|
|
36468
|
+
const pts = [
|
|
36469
|
+
transformPoint(nextCtm, bx0, by0),
|
|
36470
|
+
transformPoint(nextCtm, bx1, by0),
|
|
36471
|
+
transformPoint(nextCtm, bx1, by1),
|
|
36472
|
+
transformPoint(nextCtm, bx0, by1)
|
|
36473
|
+
];
|
|
36474
|
+
nextClipPaths = [...nextClipPaths ?? [], [
|
|
36475
|
+
...pts.map(([x, y], index) => ({ kind: index === 0 ? "move" : "line", x, y })),
|
|
36476
|
+
{ kind: "close" }
|
|
36477
|
+
]];
|
|
36478
|
+
const fMinX = Math.min(...pts.map((p) => p[0]));
|
|
36479
|
+
const fMinY = Math.min(...pts.map((p) => p[1]));
|
|
36480
|
+
const fMaxX = Math.max(...pts.map((p) => p[0]));
|
|
36481
|
+
const fMaxY = Math.max(...pts.map((p) => p[1]));
|
|
36482
|
+
if (fMaxX > fMinX && fMaxY > fMinY) {
|
|
36483
|
+
nextClip = nextClip ? [
|
|
36484
|
+
Math.max(nextClip[0], fMinX),
|
|
36485
|
+
Math.max(nextClip[1], fMinY),
|
|
36486
|
+
Math.min(nextClip[2], fMaxX),
|
|
36487
|
+
Math.min(nextClip[3], fMaxY)
|
|
36488
|
+
] : [fMinX, fMinY, fMaxX, fMaxY];
|
|
36489
|
+
}
|
|
36490
|
+
}
|
|
36491
|
+
const parentOperations = capturedOperations;
|
|
36492
|
+
const children = [];
|
|
36493
|
+
const nextState = { ...st, ctm: nextCtm };
|
|
36494
|
+
if (isolate) {
|
|
36495
|
+
capturedOperations = children;
|
|
36496
|
+
nextState.fillAlpha = nextState.strokeAlpha = 1;
|
|
36497
|
+
nextState.blendMode = "Normal";
|
|
36498
|
+
nextState.softMask = void 0;
|
|
36499
|
+
delete nextState.clipImages;
|
|
36500
|
+
delete nextState.clipPaths;
|
|
36501
|
+
delete nextState.clipRect;
|
|
36502
|
+
}
|
|
36503
|
+
if (nextClip) nextState.clipRect = nextClip;
|
|
36504
|
+
if (nextClipPaths) nextState.clipPaths = nextClipPaths;
|
|
36505
|
+
stateStack.push(nextState);
|
|
36506
|
+
try {
|
|
36507
|
+
walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
|
|
36508
|
+
} finally {
|
|
36509
|
+
stateStack.pop();
|
|
36510
|
+
capturedOperations = parentOperations;
|
|
36511
|
+
}
|
|
36512
|
+
if (isolate) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
|
|
36513
|
+
};
|
|
36392
36514
|
const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
|
|
36393
36515
|
for (const node of nodes) {
|
|
36394
36516
|
switch (node.kind) {
|
|
@@ -36433,7 +36555,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36433
36555
|
break;
|
|
36434
36556
|
}
|
|
36435
36557
|
case "state-op": {
|
|
36436
|
-
applyStateOperator(curState(), node.operator, node.operands, activeResources);
|
|
36558
|
+
applyStateOperator(curState(), node.operator, node.operands, activeResources, activeFonts, depth);
|
|
36437
36559
|
break;
|
|
36438
36560
|
}
|
|
36439
36561
|
case "path-op": {
|
|
@@ -36719,53 +36841,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36719
36841
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
36720
36842
|
}, patternMask, activeResources, activeFonts, depth);
|
|
36721
36843
|
} else if (sub === "Form" && depth < 8) {
|
|
36722
|
-
|
|
36723
|
-
const formNodes = parseContentStream(formStreamBytes);
|
|
36724
|
-
const formResDict = params.cosDoc.resolveDict(dictGet(xobjNode.dict, "Resources")) ?? activeResources;
|
|
36725
|
-
const formFonts = new Map(activeFonts);
|
|
36726
|
-
for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
|
|
36727
|
-
formFonts.set(k, v);
|
|
36728
|
-
}
|
|
36729
|
-
let nextCtm = [...st.ctm];
|
|
36730
|
-
const matArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "Matrix"));
|
|
36731
|
-
if (matArr && matArr.items.length >= 6) {
|
|
36732
|
-
const mn = (idx, fb = 0) => {
|
|
36733
|
-
const resolved = params.cosDoc.resolve(matArr.items[idx]);
|
|
36734
|
-
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36735
|
-
};
|
|
36736
|
-
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36737
|
-
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36738
|
-
}
|
|
36739
|
-
let nextClip = st.clipRect ? [...st.clipRect] : void 0;
|
|
36740
|
-
const bboxArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "BBox"));
|
|
36741
|
-
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36742
|
-
const bn = (idx, fb = 0) => {
|
|
36743
|
-
const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
|
|
36744
|
-
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36745
|
-
};
|
|
36746
|
-
const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
|
|
36747
|
-
const pts = [
|
|
36748
|
-
transformPoint(nextCtm, bx0, by0),
|
|
36749
|
-
transformPoint(nextCtm, bx1, by0),
|
|
36750
|
-
transformPoint(nextCtm, bx0, by1),
|
|
36751
|
-
transformPoint(nextCtm, bx1, by1)
|
|
36752
|
-
];
|
|
36753
|
-
const fMinX = Math.min(...pts.map((p) => p[0]));
|
|
36754
|
-
const fMinY = Math.min(...pts.map((p) => p[1]));
|
|
36755
|
-
const fMaxX = Math.max(...pts.map((p) => p[0]));
|
|
36756
|
-
const fMaxY = Math.max(...pts.map((p) => p[1]));
|
|
36757
|
-
if (fMaxX > fMinX && fMaxY > fMinY) {
|
|
36758
|
-
nextClip = nextClip ? [
|
|
36759
|
-
Math.max(nextClip[0], fMinX),
|
|
36760
|
-
Math.max(nextClip[1], fMinY),
|
|
36761
|
-
Math.min(nextClip[2], fMaxX),
|
|
36762
|
-
Math.min(nextClip[3], fMaxY)
|
|
36763
|
-
] : [fMinX, fMinY, fMaxX, fMaxY];
|
|
36764
|
-
}
|
|
36765
|
-
}
|
|
36766
|
-
stateStack.push({ ...st, ctm: nextCtm, ...nextClip ? { clipRect: nextClip } : {} });
|
|
36767
|
-
walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
|
|
36768
|
-
if (stateStack.length > 1) stateStack.pop();
|
|
36844
|
+
paintForm(xobjNode, activeResources, activeFonts, depth, mcid, actualText);
|
|
36769
36845
|
}
|
|
36770
36846
|
}
|
|
36771
36847
|
}
|
|
@@ -36984,7 +37060,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36984
37060
|
st.textRenderMode = cmd.mode;
|
|
36985
37061
|
break;
|
|
36986
37062
|
case "state-op":
|
|
36987
|
-
applyStateOperator(st, cmd.operator, cmd.operands, activeResources);
|
|
37063
|
+
applyStateOperator(st, cmd.operator, cmd.operands, activeResources, activeFonts, depth);
|
|
36988
37064
|
break;
|
|
36989
37065
|
case "show-text":
|
|
36990
37066
|
emitTokenBytes(cmd.token.bytes);
|
|
@@ -39247,6 +39323,47 @@ function flattenCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
|
|
|
39247
39323
|
points.push([x4, y4]);
|
|
39248
39324
|
return points;
|
|
39249
39325
|
}
|
|
39326
|
+
function sampleImageLinear(image, x, y, out) {
|
|
39327
|
+
x = Math.max(0, Math.min(image.width - 1, x));
|
|
39328
|
+
y = Math.max(0, Math.min(image.height - 1, y));
|
|
39329
|
+
const x0 = Math.floor(x), y0 = Math.floor(y);
|
|
39330
|
+
const fx = x - x0, fy = y - y0;
|
|
39331
|
+
out.fill(0);
|
|
39332
|
+
for (let j = 0; j < 2; j++) {
|
|
39333
|
+
for (let i = 0; i < 2; i++) {
|
|
39334
|
+
const offset = (Math.min(image.height - 1, y0 + j) * image.width + Math.min(image.width - 1, x0 + i)) * 4;
|
|
39335
|
+
const alpha = image.data[offset + 3] * (i ? fx : 1 - fx) * (j ? fy : 1 - fy);
|
|
39336
|
+
out[0] = out[0] + image.data[offset] * alpha;
|
|
39337
|
+
out[1] = out[1] + image.data[offset + 1] * alpha;
|
|
39338
|
+
out[2] = out[2] + image.data[offset + 2] * alpha;
|
|
39339
|
+
out[3] = out[3] + alpha;
|
|
39340
|
+
}
|
|
39341
|
+
}
|
|
39342
|
+
if (out[3] > 0) {
|
|
39343
|
+
out[0] = out[0] / out[3];
|
|
39344
|
+
out[1] = out[1] / out[3];
|
|
39345
|
+
out[2] = out[2] / out[3];
|
|
39346
|
+
}
|
|
39347
|
+
}
|
|
39348
|
+
function downscaleImage(image, widthScale, heightScale) {
|
|
39349
|
+
const sample = new Float64Array(4);
|
|
39350
|
+
while (widthScale > 2 && image.width > 1 || heightScale > 2 && image.height > 1) {
|
|
39351
|
+
const width = widthScale > 2 ? Math.ceil(image.width / 2) : image.width;
|
|
39352
|
+
const height = heightScale > 2 ? Math.ceil(image.height / 2) : image.height;
|
|
39353
|
+
const data = new Uint8Array(width * height * 4);
|
|
39354
|
+
for (let y = 0; y < height; y++) {
|
|
39355
|
+
for (let x = 0; x < width; x++) {
|
|
39356
|
+
sampleImageLinear(image, (x + 0.5) * image.width / width - 0.5, (y + 0.5) * image.height / height - 0.5, sample);
|
|
39357
|
+
const offset = (y * width + x) * 4;
|
|
39358
|
+
for (let c = 0; c < 4; c++) data[offset + c] = Math.round(sample[c]);
|
|
39359
|
+
}
|
|
39360
|
+
}
|
|
39361
|
+
widthScale /= image.width / width;
|
|
39362
|
+
heightScale /= image.height / height;
|
|
39363
|
+
image = { width, height, data };
|
|
39364
|
+
}
|
|
39365
|
+
return image;
|
|
39366
|
+
}
|
|
39250
39367
|
function encodePng(bitmap) {
|
|
39251
39368
|
return encodeRgbaToPng(bitmap.width, bitmap.height, bitmap.data);
|
|
39252
39369
|
}
|
|
@@ -40552,6 +40669,30 @@ function paintOperations(displayList) {
|
|
|
40552
40669
|
...displayList.glyphs.map((value) => ({ kind: "glyph", value }))
|
|
40553
40670
|
];
|
|
40554
40671
|
}
|
|
40672
|
+
function renderSoftMask(mask, displayList, scale) {
|
|
40673
|
+
const bitmap = renderDisplayListToBitmap({
|
|
40674
|
+
...displayList,
|
|
40675
|
+
rotation: 0,
|
|
40676
|
+
glyphs: [],
|
|
40677
|
+
paths: [],
|
|
40678
|
+
images: [],
|
|
40679
|
+
operations: mask.operations
|
|
40680
|
+
}, { scale, transparent: true });
|
|
40681
|
+
const { data } = bitmap;
|
|
40682
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
40683
|
+
let value = data[i + 3];
|
|
40684
|
+
if (mask.subtype === "Luminosity") {
|
|
40685
|
+
const alpha = value / 255;
|
|
40686
|
+
const r = Math.round(data[i] * alpha + mask.backdrop.r * 255 * (1 - alpha));
|
|
40687
|
+
const g = Math.round(data[i + 1] * alpha + mask.backdrop.g * 255 * (1 - alpha));
|
|
40688
|
+
const b = Math.round(data[i + 2] * alpha + mask.backdrop.b * 255 * (1 - alpha));
|
|
40689
|
+
value = Math.round(pdfLum(r, g, b));
|
|
40690
|
+
}
|
|
40691
|
+
data[i] = data[i + 1] = data[i + 2] = 0;
|
|
40692
|
+
data[i + 3] = mask.transferMap?.[value] ?? value;
|
|
40693
|
+
}
|
|
40694
|
+
return bitmap;
|
|
40695
|
+
}
|
|
40555
40696
|
function renderDisplayListToBitmap(displayList, options = {}) {
|
|
40556
40697
|
const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
|
|
40557
40698
|
const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
|
|
@@ -40575,10 +40716,28 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40575
40716
|
const aaTxt = options.antialiasText !== false;
|
|
40576
40717
|
let cachedClips;
|
|
40577
40718
|
let cachedClipMask;
|
|
40719
|
+
let cachedSoftMask;
|
|
40720
|
+
let cachedSoftMaskPixels;
|
|
40578
40721
|
const imageClipMasks = /* @__PURE__ */ new Map();
|
|
40579
40722
|
for (const original of paintOperations(displayList)) {
|
|
40580
40723
|
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
40581
|
-
|
|
40724
|
+
let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
40725
|
+
if (operation.kind === "group") {
|
|
40726
|
+
const group = operation.value;
|
|
40727
|
+
const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations: group.operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, transparent: true });
|
|
40728
|
+
for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
|
|
40729
|
+
operation = { kind: "image", value: {
|
|
40730
|
+
name: "TransparencyGroup",
|
|
40731
|
+
width: bitmap.width,
|
|
40732
|
+
height: bitmap.height,
|
|
40733
|
+
decodedRgba: bitmap.data,
|
|
40734
|
+
matrix: [bitmap.width / scale, 0, 0, bitmap.height / scale, 0, displayList.height - bitmap.height / scale],
|
|
40735
|
+
colorSpace: "DeviceRGB",
|
|
40736
|
+
bitsPerComponent: 8,
|
|
40737
|
+
blendMode: group.blendMode,
|
|
40738
|
+
clipRect: group.clipRect
|
|
40739
|
+
} };
|
|
40740
|
+
}
|
|
40582
40741
|
const clips = original.value.clipPaths;
|
|
40583
40742
|
let clipMask = clips && clips === cachedClips ? cachedClipMask : void 0;
|
|
40584
40743
|
if (clips && !clipMask) {
|
|
@@ -40592,6 +40751,19 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40592
40751
|
cachedClips = clips;
|
|
40593
40752
|
cachedClipMask = clipMask;
|
|
40594
40753
|
}
|
|
40754
|
+
const softMask = original.value.softMask;
|
|
40755
|
+
if (softMask) {
|
|
40756
|
+
if (softMask !== cachedSoftMask) {
|
|
40757
|
+
cachedSoftMaskPixels = renderSoftMask(softMask, displayList, scale).data;
|
|
40758
|
+
cachedSoftMask = softMask;
|
|
40759
|
+
}
|
|
40760
|
+
if (clipMask) {
|
|
40761
|
+
clipMask = clipMask.slice();
|
|
40762
|
+
for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * cachedSoftMaskPixels[i] / 255);
|
|
40763
|
+
} else {
|
|
40764
|
+
clipMask = cachedSoftMaskPixels;
|
|
40765
|
+
}
|
|
40766
|
+
}
|
|
40595
40767
|
const imageClips = original.value.clipImages;
|
|
40596
40768
|
if (imageClips) {
|
|
40597
40769
|
let imageMask = imageClipMasks.get(imageClips);
|
|
@@ -40695,6 +40867,17 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40695
40867
|
const maxPx = Math.min(width - 1, clipMaxPx, Math.ceil(Math.max(...cornersPx)) - 1);
|
|
40696
40868
|
const minPy = Math.max(0, clipMinPy, Math.floor(Math.min(...cornersPy)));
|
|
40697
40869
|
const maxPy = Math.min(height - 1, clipMaxPy, Math.ceil(Math.max(...cornersPy)) - 1);
|
|
40870
|
+
if (minPx > maxPx || minPy > maxPy) continue;
|
|
40871
|
+
const source = downscaleImage(
|
|
40872
|
+
{ width: img.width, height: img.height, data: img.decodedRgba },
|
|
40873
|
+
Math.hypot(d, c) * img.width / Math.abs(det * scale),
|
|
40874
|
+
Math.hypot(b, a) * img.height / Math.abs(det * scale)
|
|
40875
|
+
);
|
|
40876
|
+
const ax = a * scale / img.width, ay = b * scale / img.width;
|
|
40877
|
+
const bx = c * scale / img.height, by = d * scale / img.height;
|
|
40878
|
+
const s1 = ax * ax + ay * ay, s2 = bx * bx + by * by, cross = ax * bx + ay * by;
|
|
40879
|
+
const smooth = Math.fround((s1 + s2 + Math.hypot(s1 - s2, 2 * cross)) / 2) <= 1;
|
|
40880
|
+
const sample = new Float64Array(4);
|
|
40698
40881
|
for (let py = minPy; py <= maxPy; py++) {
|
|
40699
40882
|
const yPdf = displayList.height - (py + 0.5) / scale;
|
|
40700
40883
|
if (img.clipRect && (yPdf < img.clipRect[1] || yPdf > img.clipRect[3])) continue;
|
|
@@ -40706,9 +40889,14 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40706
40889
|
const u = (d * dxPdf - c * dyPdf) / det;
|
|
40707
40890
|
const v = (-b * dxPdf + a * dyPdf) / det;
|
|
40708
40891
|
if (u < 0 || u > 1 || v < 0 || v > 1) continue;
|
|
40709
|
-
|
|
40710
|
-
|
|
40711
|
-
|
|
40892
|
+
if (smooth) {
|
|
40893
|
+
sampleImageLinear(source, u * source.width - 0.5, (1 - v) * source.height - 0.5, sample);
|
|
40894
|
+
} else {
|
|
40895
|
+
const sx = Math.min(source.width - 1, Math.max(0, Math.floor(u * source.width)));
|
|
40896
|
+
const sy = Math.min(source.height - 1, Math.max(0, Math.floor((1 - v) * source.height)));
|
|
40897
|
+
const sIdx = (sy * source.width + sx) * 4;
|
|
40898
|
+
for (let c2 = 0; c2 < 4; c2++) sample[c2] = source.data[sIdx + c2];
|
|
40899
|
+
}
|
|
40712
40900
|
blendPixel(
|
|
40713
40901
|
rgba,
|
|
40714
40902
|
width,
|
|
@@ -40716,11 +40904,11 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40716
40904
|
px,
|
|
40717
40905
|
py,
|
|
40718
40906
|
{
|
|
40719
|
-
r:
|
|
40720
|
-
g:
|
|
40721
|
-
b:
|
|
40907
|
+
r: sample[0] / 255,
|
|
40908
|
+
g: sample[1] / 255,
|
|
40909
|
+
b: sample[2] / 255
|
|
40722
40910
|
},
|
|
40723
|
-
|
|
40911
|
+
sample[3] / 255,
|
|
40724
40912
|
img.blendMode,
|
|
40725
40913
|
clipMask
|
|
40726
40914
|
);
|
|
@@ -40757,6 +40945,27 @@ function renderDisplayListToPng(displayList, options = {}) {
|
|
|
40757
40945
|
const bmp = renderDisplayListToBitmap(displayList, options);
|
|
40758
40946
|
return encodeRgbaToPng(bmp.width, bmp.height, bmp.data);
|
|
40759
40947
|
}
|
|
40948
|
+
function pdfBlendModeToCss(mode) {
|
|
40949
|
+
if (!mode || mode === "Normal" || mode === "Compatible") return void 0;
|
|
40950
|
+
const map = {
|
|
40951
|
+
Multiply: "multiply",
|
|
40952
|
+
Screen: "screen",
|
|
40953
|
+
Overlay: "overlay",
|
|
40954
|
+
Darken: "darken",
|
|
40955
|
+
Lighten: "lighten",
|
|
40956
|
+
ColorDodge: "color-dodge",
|
|
40957
|
+
ColorBurn: "color-burn",
|
|
40958
|
+
HardLight: "hard-light",
|
|
40959
|
+
SoftLight: "soft-light",
|
|
40960
|
+
Difference: "difference",
|
|
40961
|
+
Exclusion: "exclusion",
|
|
40962
|
+
Hue: "hue",
|
|
40963
|
+
Saturation: "saturation",
|
|
40964
|
+
Color: "color",
|
|
40965
|
+
Luminosity: "luminosity"
|
|
40966
|
+
};
|
|
40967
|
+
return map[mode];
|
|
40968
|
+
}
|
|
40760
40969
|
function escapeXmlText(str) {
|
|
40761
40970
|
let valid = "";
|
|
40762
40971
|
for (const char of str) {
|
|
@@ -40818,44 +41027,74 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
40818
41027
|
parts.push(`<g transform="matrix(${a} ${b} ${-c} ${-d} ${e + c * displayList.height} ${f + d * displayList.height})">`);
|
|
40819
41028
|
}
|
|
40820
41029
|
let clipId = 0;
|
|
40821
|
-
|
|
40822
|
-
|
|
40823
|
-
const
|
|
40824
|
-
|
|
40825
|
-
|
|
40826
|
-
|
|
40827
|
-
const
|
|
40828
|
-
const
|
|
40829
|
-
|
|
40830
|
-
|
|
40831
|
-
|
|
40832
|
-
|
|
40833
|
-
|
|
40834
|
-
|
|
40835
|
-
|
|
40836
|
-
|
|
40837
|
-
|
|
40838
|
-
|
|
40839
|
-
|
|
40840
|
-
|
|
40841
|
-
|
|
40842
|
-
|
|
40843
|
-
|
|
40844
|
-
|
|
40845
|
-
|
|
40846
|
-
|
|
40847
|
-
|
|
40848
|
-
|
|
40849
|
-
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
40850
|
-
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
40851
|
-
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
40852
|
-
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
41030
|
+
const softMaskIds = /* @__PURE__ */ new Map();
|
|
41031
|
+
const appendOperations = (operations) => {
|
|
41032
|
+
for (const original of operations) {
|
|
41033
|
+
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
41034
|
+
const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
41035
|
+
const clips = original.value.clipPaths ?? [];
|
|
41036
|
+
const imageClips = original.value.clipImages ?? [];
|
|
41037
|
+
const blend = pdfBlendModeToCss(original.value.blendMode);
|
|
41038
|
+
if (blend) parts.push(`<g style="mix-blend-mode:${blend}">`);
|
|
41039
|
+
const softMask = original.value.softMask;
|
|
41040
|
+
if (softMask) {
|
|
41041
|
+
let id = softMaskIds.get(softMask);
|
|
41042
|
+
if (!id) {
|
|
41043
|
+
id = `soft-mask-${clipId++}`;
|
|
41044
|
+
softMaskIds.set(softMask, id);
|
|
41045
|
+
const bitmap = renderSoftMask(softMask, displayList, Math.max(scaleX, scaleY));
|
|
41046
|
+
const image = {
|
|
41047
|
+
name: id,
|
|
41048
|
+
width: bitmap.width,
|
|
41049
|
+
height: bitmap.height,
|
|
41050
|
+
decodedRgba: bitmap.data,
|
|
41051
|
+
matrix: [displayList.width, 0, 0, displayList.height, 0, 0],
|
|
41052
|
+
colorSpace: "DeviceGray",
|
|
41053
|
+
bitsPerComponent: 8
|
|
41054
|
+
};
|
|
41055
|
+
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>`);
|
|
41056
|
+
}
|
|
41057
|
+
parts.push(`<g mask="url(#${id})">`);
|
|
40853
41058
|
}
|
|
40854
|
-
|
|
40855
|
-
|
|
41059
|
+
for (const clip of clips) {
|
|
41060
|
+
const { segments, fillRule } = "segments" in clip ? clip : { segments: clip, fillRule: "nonzero" };
|
|
41061
|
+
const id = `text-clip-${clipId++}`;
|
|
41062
|
+
const path = `<path d="${svgPathData(segments, displayList.height)}" clip-rule="${fillRule}"/>`;
|
|
41063
|
+
parts.push(`<defs><clipPath id="${id}" clipPathUnits="userSpaceOnUse">${path}</clipPath></defs><g clip-path="url(#${id})">`);
|
|
41064
|
+
}
|
|
41065
|
+
for (const image of imageClips) {
|
|
41066
|
+
const id = `image-clip-${clipId++}`;
|
|
41067
|
+
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})">`);
|
|
41068
|
+
}
|
|
41069
|
+
if (operation.kind === "group") {
|
|
41070
|
+
parts.push(`<g opacity="${operation.value.alpha}" style="isolation:isolate">`);
|
|
41071
|
+
appendOperations(operation.value.operations);
|
|
41072
|
+
parts.push("</g>");
|
|
41073
|
+
} else if (operation.kind === "path") {
|
|
41074
|
+
const p = operation.value;
|
|
41075
|
+
const pathData = svgPathData(p.segments, displayList.height);
|
|
41076
|
+
if (pathData) {
|
|
41077
|
+
const fill = p.fillColor ? `rgb(${Math.round(p.fillColor.r * 255)},${Math.round(p.fillColor.g * 255)},${Math.round(p.fillColor.b * 255)})` : "none";
|
|
41078
|
+
const stroke = p.strokeColor ? `rgb(${Math.round(p.strokeColor.r * 255)},${Math.round(p.strokeColor.g * 255)},${Math.round(p.strokeColor.b * 255)})` : "none";
|
|
41079
|
+
const fillRuleAttr = p.fillRule === "evenodd" ? ` fill-rule="evenodd"` : "";
|
|
41080
|
+
const fillOpacityAttr = p.fillAlpha !== void 0 && p.fillAlpha < 1 ? ` fill-opacity="${p.fillAlpha}"` : "";
|
|
41081
|
+
const strokeOpacityAttr = p.strokeAlpha !== void 0 && p.strokeAlpha < 1 ? ` stroke-opacity="${p.strokeAlpha}"` : "";
|
|
41082
|
+
const strokeWidthAttr = p.strokeWidth <= 0 ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${p.strokeWidth}"`;
|
|
41083
|
+
const lineCapAttr = p.lineCap === 1 ? ` stroke-linecap="round"` : p.lineCap === 2 ? ` stroke-linecap="square"` : "";
|
|
41084
|
+
const lineJoinAttr = p.lineJoin === 1 ? ` stroke-linejoin="round"` : p.lineJoin === 2 ? ` stroke-linejoin="bevel"` : "";
|
|
41085
|
+
const miterLimitAttr = p.miterLimit !== void 0 && p.miterLimit !== 10 ? ` stroke-miterlimit="${p.miterLimit}"` : "";
|
|
41086
|
+
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
41087
|
+
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
41088
|
+
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
41089
|
+
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
41090
|
+
}
|
|
41091
|
+
} else if (operation.kind === "image") {
|
|
41092
|
+
parts.push(` ${svgImage(operation.value, displayList.height)}`);
|
|
41093
|
+
}
|
|
41094
|
+
for (let i = 0; i < clips.length + imageClips.length + (softMask ? 1 : 0) + (blend ? 1 : 0); i++) parts.push("</g>");
|
|
40856
41095
|
}
|
|
40857
|
-
|
|
40858
|
-
|
|
41096
|
+
};
|
|
41097
|
+
appendOperations(paintOperations(displayList));
|
|
40859
41098
|
if (displayList.rotation) parts.push("</g>");
|
|
40860
41099
|
parts.push("</svg>\n");
|
|
40861
41100
|
return parts.join("\n");
|
|
@@ -44268,3 +44507,8 @@ export {
|
|
|
44268
44507
|
* Adapted from PDFium third_party/agg23/agg_curves.cpp, curve4_div.
|
|
44269
44508
|
* See THIRD_PARTY_NOTICES.md for the pinned revision and adaptations.
|
|
44270
44509
|
*/
|
|
44510
|
+
/*!
|
|
44511
|
+
* Staged image reduction adapted from Mozilla PDF.js CanvasGraphics._scaleImage.
|
|
44512
|
+
* Copyright 2012 Mozilla Foundation. Licensed under Apache-2.0.
|
|
44513
|
+
* See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
|
|
44514
|
+
*/
|