@poe-platform/safe-bash 0.1.762 → 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 +186 -55
- package/dist/image-ast/index.js +186 -55
- package/dist/pdf-ast/ast.d.ts +23 -0
- package/dist/pdf-ast/index.js +273 -91
- package/dist/safe-bash/command-chunks/{chunk-D4GXXV65.js → chunk-4XHONGIU.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-P3Q2QSCA.js → chunk-S3G2B4OX.js} +186 -55
- package/dist/safe-bash/command-chunks/{chunk-F7MJRXQ2.js → chunk-S5EX6UP5.js} +1 -1
- package/dist/safe-bash/core.browser.js +1 -1
- package/dist/safe-bash/shell/runtime.js +1 -1
- 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 +7486 -7432
- 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 +186 -55
- package/dist/safe-bash-command-pdfinfo/index.js +273 -91
- package/dist/safe-bash-command-pdftk/index.js +186 -55
- package/dist/safe-bash-command-pdftoppm/index.js +273 -91
- package/dist/safe-bash-command-pdftotext/index.js +186 -55
- package/dist/safe-bash-command-qpdf/index.js +186 -55
- 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 +249 -58
- package/dist/safe-bash-command-wkhtmltopdf/index.js +186 -55
- package/package.json +2 -2
- package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +13 -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);
|
|
@@ -40593,6 +40669,30 @@ function paintOperations(displayList) {
|
|
|
40593
40669
|
...displayList.glyphs.map((value) => ({ kind: "glyph", value }))
|
|
40594
40670
|
];
|
|
40595
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
|
+
}
|
|
40596
40696
|
function renderDisplayListToBitmap(displayList, options = {}) {
|
|
40597
40697
|
const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
|
|
40598
40698
|
const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
|
|
@@ -40616,10 +40716,28 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40616
40716
|
const aaTxt = options.antialiasText !== false;
|
|
40617
40717
|
let cachedClips;
|
|
40618
40718
|
let cachedClipMask;
|
|
40719
|
+
let cachedSoftMask;
|
|
40720
|
+
let cachedSoftMaskPixels;
|
|
40619
40721
|
const imageClipMasks = /* @__PURE__ */ new Map();
|
|
40620
40722
|
for (const original of paintOperations(displayList)) {
|
|
40621
40723
|
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
40622
|
-
|
|
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
|
+
}
|
|
40623
40741
|
const clips = original.value.clipPaths;
|
|
40624
40742
|
let clipMask = clips && clips === cachedClips ? cachedClipMask : void 0;
|
|
40625
40743
|
if (clips && !clipMask) {
|
|
@@ -40633,6 +40751,19 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40633
40751
|
cachedClips = clips;
|
|
40634
40752
|
cachedClipMask = clipMask;
|
|
40635
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
|
+
}
|
|
40636
40767
|
const imageClips = original.value.clipImages;
|
|
40637
40768
|
if (imageClips) {
|
|
40638
40769
|
let imageMask = imageClipMasks.get(imageClips);
|
|
@@ -40814,6 +40945,27 @@ function renderDisplayListToPng(displayList, options = {}) {
|
|
|
40814
40945
|
const bmp = renderDisplayListToBitmap(displayList, options);
|
|
40815
40946
|
return encodeRgbaToPng(bmp.width, bmp.height, bmp.data);
|
|
40816
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
|
+
}
|
|
40817
40969
|
function escapeXmlText(str) {
|
|
40818
40970
|
let valid = "";
|
|
40819
40971
|
for (const char of str) {
|
|
@@ -40875,44 +41027,74 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
40875
41027
|
parts.push(`<g transform="matrix(${a} ${b} ${-c} ${-d} ${e + c * displayList.height} ${f + d * displayList.height})">`);
|
|
40876
41028
|
}
|
|
40877
41029
|
let clipId = 0;
|
|
40878
|
-
|
|
40879
|
-
|
|
40880
|
-
const
|
|
40881
|
-
|
|
40882
|
-
|
|
40883
|
-
|
|
40884
|
-
const
|
|
40885
|
-
const
|
|
40886
|
-
|
|
40887
|
-
|
|
40888
|
-
|
|
40889
|
-
|
|
40890
|
-
|
|
40891
|
-
|
|
40892
|
-
|
|
40893
|
-
|
|
40894
|
-
|
|
40895
|
-
|
|
40896
|
-
|
|
40897
|
-
|
|
40898
|
-
|
|
40899
|
-
|
|
40900
|
-
|
|
40901
|
-
|
|
40902
|
-
|
|
40903
|
-
|
|
40904
|
-
|
|
40905
|
-
|
|
40906
|
-
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
40907
|
-
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
40908
|
-
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
40909
|
-
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})">`);
|
|
40910
41058
|
}
|
|
40911
|
-
|
|
40912
|
-
|
|
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>");
|
|
40913
41095
|
}
|
|
40914
|
-
|
|
40915
|
-
|
|
41096
|
+
};
|
|
41097
|
+
appendOperations(paintOperations(displayList));
|
|
40916
41098
|
if (displayList.rotation) parts.push("</g>");
|
|
40917
41099
|
parts.push("</svg>\n");
|
|
40918
41100
|
return parts.join("\n");
|