@poe-platform/safe-bash 0.1.762 → 0.1.764
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 +454 -208
- package/dist/image-ast/index.js +454 -208
- package/dist/pdf-ast/ast.d.ts +23 -0
- package/dist/pdf-ast/index.js +543 -244
- package/dist/safe-bash/chunks/{chunk-CRQDMBQA.js → chunk-FSH7QRIC.js} +10 -1
- package/dist/safe-bash/command-chunks/{chunk-D4GXXV65.js → chunk-B7YLGJRF.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-P3Q2QSCA.js → chunk-G3IIEU2N.js} +457 -208
- package/dist/safe-bash/command-chunks/{chunk-F7MJRXQ2.js → chunk-RDPJGIQF.js} +1 -1
- package/dist/safe-bash/commands/python/index.browser.js +1 -1
- package/dist/safe-bash/commands/python/llm-module.js +3 -1
- package/dist/safe-bash/commands/python/shell-module.js +7 -0
- package/dist/safe-bash/core.browser.js +33 -13
- package/dist/safe-bash/shell/runtime.js +44 -12
- 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 +7476 -7338
- 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 +454 -208
- package/dist/safe-bash-command-pdfinfo/index.js +541 -244
- package/dist/safe-bash-command-pdftk/index.js +454 -208
- package/dist/safe-bash-command-pdftoppm/index.js +541 -244
- package/dist/safe-bash-command-pdftotext/index.js +454 -208
- package/dist/safe-bash-command-qpdf/index.js +454 -208
- 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 +514 -208
- package/dist/safe-bash-command-wkhtmltopdf/index.js +455 -208
- package/dist/safe-playwright-cloudflare/browser-snapshot-labels.d.ts +14 -0
- package/dist/safe-playwright-cloudflare/browser-snapshot-labels.js +62 -0
- package/dist/safe-playwright-cloudflare/browser-snapshot-scheduler.js +8 -1
- package/package.json +2 -2
- package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +27 -0
|
@@ -35762,14 +35762,18 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
35762
35762
|
const paths = [];
|
|
35763
35763
|
const images = [];
|
|
35764
35764
|
const operations = [];
|
|
35765
|
+
let capturedOperations;
|
|
35766
|
+
let insideSoftMask = false;
|
|
35765
35767
|
const emit = (operation) => {
|
|
35766
|
-
const { clipPaths, clipImages } = curState();
|
|
35767
|
-
if (clipPaths || clipImages) operation = { ...operation, value: {
|
|
35768
|
+
const { clipPaths, clipImages, softMask } = curState();
|
|
35769
|
+
if (clipPaths || clipImages || softMask) operation = { ...operation, value: {
|
|
35768
35770
|
...operation.value,
|
|
35769
35771
|
...clipPaths ? { clipPaths } : {},
|
|
35770
|
-
...clipImages ? { clipImages } : {}
|
|
35772
|
+
...clipImages ? { clipImages } : {},
|
|
35773
|
+
...softMask ? { softMask } : {}
|
|
35771
35774
|
} };
|
|
35772
|
-
operations.push(operation);
|
|
35775
|
+
(capturedOperations ?? operations).push(operation);
|
|
35776
|
+
if (insideSoftMask) return;
|
|
35773
35777
|
switch (operation.kind) {
|
|
35774
35778
|
case "path":
|
|
35775
35779
|
paths.push(operation.value);
|
|
@@ -35875,7 +35879,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
35875
35879
|
);
|
|
35876
35880
|
return { r: kClamp(r), g: kClamp(g), b: kClamp(b) };
|
|
35877
35881
|
};
|
|
35878
|
-
const applyStateOperator = (st, operator, ops, activeResources) => {
|
|
35882
|
+
const applyStateOperator = (st, operator, ops, activeResources, activeFonts, depth) => {
|
|
35879
35883
|
const num = (i, fb = 0) => ops[i]?.kind === "number" ? ops[i].value : fb;
|
|
35880
35884
|
if (operator === "cm") {
|
|
35881
35885
|
const m = [num(0, 1), num(1, 0), num(2, 0), num(3, 1), num(4, 0), num(5, 0)];
|
|
@@ -35958,6 +35962,46 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
35958
35962
|
const extDict = params.cosDoc.resolveDict(dictGet(activeResources, "ExtGState"));
|
|
35959
35963
|
const gsDict = extDict ? params.cosDoc.resolveDict(dictGet(extDict, ops[0].decoded)) : void 0;
|
|
35960
35964
|
if (gsDict) {
|
|
35965
|
+
const mask = params.cosDoc.resolve(dictGet(gsDict, "SMask"));
|
|
35966
|
+
if (mask?.kind === "name" && mask.decoded === "None") {
|
|
35967
|
+
st.softMask = void 0;
|
|
35968
|
+
} else if (mask?.kind === "dict") {
|
|
35969
|
+
const subtype = params.cosDoc.resolve(dictGet(mask, "S"));
|
|
35970
|
+
const form = params.cosDoc.resolve(dictGet(mask, "G"));
|
|
35971
|
+
if (form?.kind === "stream" && subtype?.kind === "name" && (subtype.decoded === "Alpha" || subtype.decoded === "Luminosity")) {
|
|
35972
|
+
if (depth >= 8) throw new PdfError("E_LIMIT", "Soft-mask nesting exceeds the form depth limit");
|
|
35973
|
+
const parentOperations = capturedOperations;
|
|
35974
|
+
const parentInsideSoftMask = insideSoftMask;
|
|
35975
|
+
const savedTextState = { pendingTextClip, hasTextClip, activeTm, activeTlm };
|
|
35976
|
+
const captured = [];
|
|
35977
|
+
capturedOperations = captured;
|
|
35978
|
+
insideSoftMask = true;
|
|
35979
|
+
const maskState = { ...st, softMask: void 0, fillAlpha: 1, strokeAlpha: 1, blendMode: "Normal" };
|
|
35980
|
+
delete maskState.clipPaths;
|
|
35981
|
+
delete maskState.clipImages;
|
|
35982
|
+
delete maskState.clipRect;
|
|
35983
|
+
stateStack.push(maskState);
|
|
35984
|
+
try {
|
|
35985
|
+
paintForm(form, activeResources, activeFonts, depth, void 0, void 0, true);
|
|
35986
|
+
} finally {
|
|
35987
|
+
stateStack.pop();
|
|
35988
|
+
capturedOperations = parentOperations;
|
|
35989
|
+
insideSoftMask = parentInsideSoftMask;
|
|
35990
|
+
({ pendingTextClip, hasTextClip, activeTm, activeTlm } = savedTextState);
|
|
35991
|
+
}
|
|
35992
|
+
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
35993
|
+
const colorSpace = group ? dictGet(group, "CS") : void 0;
|
|
35994
|
+
const bc = params.cosDoc.resolveArray(dictGet(mask, "BC"));
|
|
35995
|
+
const components = bc?.items.map((item) => {
|
|
35996
|
+
const value = params.cosDoc.resolve(item);
|
|
35997
|
+
return value?.kind === "number" ? value.value : 0;
|
|
35998
|
+
});
|
|
35999
|
+
const [r, g, b] = components ? convertColorSpaceComponentsToRgb(params.cosDoc, colorSpace, "DeviceRGB", components, activeResources) : [0, 0, 0];
|
|
36000
|
+
const transfer = params.cosDoc.resolve(dictGet(mask, "TR"));
|
|
36001
|
+
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;
|
|
36002
|
+
st.softMask = { subtype: subtype.decoded, operations: captured, backdrop: { r, g, b }, transferMap };
|
|
36003
|
+
}
|
|
36004
|
+
}
|
|
35961
36005
|
const bmNode = params.cosDoc.resolve(dictGet(gsDict, "BM"));
|
|
35962
36006
|
if (bmNode?.kind === "name") {
|
|
35963
36007
|
st.blendMode = bmNode.decoded === "Compatible" ? "Normal" : bmNode.decoded;
|
|
@@ -36044,6 +36088,84 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36044
36088
|
] }], void 0, void 0, resources, activeFonts, depth);
|
|
36045
36089
|
stateStack.pop();
|
|
36046
36090
|
};
|
|
36091
|
+
const paintForm = (form, activeResources, activeFonts, depth, mcid, actualText, maskGroup = false) => {
|
|
36092
|
+
const st = curState();
|
|
36093
|
+
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
36094
|
+
const groupType = group ? params.cosDoc.resolve(dictGet(group, "S")) : void 0;
|
|
36095
|
+
const isolated = group ? params.cosDoc.resolve(dictGet(group, "I")) : void 0;
|
|
36096
|
+
const isolate = !maskGroup && groupType?.kind === "name" && groupType.decoded === "Transparency" && isolated?.kind === "boolean" && isolated.value;
|
|
36097
|
+
const formStreamBytes = params.cosDoc.decodeStream(form);
|
|
36098
|
+
const formNodes = parseContentStream(formStreamBytes);
|
|
36099
|
+
const formResDict = params.cosDoc.resolveDict(dictGet(form.dict, "Resources")) ?? activeResources;
|
|
36100
|
+
const formFonts = new Map(activeFonts);
|
|
36101
|
+
for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
|
|
36102
|
+
formFonts.set(k, v);
|
|
36103
|
+
}
|
|
36104
|
+
let nextCtm = [...st.ctm];
|
|
36105
|
+
const matArr = params.cosDoc.resolveArray(dictGet(form.dict, "Matrix"));
|
|
36106
|
+
if (matArr && matArr.items.length >= 6) {
|
|
36107
|
+
const mn = (idx, fb = 0) => {
|
|
36108
|
+
const resolved = params.cosDoc.resolve(matArr.items[idx]);
|
|
36109
|
+
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36110
|
+
};
|
|
36111
|
+
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36112
|
+
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36113
|
+
}
|
|
36114
|
+
let nextClip = !isolate && st.clipRect ? [...st.clipRect] : void 0;
|
|
36115
|
+
let nextClipPaths = isolate ? void 0 : st.clipPaths;
|
|
36116
|
+
const bboxArr = params.cosDoc.resolveArray(dictGet(form.dict, "BBox"));
|
|
36117
|
+
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36118
|
+
const bn = (idx, fb = 0) => {
|
|
36119
|
+
const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
|
|
36120
|
+
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36121
|
+
};
|
|
36122
|
+
const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
|
|
36123
|
+
const pts = [
|
|
36124
|
+
transformPoint(nextCtm, bx0, by0),
|
|
36125
|
+
transformPoint(nextCtm, bx1, by0),
|
|
36126
|
+
transformPoint(nextCtm, bx1, by1),
|
|
36127
|
+
transformPoint(nextCtm, bx0, by1)
|
|
36128
|
+
];
|
|
36129
|
+
nextClipPaths = [...nextClipPaths ?? [], [
|
|
36130
|
+
...pts.map(([x, y], index) => ({ kind: index === 0 ? "move" : "line", x, y })),
|
|
36131
|
+
{ kind: "close" }
|
|
36132
|
+
]];
|
|
36133
|
+
const fMinX = Math.min(...pts.map((p) => p[0]));
|
|
36134
|
+
const fMinY = Math.min(...pts.map((p) => p[1]));
|
|
36135
|
+
const fMaxX = Math.max(...pts.map((p) => p[0]));
|
|
36136
|
+
const fMaxY = Math.max(...pts.map((p) => p[1]));
|
|
36137
|
+
if (fMaxX > fMinX && fMaxY > fMinY) {
|
|
36138
|
+
nextClip = nextClip ? [
|
|
36139
|
+
Math.max(nextClip[0], fMinX),
|
|
36140
|
+
Math.max(nextClip[1], fMinY),
|
|
36141
|
+
Math.min(nextClip[2], fMaxX),
|
|
36142
|
+
Math.min(nextClip[3], fMaxY)
|
|
36143
|
+
] : [fMinX, fMinY, fMaxX, fMaxY];
|
|
36144
|
+
}
|
|
36145
|
+
}
|
|
36146
|
+
const parentOperations = capturedOperations;
|
|
36147
|
+
const children = [];
|
|
36148
|
+
const nextState = { ...st, ctm: nextCtm };
|
|
36149
|
+
if (isolate) {
|
|
36150
|
+
capturedOperations = children;
|
|
36151
|
+
nextState.fillAlpha = nextState.strokeAlpha = 1;
|
|
36152
|
+
nextState.blendMode = "Normal";
|
|
36153
|
+
nextState.softMask = void 0;
|
|
36154
|
+
delete nextState.clipImages;
|
|
36155
|
+
delete nextState.clipPaths;
|
|
36156
|
+
delete nextState.clipRect;
|
|
36157
|
+
}
|
|
36158
|
+
if (nextClip) nextState.clipRect = nextClip;
|
|
36159
|
+
if (nextClipPaths) nextState.clipPaths = nextClipPaths;
|
|
36160
|
+
stateStack.push(nextState);
|
|
36161
|
+
try {
|
|
36162
|
+
walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
|
|
36163
|
+
} finally {
|
|
36164
|
+
stateStack.pop();
|
|
36165
|
+
capturedOperations = parentOperations;
|
|
36166
|
+
}
|
|
36167
|
+
if (isolate) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
|
|
36168
|
+
};
|
|
36047
36169
|
const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
|
|
36048
36170
|
for (const node of nodes) {
|
|
36049
36171
|
switch (node.kind) {
|
|
@@ -36088,7 +36210,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36088
36210
|
break;
|
|
36089
36211
|
}
|
|
36090
36212
|
case "state-op": {
|
|
36091
|
-
applyStateOperator(curState(), node.operator, node.operands, activeResources);
|
|
36213
|
+
applyStateOperator(curState(), node.operator, node.operands, activeResources, activeFonts, depth);
|
|
36092
36214
|
break;
|
|
36093
36215
|
}
|
|
36094
36216
|
case "path-op": {
|
|
@@ -36374,53 +36496,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36374
36496
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
36375
36497
|
}, patternMask, activeResources, activeFonts, depth);
|
|
36376
36498
|
} else if (sub === "Form" && depth < 8) {
|
|
36377
|
-
|
|
36378
|
-
const formNodes = parseContentStream(formStreamBytes);
|
|
36379
|
-
const formResDict = params.cosDoc.resolveDict(dictGet(xobjNode.dict, "Resources")) ?? activeResources;
|
|
36380
|
-
const formFonts = new Map(activeFonts);
|
|
36381
|
-
for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
|
|
36382
|
-
formFonts.set(k, v);
|
|
36383
|
-
}
|
|
36384
|
-
let nextCtm = [...st.ctm];
|
|
36385
|
-
const matArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "Matrix"));
|
|
36386
|
-
if (matArr && matArr.items.length >= 6) {
|
|
36387
|
-
const mn = (idx, fb = 0) => {
|
|
36388
|
-
const resolved = params.cosDoc.resolve(matArr.items[idx]);
|
|
36389
|
-
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36390
|
-
};
|
|
36391
|
-
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36392
|
-
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36393
|
-
}
|
|
36394
|
-
let nextClip = st.clipRect ? [...st.clipRect] : void 0;
|
|
36395
|
-
const bboxArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "BBox"));
|
|
36396
|
-
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36397
|
-
const bn = (idx, fb = 0) => {
|
|
36398
|
-
const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
|
|
36399
|
-
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36400
|
-
};
|
|
36401
|
-
const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
|
|
36402
|
-
const pts = [
|
|
36403
|
-
transformPoint(nextCtm, bx0, by0),
|
|
36404
|
-
transformPoint(nextCtm, bx1, by0),
|
|
36405
|
-
transformPoint(nextCtm, bx0, by1),
|
|
36406
|
-
transformPoint(nextCtm, bx1, by1)
|
|
36407
|
-
];
|
|
36408
|
-
const fMinX = Math.min(...pts.map((p) => p[0]));
|
|
36409
|
-
const fMinY = Math.min(...pts.map((p) => p[1]));
|
|
36410
|
-
const fMaxX = Math.max(...pts.map((p) => p[0]));
|
|
36411
|
-
const fMaxY = Math.max(...pts.map((p) => p[1]));
|
|
36412
|
-
if (fMaxX > fMinX && fMaxY > fMinY) {
|
|
36413
|
-
nextClip = nextClip ? [
|
|
36414
|
-
Math.max(nextClip[0], fMinX),
|
|
36415
|
-
Math.max(nextClip[1], fMinY),
|
|
36416
|
-
Math.min(nextClip[2], fMaxX),
|
|
36417
|
-
Math.min(nextClip[3], fMaxY)
|
|
36418
|
-
] : [fMinX, fMinY, fMaxX, fMaxY];
|
|
36419
|
-
}
|
|
36420
|
-
}
|
|
36421
|
-
stateStack.push({ ...st, ctm: nextCtm, ...nextClip ? { clipRect: nextClip } : {} });
|
|
36422
|
-
walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
|
|
36423
|
-
if (stateStack.length > 1) stateStack.pop();
|
|
36499
|
+
paintForm(xobjNode, activeResources, activeFonts, depth, mcid, actualText);
|
|
36424
36500
|
}
|
|
36425
36501
|
}
|
|
36426
36502
|
}
|
|
@@ -36639,7 +36715,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36639
36715
|
st.textRenderMode = cmd.mode;
|
|
36640
36716
|
break;
|
|
36641
36717
|
case "state-op":
|
|
36642
|
-
applyStateOperator(st, cmd.operator, cmd.operands, activeResources);
|
|
36718
|
+
applyStateOperator(st, cmd.operator, cmd.operands, activeResources, activeFonts, depth);
|
|
36643
36719
|
break;
|
|
36644
36720
|
case "show-text":
|
|
36645
36721
|
emitTokenBytes(cmd.token.bytes);
|
|
@@ -38943,6 +39019,184 @@ function downscaleImage(image, widthScale, heightScale) {
|
|
|
38943
39019
|
}
|
|
38944
39020
|
return image;
|
|
38945
39021
|
}
|
|
39022
|
+
var MAX_STROKE_VERTICES = 1e6;
|
|
39023
|
+
function dashSubpath(path, pattern, phase) {
|
|
39024
|
+
const cycle = pattern.reduce((sum, value) => sum + value, 0);
|
|
39025
|
+
if (!(cycle > 0)) return [path];
|
|
39026
|
+
let offset = (phase % cycle + cycle) % cycle, index = 0;
|
|
39027
|
+
while (offset > 0) {
|
|
39028
|
+
if (offset < pattern[index]) break;
|
|
39029
|
+
offset -= pattern[index];
|
|
39030
|
+
index = (index + 1) % pattern.length;
|
|
39031
|
+
}
|
|
39032
|
+
let remaining = pattern[index] - offset;
|
|
39033
|
+
const points = path.closed ? [...path.points, path.points[0]] : path.points;
|
|
39034
|
+
const result = [];
|
|
39035
|
+
let current = [];
|
|
39036
|
+
let steps = 0;
|
|
39037
|
+
const flush = () => {
|
|
39038
|
+
if (current.length) result.push({ points: current, closed: false });
|
|
39039
|
+
current = [];
|
|
39040
|
+
};
|
|
39041
|
+
const advance = (point) => {
|
|
39042
|
+
while (remaining <= 0) {
|
|
39043
|
+
if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39044
|
+
if (index % 2 === 0) {
|
|
39045
|
+
if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
|
|
39046
|
+
flush();
|
|
39047
|
+
}
|
|
39048
|
+
index = (index + 1) % pattern.length;
|
|
39049
|
+
remaining = pattern[index];
|
|
39050
|
+
}
|
|
39051
|
+
};
|
|
39052
|
+
for (let i = 1; i < points.length; i++) {
|
|
39053
|
+
const start = points[i - 1], end = points[i];
|
|
39054
|
+
const dx = end[0] - start[0], dy = end[1] - start[1];
|
|
39055
|
+
const length = Math.hypot(dx, dy);
|
|
39056
|
+
if (!Number.isFinite(length) || length / cycle * pattern.length > MAX_STROKE_VERTICES) {
|
|
39057
|
+
throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39058
|
+
}
|
|
39059
|
+
let distance = 0;
|
|
39060
|
+
while (distance < length) {
|
|
39061
|
+
const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
|
|
39062
|
+
advance(point);
|
|
39063
|
+
const step = Math.min(remaining, length - distance);
|
|
39064
|
+
if (distance + step === distance || ++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39065
|
+
distance += step;
|
|
39066
|
+
remaining -= step;
|
|
39067
|
+
if (index % 2 === 0) {
|
|
39068
|
+
if (!current.length) current.push(point);
|
|
39069
|
+
current.push([start[0] + dx * distance / length, start[1] + dy * distance / length]);
|
|
39070
|
+
}
|
|
39071
|
+
}
|
|
39072
|
+
}
|
|
39073
|
+
flush();
|
|
39074
|
+
if (path.closed && result.length) {
|
|
39075
|
+
const first = result[0], last = result[result.length - 1];
|
|
39076
|
+
const start = path.points[0];
|
|
39077
|
+
const firstPoint = first.points[0], lastPoint = last.points[last.points.length - 1];
|
|
39078
|
+
if (firstPoint[0] === start[0] && firstPoint[1] === start[1] && lastPoint[0] === start[0] && lastPoint[1] === start[1]) {
|
|
39079
|
+
if (first === last) result[0] = { points: first.points, closed: true };
|
|
39080
|
+
else {
|
|
39081
|
+
result[0] = { points: [...last.points, ...first.points.slice(1)], closed: false };
|
|
39082
|
+
result.pop();
|
|
39083
|
+
}
|
|
39084
|
+
}
|
|
39085
|
+
}
|
|
39086
|
+
return result;
|
|
39087
|
+
}
|
|
39088
|
+
function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], dashPhase = 0) {
|
|
39089
|
+
const half = width / 2;
|
|
39090
|
+
const contours = [];
|
|
39091
|
+
const pattern = dashArray.length % 2 ? [...dashArray, ...dashArray] : dashArray;
|
|
39092
|
+
let count = 0;
|
|
39093
|
+
let contour = [];
|
|
39094
|
+
const add = (x, y) => {
|
|
39095
|
+
if (++count > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke outline exceeds the vertex limit");
|
|
39096
|
+
contour.push([x, y]);
|
|
39097
|
+
};
|
|
39098
|
+
const arc = (point, dx1, dy1, dx2, dy2) => {
|
|
39099
|
+
let a1 = Math.atan2(dy1, dx1), a2 = Math.atan2(dy2, dx2);
|
|
39100
|
+
const ccw = a1 - a2 > 0 && a1 - a2 < Math.PI;
|
|
39101
|
+
const step = Math.acos(half / (half + 0.125)) * 2;
|
|
39102
|
+
add(point[0] + dx1, point[1] + dy1);
|
|
39103
|
+
if (step > 0) {
|
|
39104
|
+
if (!ccw) {
|
|
39105
|
+
if (a1 > a2) a2 += 2 * Math.PI;
|
|
39106
|
+
a2 -= step / 4;
|
|
39107
|
+
if ((a2 - a1) / step > MAX_STROKE_VERTICES - count) throw new PdfError("E_LIMIT", "Stroke arc exceeds the vertex limit");
|
|
39108
|
+
for (a1 += step; a1 < a2; a1 += step) add(point[0] + half * Math.cos(a1), point[1] + half * Math.sin(a1));
|
|
39109
|
+
} else {
|
|
39110
|
+
if (a1 < a2) a2 -= 2 * Math.PI;
|
|
39111
|
+
a2 += step / 4;
|
|
39112
|
+
if ((a1 - a2) / step > MAX_STROKE_VERTICES - count) throw new PdfError("E_LIMIT", "Stroke arc exceeds the vertex limit");
|
|
39113
|
+
for (a1 -= step; a1 > a2; a1 -= step) add(point[0] + half * Math.cos(a1), point[1] + half * Math.sin(a1));
|
|
39114
|
+
}
|
|
39115
|
+
}
|
|
39116
|
+
add(point[0] + dx2, point[1] + dy2);
|
|
39117
|
+
};
|
|
39118
|
+
const addCap = (point, next) => {
|
|
39119
|
+
const length = Math.hypot(next[0] - point[0], next[1] - point[1]);
|
|
39120
|
+
const dx = half * (next[1] - point[1]) / length;
|
|
39121
|
+
const dy = half * (next[0] - point[0]) / length;
|
|
39122
|
+
if (cap !== 1) {
|
|
39123
|
+
const sx = cap === 2 ? dy : 0, sy = cap === 2 ? dx : 0;
|
|
39124
|
+
add(point[0] - dx - sx, point[1] + dy - sy);
|
|
39125
|
+
add(point[0] + dx - sx, point[1] - dy - sy);
|
|
39126
|
+
} else {
|
|
39127
|
+
const angle = Math.atan2(dy, -dx);
|
|
39128
|
+
const step = Math.max(1e-3, Math.acos(half / (half + 0.125)) * 2);
|
|
39129
|
+
add(point[0] - dx, point[1] + dy);
|
|
39130
|
+
for (let a = angle + step; a < angle + Math.PI - step / 4; a += step) add(point[0] + half * Math.cos(a), point[1] + half * Math.sin(a));
|
|
39131
|
+
add(point[0] + dx, point[1] - dy);
|
|
39132
|
+
}
|
|
39133
|
+
};
|
|
39134
|
+
const addJoin = (prev, point, next) => {
|
|
39135
|
+
const len1 = Math.hypot(point[0] - prev[0], point[1] - prev[1]);
|
|
39136
|
+
const len2 = Math.hypot(next[0] - point[0], next[1] - point[1]);
|
|
39137
|
+
const dx1 = half * (point[1] - prev[1]) / len1, dy1 = half * (point[0] - prev[0]) / len1;
|
|
39138
|
+
const dx2 = half * (next[1] - point[1]) / len2, dy2 = half * (next[0] - point[0]) / len2;
|
|
39139
|
+
const inner = (next[0] - point[0]) * (point[1] - prev[1]) - (next[1] - point[1]) * (point[0] - prev[0]) > 0;
|
|
39140
|
+
if (!inner && join === 1) {
|
|
39141
|
+
arc(point, dx1, -dy1, dx2, -dy2);
|
|
39142
|
+
return;
|
|
39143
|
+
}
|
|
39144
|
+
if (inner || join === 0) {
|
|
39145
|
+
const ax = prev[0] + dx1, ay = prev[1] - dy1;
|
|
39146
|
+
const bx = point[0] + dx1, by = point[1] - dy1;
|
|
39147
|
+
const cx = point[0] + dx2, cy = point[1] - dy2;
|
|
39148
|
+
const dx = next[0] + dx2, dy = next[1] - dy2;
|
|
39149
|
+
const den = (bx - ax) * (dy - cy) - (by - ay) * (dx - cx);
|
|
39150
|
+
if (Math.abs(den) >= 1e-30) {
|
|
39151
|
+
const t = ((ay - cy) * (dx - cx) - (ax - cx) * (dy - cy)) / den;
|
|
39152
|
+
const x = ax + (bx - ax) * t, y = ay + (by - ay) * t;
|
|
39153
|
+
if (Math.hypot(x - point[0], y - point[1]) <= half * (inner ? 1.01 : miterLimit)) {
|
|
39154
|
+
add(x, y);
|
|
39155
|
+
return;
|
|
39156
|
+
}
|
|
39157
|
+
} else if ((bx - prev[0]) * dy1 - (prev[1] - by) * dx1 < 0 !== (bx - next[0]) * dy1 - (next[1] - by) * dx1 < 0) {
|
|
39158
|
+
add(bx, by);
|
|
39159
|
+
return;
|
|
39160
|
+
}
|
|
39161
|
+
}
|
|
39162
|
+
add(point[0] + dx1, point[1] - dy1);
|
|
39163
|
+
add(point[0] + dx2, point[1] - dy2);
|
|
39164
|
+
};
|
|
39165
|
+
for (const path of paths) {
|
|
39166
|
+
for (const subpath of pattern.length ? dashSubpath(path, pattern, dashPhase) : [path]) {
|
|
39167
|
+
const points = [];
|
|
39168
|
+
for (const point of subpath.points) {
|
|
39169
|
+
const prev = points[points.length - 1];
|
|
39170
|
+
if (!prev || Math.hypot(prev[0] - point[0], prev[1] - point[1]) > 1e-14) points.push(point);
|
|
39171
|
+
}
|
|
39172
|
+
let closed = subpath.closed;
|
|
39173
|
+
if (closed && points.length > 1 && Math.hypot(points[0][0] - points[points.length - 1][0], points[0][1] - points[points.length - 1][1]) <= 1e-14) points.pop();
|
|
39174
|
+
if (points.length < 3) closed = false;
|
|
39175
|
+
if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
|
|
39176
|
+
contour = [];
|
|
39177
|
+
const [x, y] = points[0];
|
|
39178
|
+
addCap([x, y], [x + 1, y]);
|
|
39179
|
+
addCap([x, y], [x - 1, y]);
|
|
39180
|
+
contours.push(contour);
|
|
39181
|
+
} else if (points.length >= 2) {
|
|
39182
|
+
contour = [];
|
|
39183
|
+
if (!closed) addCap(points[0], points[1]);
|
|
39184
|
+
for (let i = closed ? 0 : 1; i < points.length - (closed ? 0 : 1); i++) {
|
|
39185
|
+
addJoin(points[(i + points.length - 1) % points.length], points[i], points[(i + 1) % points.length]);
|
|
39186
|
+
}
|
|
39187
|
+
if (closed) {
|
|
39188
|
+
contours.push(contour);
|
|
39189
|
+
contour = [];
|
|
39190
|
+
} else addCap(points[points.length - 1], points[points.length - 2]);
|
|
39191
|
+
for (let i = points.length - (closed ? 1 : 2); i >= (closed ? 0 : 1); i--) {
|
|
39192
|
+
addJoin(points[(i + 1) % points.length], points[i], points[(i + points.length - 1) % points.length]);
|
|
39193
|
+
}
|
|
39194
|
+
contours.push(contour);
|
|
39195
|
+
}
|
|
39196
|
+
}
|
|
39197
|
+
}
|
|
39198
|
+
return contours;
|
|
39199
|
+
}
|
|
38946
39200
|
function encodePng(bitmap) {
|
|
38947
39201
|
return encodeRgbaToPng(bitmap.width, bitmap.height, bitmap.data);
|
|
38948
39202
|
}
|
|
@@ -40033,111 +40287,60 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
|
|
|
40033
40287
|
rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
|
|
40034
40288
|
rgba[idx + 3] = Math.round(outA * 255);
|
|
40035
40289
|
}
|
|
40036
|
-
function
|
|
40037
|
-
const
|
|
40038
|
-
|
|
40039
|
-
|
|
40040
|
-
const lenSq = dx * dx + dy * dy;
|
|
40041
|
-
const segLen = Math.sqrt(lenSq);
|
|
40042
|
-
const pad = lineCap === 2 ? halfW + 2 : halfW + 1;
|
|
40043
|
-
const minX = Math.max(0, Math.floor(Math.min(x0, x1) - pad));
|
|
40044
|
-
const maxX = Math.min(width - 1, Math.ceil(Math.max(x0, x1) + pad));
|
|
40045
|
-
const minY = Math.max(0, Math.floor(Math.min(y0, y1) - pad));
|
|
40046
|
-
const maxY = Math.min(height - 1, Math.ceil(Math.max(y0, y1) + pad));
|
|
40047
|
-
for (let py = minY; py <= maxY; py++) {
|
|
40048
|
-
for (let px = minX; px <= maxX; px++) {
|
|
40049
|
-
const cx = px + 0.5;
|
|
40050
|
-
const cy = py + 0.5;
|
|
40051
|
-
if (segLen > 1e-6 && (lineCap === 0 || lineCap === 2)) {
|
|
40052
|
-
const ux = dx / segLen;
|
|
40053
|
-
const uy = dy / segLen;
|
|
40054
|
-
const along = (cx - x0) * ux + (cy - y0) * uy;
|
|
40055
|
-
const perp = Math.abs(-(cx - x0) * uy + (cy - y0) * ux);
|
|
40056
|
-
const minAlong = lineCap === 2 ? -halfW : 0;
|
|
40057
|
-
const maxAlong = lineCap === 2 ? segLen + halfW : segLen;
|
|
40058
|
-
const overAlong = along < minAlong ? minAlong - along : along > maxAlong ? along - maxAlong : 0;
|
|
40059
|
-
const dist2 = overAlong > 0 ? Math.max(perp, halfW + overAlong) : perp;
|
|
40060
|
-
if (dist2 <= halfW + 0.75) {
|
|
40061
|
-
const cov = antialias ? Math.max(0, Math.min(1, halfW + 0.5 - dist2)) : dist2 <= halfW + 0.25 ? 1 : 0;
|
|
40062
|
-
blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask);
|
|
40063
|
-
}
|
|
40064
|
-
continue;
|
|
40065
|
-
}
|
|
40066
|
-
let t = lenSq > 1e-6 ? ((cx - x0) * dx + (cy - y0) * dy) / lenSq : 0;
|
|
40067
|
-
t = Math.max(0, Math.min(1, t));
|
|
40068
|
-
const projX = x0 + t * dx;
|
|
40069
|
-
const projY = y0 + t * dy;
|
|
40070
|
-
const dist = Math.hypot(cx - projX, cy - projY);
|
|
40071
|
-
if (dist <= halfW + 0.75) {
|
|
40072
|
-
const cov = antialias ? Math.max(0, Math.min(1, halfW + 0.5 - dist)) : dist <= halfW + 0.25 ? 1 : 0;
|
|
40073
|
-
blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask);
|
|
40074
|
-
}
|
|
40075
|
-
}
|
|
40076
|
-
}
|
|
40077
|
-
}
|
|
40078
|
-
function segmentsToScreenEdges(segments, pageHeight, scale, closeSubpaths = false) {
|
|
40079
|
-
const edges = [];
|
|
40080
|
-
let curX = 0;
|
|
40081
|
-
let curY = 0;
|
|
40082
|
-
let startX = 0;
|
|
40083
|
-
let startY = 0;
|
|
40084
|
-
let hasOpenSubpath = false;
|
|
40290
|
+
function segmentsToScreenPaths(segments, pageHeight, scale) {
|
|
40291
|
+
const paths = [];
|
|
40292
|
+
let points = [];
|
|
40293
|
+
let current = [0, 0];
|
|
40085
40294
|
const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
|
|
40086
|
-
for (const
|
|
40087
|
-
if (
|
|
40088
|
-
if (
|
|
40089
|
-
|
|
40090
|
-
|
|
40091
|
-
|
|
40092
|
-
|
|
40093
|
-
|
|
40094
|
-
|
|
40095
|
-
} else if (
|
|
40096
|
-
|
|
40097
|
-
|
|
40098
|
-
|
|
40099
|
-
|
|
40100
|
-
|
|
40101
|
-
|
|
40102
|
-
|
|
40103
|
-
|
|
40104
|
-
|
|
40105
|
-
|
|
40106
|
-
|
|
40107
|
-
|
|
40108
|
-
|
|
40109
|
-
|
|
40110
|
-
|
|
40111
|
-
|
|
40112
|
-
|
|
40113
|
-
|
|
40114
|
-
|
|
40115
|
-
|
|
40116
|
-
|
|
40117
|
-
|
|
40118
|
-
|
|
40119
|
-
|
|
40120
|
-
|
|
40121
|
-
|
|
40122
|
-
|
|
40123
|
-
|
|
40124
|
-
|
|
40125
|
-
|
|
40126
|
-
|
|
40127
|
-
|
|
40128
|
-
const [
|
|
40129
|
-
|
|
40130
|
-
|
|
40131
|
-
|
|
40132
|
-
|
|
40133
|
-
|
|
40134
|
-
{ x0: rx0, y0: ry1, x1: rx0, y1: ry0 }
|
|
40135
|
-
);
|
|
40136
|
-
hasOpenSubpath = false;
|
|
40295
|
+
for (const segment of segments) {
|
|
40296
|
+
if (segment.kind === "move") {
|
|
40297
|
+
if (points.length) paths.push({ points, closed: false });
|
|
40298
|
+
current = toScreen(segment.x, segment.y);
|
|
40299
|
+
points = [current];
|
|
40300
|
+
} else if (segment.kind === "line") {
|
|
40301
|
+
if (!points.length) points = [current];
|
|
40302
|
+
current = toScreen(segment.x, segment.y);
|
|
40303
|
+
points.push(current);
|
|
40304
|
+
} else if (segment.kind === "cubic") {
|
|
40305
|
+
if (!points.length) points = [current];
|
|
40306
|
+
const a = toScreen(segment.x1, segment.y1), b = toScreen(segment.x2, segment.y2);
|
|
40307
|
+
const end = toScreen(segment.x, segment.y);
|
|
40308
|
+
const curve = flattenCubic(current[0], current[1], a[0], a[1], b[0], b[1], end[0], end[1]);
|
|
40309
|
+
for (let i = 1; i < curve.length; i++) points.push(curve[i]);
|
|
40310
|
+
current = end;
|
|
40311
|
+
} else if (segment.kind === "close") {
|
|
40312
|
+
if (points.length) {
|
|
40313
|
+
paths.push({ points, closed: true });
|
|
40314
|
+
current = points[0];
|
|
40315
|
+
points = [];
|
|
40316
|
+
}
|
|
40317
|
+
} else if (segment.kind === "rect") {
|
|
40318
|
+
if (points.length) paths.push({ points, closed: false });
|
|
40319
|
+
const first = toScreen(segment.x, segment.y);
|
|
40320
|
+
paths.push({ points: [
|
|
40321
|
+
first,
|
|
40322
|
+
toScreen(segment.x + segment.width, segment.y),
|
|
40323
|
+
toScreen(segment.x + segment.width, segment.y + segment.height),
|
|
40324
|
+
toScreen(segment.x, segment.y + segment.height)
|
|
40325
|
+
], closed: true });
|
|
40326
|
+
current = first;
|
|
40327
|
+
points = [];
|
|
40328
|
+
}
|
|
40329
|
+
}
|
|
40330
|
+
if (points.length) paths.push({ points, closed: false });
|
|
40331
|
+
return paths;
|
|
40332
|
+
}
|
|
40333
|
+
function pathsToEdges(paths, closeSubpaths = false) {
|
|
40334
|
+
const edges = [];
|
|
40335
|
+
for (const { points, closed } of paths) {
|
|
40336
|
+
for (let i = 1; i < points.length; i++) {
|
|
40337
|
+
const a = points[i - 1], b = points[i];
|
|
40338
|
+
edges.push({ x0: a[0], y0: a[1], x1: b[0], y1: b[1] });
|
|
40339
|
+
}
|
|
40340
|
+
if ((closed || closeSubpaths) && points.length > 1) {
|
|
40341
|
+
const a = points[points.length - 1], b = points[0];
|
|
40342
|
+
edges.push({ x0: a[0], y0: a[1], x1: b[0], y1: b[1] });
|
|
40137
40343
|
}
|
|
40138
|
-
}
|
|
40139
|
-
if (closeSubpaths && hasOpenSubpath && (curX !== startX || curY !== startY)) {
|
|
40140
|
-
edges.push({ x0: curX, y0: curY, x1: startX, y1: startY });
|
|
40141
40344
|
}
|
|
40142
40345
|
return edges;
|
|
40143
40346
|
}
|
|
@@ -40248,6 +40451,30 @@ function paintOperations(displayList) {
|
|
|
40248
40451
|
...displayList.glyphs.map((value) => ({ kind: "glyph", value }))
|
|
40249
40452
|
];
|
|
40250
40453
|
}
|
|
40454
|
+
function renderSoftMask(mask, displayList, scale) {
|
|
40455
|
+
const bitmap = renderDisplayListToBitmap({
|
|
40456
|
+
...displayList,
|
|
40457
|
+
rotation: 0,
|
|
40458
|
+
glyphs: [],
|
|
40459
|
+
paths: [],
|
|
40460
|
+
images: [],
|
|
40461
|
+
operations: mask.operations
|
|
40462
|
+
}, { scale, transparent: true });
|
|
40463
|
+
const { data } = bitmap;
|
|
40464
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
40465
|
+
let value = data[i + 3];
|
|
40466
|
+
if (mask.subtype === "Luminosity") {
|
|
40467
|
+
const alpha = value / 255;
|
|
40468
|
+
const r = Math.round(data[i] * alpha + mask.backdrop.r * 255 * (1 - alpha));
|
|
40469
|
+
const g = Math.round(data[i + 1] * alpha + mask.backdrop.g * 255 * (1 - alpha));
|
|
40470
|
+
const b = Math.round(data[i + 2] * alpha + mask.backdrop.b * 255 * (1 - alpha));
|
|
40471
|
+
value = Math.round(pdfLum(r, g, b));
|
|
40472
|
+
}
|
|
40473
|
+
data[i] = data[i + 1] = data[i + 2] = 0;
|
|
40474
|
+
data[i + 3] = mask.transferMap?.[value] ?? value;
|
|
40475
|
+
}
|
|
40476
|
+
return bitmap;
|
|
40477
|
+
}
|
|
40251
40478
|
function renderDisplayListToBitmap(displayList, options = {}) {
|
|
40252
40479
|
const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
|
|
40253
40480
|
const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
|
|
@@ -40271,10 +40498,28 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40271
40498
|
const aaTxt = options.antialiasText !== false;
|
|
40272
40499
|
let cachedClips;
|
|
40273
40500
|
let cachedClipMask;
|
|
40501
|
+
let cachedSoftMask;
|
|
40502
|
+
let cachedSoftMaskPixels;
|
|
40274
40503
|
const imageClipMasks = /* @__PURE__ */ new Map();
|
|
40275
40504
|
for (const original of paintOperations(displayList)) {
|
|
40276
40505
|
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
40277
|
-
|
|
40506
|
+
let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
40507
|
+
if (operation.kind === "group") {
|
|
40508
|
+
const group = operation.value;
|
|
40509
|
+
const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations: group.operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, transparent: true });
|
|
40510
|
+
for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
|
|
40511
|
+
operation = { kind: "image", value: {
|
|
40512
|
+
name: "TransparencyGroup",
|
|
40513
|
+
width: bitmap.width,
|
|
40514
|
+
height: bitmap.height,
|
|
40515
|
+
decodedRgba: bitmap.data,
|
|
40516
|
+
matrix: [bitmap.width / scale, 0, 0, bitmap.height / scale, 0, displayList.height - bitmap.height / scale],
|
|
40517
|
+
colorSpace: "DeviceRGB",
|
|
40518
|
+
bitsPerComponent: 8,
|
|
40519
|
+
blendMode: group.blendMode,
|
|
40520
|
+
clipRect: group.clipRect
|
|
40521
|
+
} };
|
|
40522
|
+
}
|
|
40278
40523
|
const clips = original.value.clipPaths;
|
|
40279
40524
|
let clipMask = clips && clips === cachedClips ? cachedClipMask : void 0;
|
|
40280
40525
|
if (clips && !clipMask) {
|
|
@@ -40282,12 +40527,25 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40282
40527
|
for (const clip of clips) {
|
|
40283
40528
|
const { segments, fillRule } = "segments" in clip ? clip : { segments: clip, fillRule: "nonzero" };
|
|
40284
40529
|
const layer = new Uint8Array(width * height * 4);
|
|
40285
|
-
fillEdgesScanline4x4(layer, width, height,
|
|
40530
|
+
fillEdgesScanline4x4(layer, width, height, pathsToEdges(segmentsToScreenPaths(segments, displayList.height, scale), true), { r: 1, g: 1, b: 1 }, 1, fillRule);
|
|
40286
40531
|
for (let i = 3; i < layer.length; i += 4) clipMask[i] = Math.round(clipMask[i] * layer[i] / 255);
|
|
40287
40532
|
}
|
|
40288
40533
|
cachedClips = clips;
|
|
40289
40534
|
cachedClipMask = clipMask;
|
|
40290
40535
|
}
|
|
40536
|
+
const softMask = original.value.softMask;
|
|
40537
|
+
if (softMask) {
|
|
40538
|
+
if (softMask !== cachedSoftMask) {
|
|
40539
|
+
cachedSoftMaskPixels = renderSoftMask(softMask, displayList, scale).data;
|
|
40540
|
+
cachedSoftMask = softMask;
|
|
40541
|
+
}
|
|
40542
|
+
if (clipMask) {
|
|
40543
|
+
clipMask = clipMask.slice();
|
|
40544
|
+
for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * cachedSoftMaskPixels[i] / 255);
|
|
40545
|
+
} else {
|
|
40546
|
+
clipMask = cachedSoftMaskPixels;
|
|
40547
|
+
}
|
|
40548
|
+
}
|
|
40291
40549
|
const imageClips = original.value.clipImages;
|
|
40292
40550
|
if (imageClips) {
|
|
40293
40551
|
let imageMask = imageClipMasks.get(imageClips);
|
|
@@ -40316,62 +40574,38 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40316
40574
|
if (operation.kind === "path") {
|
|
40317
40575
|
const path = operation.value;
|
|
40318
40576
|
if (path.fillColor) {
|
|
40319
|
-
const edges =
|
|
40577
|
+
const edges = pathsToEdges(segmentsToScreenPaths(path.segments, displayList.height, scale), true);
|
|
40320
40578
|
const clipScreen = path.clipRect ? [path.clipRect[0] * scale, (displayList.height - path.clipRect[3]) * scale, path.clipRect[2] * scale, (displayList.height - path.clipRect[1]) * scale] : void 0;
|
|
40321
40579
|
fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
|
|
40322
40580
|
}
|
|
40323
40581
|
if (path.strokeColor) {
|
|
40324
|
-
const edges = segmentsToScreenEdges(path.segments, displayList.height, scale, false);
|
|
40325
40582
|
const rawSw = path.strokeWidth * scale;
|
|
40326
40583
|
const sw = Math.max(1, rawSw);
|
|
40327
40584
|
const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
|
|
40328
|
-
const
|
|
40329
|
-
|
|
40330
|
-
|
|
40331
|
-
|
|
40332
|
-
|
|
40333
|
-
|
|
40334
|
-
|
|
40335
|
-
|
|
40336
|
-
|
|
40337
|
-
|
|
40338
|
-
|
|
40339
|
-
|
|
40340
|
-
|
|
40341
|
-
|
|
40342
|
-
|
|
40343
|
-
|
|
40344
|
-
|
|
40345
|
-
|
|
40346
|
-
|
|
40347
|
-
|
|
40348
|
-
|
|
40349
|
-
|
|
40350
|
-
|
|
40351
|
-
|
|
40352
|
-
const t1 = (pos + step) / edgeLen;
|
|
40353
|
-
drawAntiAliasedSegment(
|
|
40354
|
-
rgba,
|
|
40355
|
-
width,
|
|
40356
|
-
height,
|
|
40357
|
-
e.x0 + dx * t0,
|
|
40358
|
-
e.y0 + dy * t0,
|
|
40359
|
-
e.x0 + dx * t1,
|
|
40360
|
-
e.y0 + dy * t1,
|
|
40361
|
-
sw,
|
|
40362
|
-
path.strokeColor,
|
|
40363
|
-
strokeAlpha,
|
|
40364
|
-
path.lineCap ?? 0,
|
|
40365
|
-
original.kind === "glyph" ? aaTxt : aaVec,
|
|
40366
|
-
path.blendMode,
|
|
40367
|
-
clipMask
|
|
40368
|
-
);
|
|
40369
|
-
}
|
|
40370
|
-
pos += step;
|
|
40371
|
-
dashDist = (dashDist + step) % dashCycle;
|
|
40372
|
-
}
|
|
40373
|
-
}
|
|
40374
|
-
}
|
|
40585
|
+
const contours = strokeOutlines(
|
|
40586
|
+
segmentsToScreenPaths(path.segments, displayList.height, scale),
|
|
40587
|
+
sw,
|
|
40588
|
+
path.lineCap ?? 0,
|
|
40589
|
+
path.lineJoin ?? 0,
|
|
40590
|
+
path.miterLimit ?? 10,
|
|
40591
|
+
path.dashArray?.map((value) => Math.max(0, value * scale)),
|
|
40592
|
+
(path.dashPhase ?? 0) * scale
|
|
40593
|
+
);
|
|
40594
|
+
const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
|
|
40595
|
+
const clipScreen = path.clipRect ? [path.clipRect[0] * scale, (displayList.height - path.clipRect[3]) * scale, path.clipRect[2] * scale, (displayList.height - path.clipRect[1]) * scale] : void 0;
|
|
40596
|
+
fillEdgesScanline4x4(
|
|
40597
|
+
rgba,
|
|
40598
|
+
width,
|
|
40599
|
+
height,
|
|
40600
|
+
edges,
|
|
40601
|
+
path.strokeColor,
|
|
40602
|
+
strokeAlpha,
|
|
40603
|
+
"nonzero",
|
|
40604
|
+
clipScreen,
|
|
40605
|
+
original.kind === "glyph" ? aaTxt : aaVec,
|
|
40606
|
+
path.blendMode,
|
|
40607
|
+
clipMask
|
|
40608
|
+
);
|
|
40375
40609
|
}
|
|
40376
40610
|
} else if (operation.kind === "image") {
|
|
40377
40611
|
const img = operation.value;
|
|
@@ -40469,6 +40703,27 @@ function renderDisplayListToPng(displayList, options = {}) {
|
|
|
40469
40703
|
const bmp = renderDisplayListToBitmap(displayList, options);
|
|
40470
40704
|
return encodeRgbaToPng(bmp.width, bmp.height, bmp.data);
|
|
40471
40705
|
}
|
|
40706
|
+
function pdfBlendModeToCss(mode) {
|
|
40707
|
+
if (!mode || mode === "Normal" || mode === "Compatible") return void 0;
|
|
40708
|
+
const map = {
|
|
40709
|
+
Multiply: "multiply",
|
|
40710
|
+
Screen: "screen",
|
|
40711
|
+
Overlay: "overlay",
|
|
40712
|
+
Darken: "darken",
|
|
40713
|
+
Lighten: "lighten",
|
|
40714
|
+
ColorDodge: "color-dodge",
|
|
40715
|
+
ColorBurn: "color-burn",
|
|
40716
|
+
HardLight: "hard-light",
|
|
40717
|
+
SoftLight: "soft-light",
|
|
40718
|
+
Difference: "difference",
|
|
40719
|
+
Exclusion: "exclusion",
|
|
40720
|
+
Hue: "hue",
|
|
40721
|
+
Saturation: "saturation",
|
|
40722
|
+
Color: "color",
|
|
40723
|
+
Luminosity: "luminosity"
|
|
40724
|
+
};
|
|
40725
|
+
return map[mode];
|
|
40726
|
+
}
|
|
40472
40727
|
function escapeXmlText(str) {
|
|
40473
40728
|
let valid = "";
|
|
40474
40729
|
for (const char of str) {
|
|
@@ -40530,44 +40785,74 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
40530
40785
|
parts.push(`<g transform="matrix(${a} ${b} ${-c} ${-d} ${e + c * displayList.height} ${f + d * displayList.height})">`);
|
|
40531
40786
|
}
|
|
40532
40787
|
let clipId = 0;
|
|
40533
|
-
|
|
40534
|
-
|
|
40535
|
-
const
|
|
40536
|
-
|
|
40537
|
-
|
|
40538
|
-
|
|
40539
|
-
const
|
|
40540
|
-
const
|
|
40541
|
-
|
|
40542
|
-
|
|
40543
|
-
|
|
40544
|
-
|
|
40545
|
-
|
|
40546
|
-
|
|
40547
|
-
|
|
40548
|
-
|
|
40549
|
-
|
|
40550
|
-
|
|
40551
|
-
|
|
40552
|
-
|
|
40553
|
-
|
|
40554
|
-
|
|
40555
|
-
|
|
40556
|
-
|
|
40557
|
-
|
|
40558
|
-
|
|
40559
|
-
|
|
40560
|
-
|
|
40561
|
-
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
40562
|
-
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
40563
|
-
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
40564
|
-
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
40788
|
+
const softMaskIds = /* @__PURE__ */ new Map();
|
|
40789
|
+
const appendOperations = (operations) => {
|
|
40790
|
+
for (const original of operations) {
|
|
40791
|
+
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
40792
|
+
const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
40793
|
+
const clips = original.value.clipPaths ?? [];
|
|
40794
|
+
const imageClips = original.value.clipImages ?? [];
|
|
40795
|
+
const blend = pdfBlendModeToCss(original.value.blendMode);
|
|
40796
|
+
if (blend) parts.push(`<g style="mix-blend-mode:${blend}">`);
|
|
40797
|
+
const softMask = original.value.softMask;
|
|
40798
|
+
if (softMask) {
|
|
40799
|
+
let id = softMaskIds.get(softMask);
|
|
40800
|
+
if (!id) {
|
|
40801
|
+
id = `soft-mask-${clipId++}`;
|
|
40802
|
+
softMaskIds.set(softMask, id);
|
|
40803
|
+
const bitmap = renderSoftMask(softMask, displayList, Math.max(scaleX, scaleY));
|
|
40804
|
+
const image = {
|
|
40805
|
+
name: id,
|
|
40806
|
+
width: bitmap.width,
|
|
40807
|
+
height: bitmap.height,
|
|
40808
|
+
decodedRgba: bitmap.data,
|
|
40809
|
+
matrix: [displayList.width, 0, 0, displayList.height, 0, 0],
|
|
40810
|
+
colorSpace: "DeviceGray",
|
|
40811
|
+
bitsPerComponent: 8
|
|
40812
|
+
};
|
|
40813
|
+
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>`);
|
|
40814
|
+
}
|
|
40815
|
+
parts.push(`<g mask="url(#${id})">`);
|
|
40565
40816
|
}
|
|
40566
|
-
|
|
40567
|
-
|
|
40817
|
+
for (const clip of clips) {
|
|
40818
|
+
const { segments, fillRule } = "segments" in clip ? clip : { segments: clip, fillRule: "nonzero" };
|
|
40819
|
+
const id = `text-clip-${clipId++}`;
|
|
40820
|
+
const path = `<path d="${svgPathData(segments, displayList.height)}" clip-rule="${fillRule}"/>`;
|
|
40821
|
+
parts.push(`<defs><clipPath id="${id}" clipPathUnits="userSpaceOnUse">${path}</clipPath></defs><g clip-path="url(#${id})">`);
|
|
40822
|
+
}
|
|
40823
|
+
for (const image of imageClips) {
|
|
40824
|
+
const id = `image-clip-${clipId++}`;
|
|
40825
|
+
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})">`);
|
|
40826
|
+
}
|
|
40827
|
+
if (operation.kind === "group") {
|
|
40828
|
+
parts.push(`<g opacity="${operation.value.alpha}" style="isolation:isolate">`);
|
|
40829
|
+
appendOperations(operation.value.operations);
|
|
40830
|
+
parts.push("</g>");
|
|
40831
|
+
} else if (operation.kind === "path") {
|
|
40832
|
+
const p = operation.value;
|
|
40833
|
+
const pathData = svgPathData(p.segments, displayList.height);
|
|
40834
|
+
if (pathData) {
|
|
40835
|
+
const fill = p.fillColor ? `rgb(${Math.round(p.fillColor.r * 255)},${Math.round(p.fillColor.g * 255)},${Math.round(p.fillColor.b * 255)})` : "none";
|
|
40836
|
+
const stroke = p.strokeColor ? `rgb(${Math.round(p.strokeColor.r * 255)},${Math.round(p.strokeColor.g * 255)},${Math.round(p.strokeColor.b * 255)})` : "none";
|
|
40837
|
+
const fillRuleAttr = p.fillRule === "evenodd" ? ` fill-rule="evenodd"` : "";
|
|
40838
|
+
const fillOpacityAttr = p.fillAlpha !== void 0 && p.fillAlpha < 1 ? ` fill-opacity="${p.fillAlpha}"` : "";
|
|
40839
|
+
const strokeOpacityAttr = p.strokeAlpha !== void 0 && p.strokeAlpha < 1 ? ` stroke-opacity="${p.strokeAlpha}"` : "";
|
|
40840
|
+
const strokeWidthAttr = p.strokeWidth <= 0 ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${p.strokeWidth}"`;
|
|
40841
|
+
const lineCapAttr = p.lineCap === 1 ? ` stroke-linecap="round"` : p.lineCap === 2 ? ` stroke-linecap="square"` : "";
|
|
40842
|
+
const lineJoinAttr = p.lineJoin === 1 ? ` stroke-linejoin="round"` : p.lineJoin === 2 ? ` stroke-linejoin="bevel"` : "";
|
|
40843
|
+
const miterLimitAttr = p.miterLimit !== void 0 && p.miterLimit !== 10 ? ` stroke-miterlimit="${p.miterLimit}"` : "";
|
|
40844
|
+
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
40845
|
+
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
40846
|
+
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
40847
|
+
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
40848
|
+
}
|
|
40849
|
+
} else if (operation.kind === "image") {
|
|
40850
|
+
parts.push(` ${svgImage(operation.value, displayList.height)}`);
|
|
40851
|
+
}
|
|
40852
|
+
for (let i = 0; i < clips.length + imageClips.length + (softMask ? 1 : 0) + (blend ? 1 : 0); i++) parts.push("</g>");
|
|
40568
40853
|
}
|
|
40569
|
-
|
|
40570
|
-
|
|
40854
|
+
};
|
|
40855
|
+
appendOperations(paintOperations(displayList));
|
|
40571
40856
|
if (displayList.rotation) parts.push("</g>");
|
|
40572
40857
|
parts.push("</svg>\n");
|
|
40573
40858
|
return parts.join("\n");
|
|
@@ -42200,3 +42485,15 @@ export {
|
|
|
42200
42485
|
* Copyright 2012 Mozilla Foundation. Licensed under Apache-2.0.
|
|
42201
42486
|
* See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
|
|
42202
42487
|
*/
|
|
42488
|
+
/*!
|
|
42489
|
+
* Anti-Grain Geometry - Version 2.3
|
|
42490
|
+
* Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
|
42491
|
+
*
|
|
42492
|
+
* Permission to copy, use, modify, sell and distribute this software
|
|
42493
|
+
* is granted provided this copyright notice appears in all copies.
|
|
42494
|
+
* This software is provided "as is" without express or implied
|
|
42495
|
+
* warranty, and with no claim as to its suitability for any purpose.
|
|
42496
|
+
*
|
|
42497
|
+
* Adapted from PDFium agg_math_stroke.h and agg_vcgen_stroke.cpp.
|
|
42498
|
+
* See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
|
|
42499
|
+
*/
|