@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
package/dist/pdf-ast/index.js
CHANGED
|
@@ -36281,14 +36281,18 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36281
36281
|
const paths = [];
|
|
36282
36282
|
const images = [];
|
|
36283
36283
|
const operations = [];
|
|
36284
|
+
let capturedOperations;
|
|
36285
|
+
let insideSoftMask = false;
|
|
36284
36286
|
const emit = (operation) => {
|
|
36285
|
-
const { clipPaths, clipImages } = curState();
|
|
36286
|
-
if (clipPaths || clipImages) operation = { ...operation, value: {
|
|
36287
|
+
const { clipPaths, clipImages, softMask } = curState();
|
|
36288
|
+
if (clipPaths || clipImages || softMask) operation = { ...operation, value: {
|
|
36287
36289
|
...operation.value,
|
|
36288
36290
|
...clipPaths ? { clipPaths } : {},
|
|
36289
|
-
...clipImages ? { clipImages } : {}
|
|
36291
|
+
...clipImages ? { clipImages } : {},
|
|
36292
|
+
...softMask ? { softMask } : {}
|
|
36290
36293
|
} };
|
|
36291
|
-
operations.push(operation);
|
|
36294
|
+
(capturedOperations ?? operations).push(operation);
|
|
36295
|
+
if (insideSoftMask) return;
|
|
36292
36296
|
switch (operation.kind) {
|
|
36293
36297
|
case "path":
|
|
36294
36298
|
paths.push(operation.value);
|
|
@@ -36394,7 +36398,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36394
36398
|
);
|
|
36395
36399
|
return { r: kClamp(r), g: kClamp(g), b: kClamp(b) };
|
|
36396
36400
|
};
|
|
36397
|
-
const applyStateOperator = (st, operator, ops, activeResources) => {
|
|
36401
|
+
const applyStateOperator = (st, operator, ops, activeResources, activeFonts, depth) => {
|
|
36398
36402
|
const num = (i, fb = 0) => ops[i]?.kind === "number" ? ops[i].value : fb;
|
|
36399
36403
|
if (operator === "cm") {
|
|
36400
36404
|
const m = [num(0, 1), num(1, 0), num(2, 0), num(3, 1), num(4, 0), num(5, 0)];
|
|
@@ -36477,6 +36481,46 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36477
36481
|
const extDict = params.cosDoc.resolveDict(dictGet(activeResources, "ExtGState"));
|
|
36478
36482
|
const gsDict = extDict ? params.cosDoc.resolveDict(dictGet(extDict, ops[0].decoded)) : void 0;
|
|
36479
36483
|
if (gsDict) {
|
|
36484
|
+
const mask = params.cosDoc.resolve(dictGet(gsDict, "SMask"));
|
|
36485
|
+
if (mask?.kind === "name" && mask.decoded === "None") {
|
|
36486
|
+
st.softMask = void 0;
|
|
36487
|
+
} else if (mask?.kind === "dict") {
|
|
36488
|
+
const subtype = params.cosDoc.resolve(dictGet(mask, "S"));
|
|
36489
|
+
const form = params.cosDoc.resolve(dictGet(mask, "G"));
|
|
36490
|
+
if (form?.kind === "stream" && subtype?.kind === "name" && (subtype.decoded === "Alpha" || subtype.decoded === "Luminosity")) {
|
|
36491
|
+
if (depth >= 8) throw new PdfError("E_LIMIT", "Soft-mask nesting exceeds the form depth limit");
|
|
36492
|
+
const parentOperations = capturedOperations;
|
|
36493
|
+
const parentInsideSoftMask = insideSoftMask;
|
|
36494
|
+
const savedTextState = { pendingTextClip, hasTextClip, activeTm, activeTlm };
|
|
36495
|
+
const captured = [];
|
|
36496
|
+
capturedOperations = captured;
|
|
36497
|
+
insideSoftMask = true;
|
|
36498
|
+
const maskState = { ...st, softMask: void 0, fillAlpha: 1, strokeAlpha: 1, blendMode: "Normal" };
|
|
36499
|
+
delete maskState.clipPaths;
|
|
36500
|
+
delete maskState.clipImages;
|
|
36501
|
+
delete maskState.clipRect;
|
|
36502
|
+
stateStack.push(maskState);
|
|
36503
|
+
try {
|
|
36504
|
+
paintForm(form, activeResources, activeFonts, depth, void 0, void 0, true);
|
|
36505
|
+
} finally {
|
|
36506
|
+
stateStack.pop();
|
|
36507
|
+
capturedOperations = parentOperations;
|
|
36508
|
+
insideSoftMask = parentInsideSoftMask;
|
|
36509
|
+
({ pendingTextClip, hasTextClip, activeTm, activeTlm } = savedTextState);
|
|
36510
|
+
}
|
|
36511
|
+
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
36512
|
+
const colorSpace = group ? dictGet(group, "CS") : void 0;
|
|
36513
|
+
const bc = params.cosDoc.resolveArray(dictGet(mask, "BC"));
|
|
36514
|
+
const components = bc?.items.map((item) => {
|
|
36515
|
+
const value = params.cosDoc.resolve(item);
|
|
36516
|
+
return value?.kind === "number" ? value.value : 0;
|
|
36517
|
+
});
|
|
36518
|
+
const [r, g, b] = components ? convertColorSpaceComponentsToRgb(params.cosDoc, colorSpace, "DeviceRGB", components, activeResources) : [0, 0, 0];
|
|
36519
|
+
const transfer = params.cosDoc.resolve(dictGet(mask, "TR"));
|
|
36520
|
+
const transferMap = transfer?.kind === "dict" || transfer?.kind === "stream" ? Uint8Array.from({ length: 256 }, (_, i) => Math.floor(kClamp(Math.fround(evalShadingFunctionToComponents(params.cosDoc, transfer, Math.fround(i / 255))[0] ?? 0)) * 255)) : void 0;
|
|
36521
|
+
st.softMask = { subtype: subtype.decoded, operations: captured, backdrop: { r, g, b }, transferMap };
|
|
36522
|
+
}
|
|
36523
|
+
}
|
|
36480
36524
|
const bmNode = params.cosDoc.resolve(dictGet(gsDict, "BM"));
|
|
36481
36525
|
if (bmNode?.kind === "name") {
|
|
36482
36526
|
st.blendMode = bmNode.decoded === "Compatible" ? "Normal" : bmNode.decoded;
|
|
@@ -36563,6 +36607,84 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36563
36607
|
] }], void 0, void 0, resources, activeFonts, depth);
|
|
36564
36608
|
stateStack.pop();
|
|
36565
36609
|
};
|
|
36610
|
+
const paintForm = (form, activeResources, activeFonts, depth, mcid, actualText, maskGroup = false) => {
|
|
36611
|
+
const st = curState();
|
|
36612
|
+
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
36613
|
+
const groupType = group ? params.cosDoc.resolve(dictGet(group, "S")) : void 0;
|
|
36614
|
+
const isolated = group ? params.cosDoc.resolve(dictGet(group, "I")) : void 0;
|
|
36615
|
+
const isolate = !maskGroup && groupType?.kind === "name" && groupType.decoded === "Transparency" && isolated?.kind === "boolean" && isolated.value;
|
|
36616
|
+
const formStreamBytes = params.cosDoc.decodeStream(form);
|
|
36617
|
+
const formNodes = parseContentStream(formStreamBytes);
|
|
36618
|
+
const formResDict = params.cosDoc.resolveDict(dictGet(form.dict, "Resources")) ?? activeResources;
|
|
36619
|
+
const formFonts = new Map(activeFonts);
|
|
36620
|
+
for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
|
|
36621
|
+
formFonts.set(k, v);
|
|
36622
|
+
}
|
|
36623
|
+
let nextCtm = [...st.ctm];
|
|
36624
|
+
const matArr = params.cosDoc.resolveArray(dictGet(form.dict, "Matrix"));
|
|
36625
|
+
if (matArr && matArr.items.length >= 6) {
|
|
36626
|
+
const mn = (idx, fb = 0) => {
|
|
36627
|
+
const resolved = params.cosDoc.resolve(matArr.items[idx]);
|
|
36628
|
+
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36629
|
+
};
|
|
36630
|
+
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36631
|
+
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36632
|
+
}
|
|
36633
|
+
let nextClip = !isolate && st.clipRect ? [...st.clipRect] : void 0;
|
|
36634
|
+
let nextClipPaths = isolate ? void 0 : st.clipPaths;
|
|
36635
|
+
const bboxArr = params.cosDoc.resolveArray(dictGet(form.dict, "BBox"));
|
|
36636
|
+
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36637
|
+
const bn = (idx, fb = 0) => {
|
|
36638
|
+
const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
|
|
36639
|
+
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36640
|
+
};
|
|
36641
|
+
const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
|
|
36642
|
+
const pts = [
|
|
36643
|
+
transformPoint(nextCtm, bx0, by0),
|
|
36644
|
+
transformPoint(nextCtm, bx1, by0),
|
|
36645
|
+
transformPoint(nextCtm, bx1, by1),
|
|
36646
|
+
transformPoint(nextCtm, bx0, by1)
|
|
36647
|
+
];
|
|
36648
|
+
nextClipPaths = [...nextClipPaths ?? [], [
|
|
36649
|
+
...pts.map(([x, y], index) => ({ kind: index === 0 ? "move" : "line", x, y })),
|
|
36650
|
+
{ kind: "close" }
|
|
36651
|
+
]];
|
|
36652
|
+
const fMinX = Math.min(...pts.map((p) => p[0]));
|
|
36653
|
+
const fMinY = Math.min(...pts.map((p) => p[1]));
|
|
36654
|
+
const fMaxX = Math.max(...pts.map((p) => p[0]));
|
|
36655
|
+
const fMaxY = Math.max(...pts.map((p) => p[1]));
|
|
36656
|
+
if (fMaxX > fMinX && fMaxY > fMinY) {
|
|
36657
|
+
nextClip = nextClip ? [
|
|
36658
|
+
Math.max(nextClip[0], fMinX),
|
|
36659
|
+
Math.max(nextClip[1], fMinY),
|
|
36660
|
+
Math.min(nextClip[2], fMaxX),
|
|
36661
|
+
Math.min(nextClip[3], fMaxY)
|
|
36662
|
+
] : [fMinX, fMinY, fMaxX, fMaxY];
|
|
36663
|
+
}
|
|
36664
|
+
}
|
|
36665
|
+
const parentOperations = capturedOperations;
|
|
36666
|
+
const children = [];
|
|
36667
|
+
const nextState = { ...st, ctm: nextCtm };
|
|
36668
|
+
if (isolate) {
|
|
36669
|
+
capturedOperations = children;
|
|
36670
|
+
nextState.fillAlpha = nextState.strokeAlpha = 1;
|
|
36671
|
+
nextState.blendMode = "Normal";
|
|
36672
|
+
nextState.softMask = void 0;
|
|
36673
|
+
delete nextState.clipImages;
|
|
36674
|
+
delete nextState.clipPaths;
|
|
36675
|
+
delete nextState.clipRect;
|
|
36676
|
+
}
|
|
36677
|
+
if (nextClip) nextState.clipRect = nextClip;
|
|
36678
|
+
if (nextClipPaths) nextState.clipPaths = nextClipPaths;
|
|
36679
|
+
stateStack.push(nextState);
|
|
36680
|
+
try {
|
|
36681
|
+
walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
|
|
36682
|
+
} finally {
|
|
36683
|
+
stateStack.pop();
|
|
36684
|
+
capturedOperations = parentOperations;
|
|
36685
|
+
}
|
|
36686
|
+
if (isolate) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
|
|
36687
|
+
};
|
|
36566
36688
|
const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
|
|
36567
36689
|
for (const node of nodes) {
|
|
36568
36690
|
switch (node.kind) {
|
|
@@ -36607,7 +36729,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36607
36729
|
break;
|
|
36608
36730
|
}
|
|
36609
36731
|
case "state-op": {
|
|
36610
|
-
applyStateOperator(curState(), node.operator, node.operands, activeResources);
|
|
36732
|
+
applyStateOperator(curState(), node.operator, node.operands, activeResources, activeFonts, depth);
|
|
36611
36733
|
break;
|
|
36612
36734
|
}
|
|
36613
36735
|
case "path-op": {
|
|
@@ -36893,53 +37015,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36893
37015
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
36894
37016
|
}, patternMask, activeResources, activeFonts, depth);
|
|
36895
37017
|
} else if (sub === "Form" && depth < 8) {
|
|
36896
|
-
|
|
36897
|
-
const formNodes = parseContentStream(formStreamBytes);
|
|
36898
|
-
const formResDict = params.cosDoc.resolveDict(dictGet(xobjNode.dict, "Resources")) ?? activeResources;
|
|
36899
|
-
const formFonts = new Map(activeFonts);
|
|
36900
|
-
for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
|
|
36901
|
-
formFonts.set(k, v);
|
|
36902
|
-
}
|
|
36903
|
-
let nextCtm = [...st.ctm];
|
|
36904
|
-
const matArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "Matrix"));
|
|
36905
|
-
if (matArr && matArr.items.length >= 6) {
|
|
36906
|
-
const mn = (idx, fb = 0) => {
|
|
36907
|
-
const resolved = params.cosDoc.resolve(matArr.items[idx]);
|
|
36908
|
-
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36909
|
-
};
|
|
36910
|
-
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36911
|
-
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36912
|
-
}
|
|
36913
|
-
let nextClip = st.clipRect ? [...st.clipRect] : void 0;
|
|
36914
|
-
const bboxArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "BBox"));
|
|
36915
|
-
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36916
|
-
const bn = (idx, fb = 0) => {
|
|
36917
|
-
const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
|
|
36918
|
-
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36919
|
-
};
|
|
36920
|
-
const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
|
|
36921
|
-
const pts = [
|
|
36922
|
-
transformPoint(nextCtm, bx0, by0),
|
|
36923
|
-
transformPoint(nextCtm, bx1, by0),
|
|
36924
|
-
transformPoint(nextCtm, bx0, by1),
|
|
36925
|
-
transformPoint(nextCtm, bx1, by1)
|
|
36926
|
-
];
|
|
36927
|
-
const fMinX = Math.min(...pts.map((p) => p[0]));
|
|
36928
|
-
const fMinY = Math.min(...pts.map((p) => p[1]));
|
|
36929
|
-
const fMaxX = Math.max(...pts.map((p) => p[0]));
|
|
36930
|
-
const fMaxY = Math.max(...pts.map((p) => p[1]));
|
|
36931
|
-
if (fMaxX > fMinX && fMaxY > fMinY) {
|
|
36932
|
-
nextClip = nextClip ? [
|
|
36933
|
-
Math.max(nextClip[0], fMinX),
|
|
36934
|
-
Math.max(nextClip[1], fMinY),
|
|
36935
|
-
Math.min(nextClip[2], fMaxX),
|
|
36936
|
-
Math.min(nextClip[3], fMaxY)
|
|
36937
|
-
] : [fMinX, fMinY, fMaxX, fMaxY];
|
|
36938
|
-
}
|
|
36939
|
-
}
|
|
36940
|
-
stateStack.push({ ...st, ctm: nextCtm, ...nextClip ? { clipRect: nextClip } : {} });
|
|
36941
|
-
walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
|
|
36942
|
-
if (stateStack.length > 1) stateStack.pop();
|
|
37018
|
+
paintForm(xobjNode, activeResources, activeFonts, depth, mcid, actualText);
|
|
36943
37019
|
}
|
|
36944
37020
|
}
|
|
36945
37021
|
}
|
|
@@ -37158,7 +37234,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
37158
37234
|
st.textRenderMode = cmd.mode;
|
|
37159
37235
|
break;
|
|
37160
37236
|
case "state-op":
|
|
37161
|
-
applyStateOperator(st, cmd.operator, cmd.operands, activeResources);
|
|
37237
|
+
applyStateOperator(st, cmd.operator, cmd.operands, activeResources, activeFonts, depth);
|
|
37162
37238
|
break;
|
|
37163
37239
|
case "show-text":
|
|
37164
37240
|
emitTokenBytes(cmd.token.bytes);
|
|
@@ -40156,6 +40232,186 @@ function downscaleImage(image, widthScale, heightScale) {
|
|
|
40156
40232
|
return image;
|
|
40157
40233
|
}
|
|
40158
40234
|
|
|
40235
|
+
// src/render/stroke.ts
|
|
40236
|
+
var MAX_STROKE_VERTICES = 1e6;
|
|
40237
|
+
function dashSubpath(path, pattern, phase) {
|
|
40238
|
+
const cycle = pattern.reduce((sum, value) => sum + value, 0);
|
|
40239
|
+
if (!(cycle > 0)) return [path];
|
|
40240
|
+
let offset = (phase % cycle + cycle) % cycle, index = 0;
|
|
40241
|
+
while (offset > 0) {
|
|
40242
|
+
if (offset < pattern[index]) break;
|
|
40243
|
+
offset -= pattern[index];
|
|
40244
|
+
index = (index + 1) % pattern.length;
|
|
40245
|
+
}
|
|
40246
|
+
let remaining = pattern[index] - offset;
|
|
40247
|
+
const points = path.closed ? [...path.points, path.points[0]] : path.points;
|
|
40248
|
+
const result = [];
|
|
40249
|
+
let current = [];
|
|
40250
|
+
let steps = 0;
|
|
40251
|
+
const flush = () => {
|
|
40252
|
+
if (current.length) result.push({ points: current, closed: false });
|
|
40253
|
+
current = [];
|
|
40254
|
+
};
|
|
40255
|
+
const advance = (point) => {
|
|
40256
|
+
while (remaining <= 0) {
|
|
40257
|
+
if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
40258
|
+
if (index % 2 === 0) {
|
|
40259
|
+
if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
|
|
40260
|
+
flush();
|
|
40261
|
+
}
|
|
40262
|
+
index = (index + 1) % pattern.length;
|
|
40263
|
+
remaining = pattern[index];
|
|
40264
|
+
}
|
|
40265
|
+
};
|
|
40266
|
+
for (let i = 1; i < points.length; i++) {
|
|
40267
|
+
const start = points[i - 1], end = points[i];
|
|
40268
|
+
const dx = end[0] - start[0], dy = end[1] - start[1];
|
|
40269
|
+
const length = Math.hypot(dx, dy);
|
|
40270
|
+
if (!Number.isFinite(length) || length / cycle * pattern.length > MAX_STROKE_VERTICES) {
|
|
40271
|
+
throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
40272
|
+
}
|
|
40273
|
+
let distance = 0;
|
|
40274
|
+
while (distance < length) {
|
|
40275
|
+
const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
|
|
40276
|
+
advance(point);
|
|
40277
|
+
const step = Math.min(remaining, length - distance);
|
|
40278
|
+
if (distance + step === distance || ++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
40279
|
+
distance += step;
|
|
40280
|
+
remaining -= step;
|
|
40281
|
+
if (index % 2 === 0) {
|
|
40282
|
+
if (!current.length) current.push(point);
|
|
40283
|
+
current.push([start[0] + dx * distance / length, start[1] + dy * distance / length]);
|
|
40284
|
+
}
|
|
40285
|
+
}
|
|
40286
|
+
}
|
|
40287
|
+
flush();
|
|
40288
|
+
if (path.closed && result.length) {
|
|
40289
|
+
const first = result[0], last = result[result.length - 1];
|
|
40290
|
+
const start = path.points[0];
|
|
40291
|
+
const firstPoint = first.points[0], lastPoint = last.points[last.points.length - 1];
|
|
40292
|
+
if (firstPoint[0] === start[0] && firstPoint[1] === start[1] && lastPoint[0] === start[0] && lastPoint[1] === start[1]) {
|
|
40293
|
+
if (first === last) result[0] = { points: first.points, closed: true };
|
|
40294
|
+
else {
|
|
40295
|
+
result[0] = { points: [...last.points, ...first.points.slice(1)], closed: false };
|
|
40296
|
+
result.pop();
|
|
40297
|
+
}
|
|
40298
|
+
}
|
|
40299
|
+
}
|
|
40300
|
+
return result;
|
|
40301
|
+
}
|
|
40302
|
+
function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], dashPhase = 0) {
|
|
40303
|
+
const half = width / 2;
|
|
40304
|
+
const contours = [];
|
|
40305
|
+
const pattern = dashArray.length % 2 ? [...dashArray, ...dashArray] : dashArray;
|
|
40306
|
+
let count = 0;
|
|
40307
|
+
let contour = [];
|
|
40308
|
+
const add = (x, y) => {
|
|
40309
|
+
if (++count > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke outline exceeds the vertex limit");
|
|
40310
|
+
contour.push([x, y]);
|
|
40311
|
+
};
|
|
40312
|
+
const arc = (point, dx1, dy1, dx2, dy2) => {
|
|
40313
|
+
let a1 = Math.atan2(dy1, dx1), a2 = Math.atan2(dy2, dx2);
|
|
40314
|
+
const ccw = a1 - a2 > 0 && a1 - a2 < Math.PI;
|
|
40315
|
+
const step = Math.acos(half / (half + 0.125)) * 2;
|
|
40316
|
+
add(point[0] + dx1, point[1] + dy1);
|
|
40317
|
+
if (step > 0) {
|
|
40318
|
+
if (!ccw) {
|
|
40319
|
+
if (a1 > a2) a2 += 2 * Math.PI;
|
|
40320
|
+
a2 -= step / 4;
|
|
40321
|
+
if ((a2 - a1) / step > MAX_STROKE_VERTICES - count) throw new PdfError("E_LIMIT", "Stroke arc exceeds the vertex limit");
|
|
40322
|
+
for (a1 += step; a1 < a2; a1 += step) add(point[0] + half * Math.cos(a1), point[1] + half * Math.sin(a1));
|
|
40323
|
+
} else {
|
|
40324
|
+
if (a1 < a2) a2 -= 2 * Math.PI;
|
|
40325
|
+
a2 += step / 4;
|
|
40326
|
+
if ((a1 - a2) / step > MAX_STROKE_VERTICES - count) throw new PdfError("E_LIMIT", "Stroke arc exceeds the vertex limit");
|
|
40327
|
+
for (a1 -= step; a1 > a2; a1 -= step) add(point[0] + half * Math.cos(a1), point[1] + half * Math.sin(a1));
|
|
40328
|
+
}
|
|
40329
|
+
}
|
|
40330
|
+
add(point[0] + dx2, point[1] + dy2);
|
|
40331
|
+
};
|
|
40332
|
+
const addCap = (point, next) => {
|
|
40333
|
+
const length = Math.hypot(next[0] - point[0], next[1] - point[1]);
|
|
40334
|
+
const dx = half * (next[1] - point[1]) / length;
|
|
40335
|
+
const dy = half * (next[0] - point[0]) / length;
|
|
40336
|
+
if (cap !== 1) {
|
|
40337
|
+
const sx = cap === 2 ? dy : 0, sy = cap === 2 ? dx : 0;
|
|
40338
|
+
add(point[0] - dx - sx, point[1] + dy - sy);
|
|
40339
|
+
add(point[0] + dx - sx, point[1] - dy - sy);
|
|
40340
|
+
} else {
|
|
40341
|
+
const angle = Math.atan2(dy, -dx);
|
|
40342
|
+
const step = Math.max(1e-3, Math.acos(half / (half + 0.125)) * 2);
|
|
40343
|
+
add(point[0] - dx, point[1] + dy);
|
|
40344
|
+
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));
|
|
40345
|
+
add(point[0] + dx, point[1] - dy);
|
|
40346
|
+
}
|
|
40347
|
+
};
|
|
40348
|
+
const addJoin = (prev, point, next) => {
|
|
40349
|
+
const len1 = Math.hypot(point[0] - prev[0], point[1] - prev[1]);
|
|
40350
|
+
const len2 = Math.hypot(next[0] - point[0], next[1] - point[1]);
|
|
40351
|
+
const dx1 = half * (point[1] - prev[1]) / len1, dy1 = half * (point[0] - prev[0]) / len1;
|
|
40352
|
+
const dx2 = half * (next[1] - point[1]) / len2, dy2 = half * (next[0] - point[0]) / len2;
|
|
40353
|
+
const inner = (next[0] - point[0]) * (point[1] - prev[1]) - (next[1] - point[1]) * (point[0] - prev[0]) > 0;
|
|
40354
|
+
if (!inner && join === 1) {
|
|
40355
|
+
arc(point, dx1, -dy1, dx2, -dy2);
|
|
40356
|
+
return;
|
|
40357
|
+
}
|
|
40358
|
+
if (inner || join === 0) {
|
|
40359
|
+
const ax = prev[0] + dx1, ay = prev[1] - dy1;
|
|
40360
|
+
const bx = point[0] + dx1, by = point[1] - dy1;
|
|
40361
|
+
const cx = point[0] + dx2, cy = point[1] - dy2;
|
|
40362
|
+
const dx = next[0] + dx2, dy = next[1] - dy2;
|
|
40363
|
+
const den = (bx - ax) * (dy - cy) - (by - ay) * (dx - cx);
|
|
40364
|
+
if (Math.abs(den) >= 1e-30) {
|
|
40365
|
+
const t = ((ay - cy) * (dx - cx) - (ax - cx) * (dy - cy)) / den;
|
|
40366
|
+
const x = ax + (bx - ax) * t, y = ay + (by - ay) * t;
|
|
40367
|
+
if (Math.hypot(x - point[0], y - point[1]) <= half * (inner ? 1.01 : miterLimit)) {
|
|
40368
|
+
add(x, y);
|
|
40369
|
+
return;
|
|
40370
|
+
}
|
|
40371
|
+
} else if ((bx - prev[0]) * dy1 - (prev[1] - by) * dx1 < 0 !== (bx - next[0]) * dy1 - (next[1] - by) * dx1 < 0) {
|
|
40372
|
+
add(bx, by);
|
|
40373
|
+
return;
|
|
40374
|
+
}
|
|
40375
|
+
}
|
|
40376
|
+
add(point[0] + dx1, point[1] - dy1);
|
|
40377
|
+
add(point[0] + dx2, point[1] - dy2);
|
|
40378
|
+
};
|
|
40379
|
+
for (const path of paths) {
|
|
40380
|
+
for (const subpath of pattern.length ? dashSubpath(path, pattern, dashPhase) : [path]) {
|
|
40381
|
+
const points = [];
|
|
40382
|
+
for (const point of subpath.points) {
|
|
40383
|
+
const prev = points[points.length - 1];
|
|
40384
|
+
if (!prev || Math.hypot(prev[0] - point[0], prev[1] - point[1]) > 1e-14) points.push(point);
|
|
40385
|
+
}
|
|
40386
|
+
let closed = subpath.closed;
|
|
40387
|
+
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();
|
|
40388
|
+
if (points.length < 3) closed = false;
|
|
40389
|
+
if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
|
|
40390
|
+
contour = [];
|
|
40391
|
+
const [x, y] = points[0];
|
|
40392
|
+
addCap([x, y], [x + 1, y]);
|
|
40393
|
+
addCap([x, y], [x - 1, y]);
|
|
40394
|
+
contours.push(contour);
|
|
40395
|
+
} else if (points.length >= 2) {
|
|
40396
|
+
contour = [];
|
|
40397
|
+
if (!closed) addCap(points[0], points[1]);
|
|
40398
|
+
for (let i = closed ? 0 : 1; i < points.length - (closed ? 0 : 1); i++) {
|
|
40399
|
+
addJoin(points[(i + points.length - 1) % points.length], points[i], points[(i + 1) % points.length]);
|
|
40400
|
+
}
|
|
40401
|
+
if (closed) {
|
|
40402
|
+
contours.push(contour);
|
|
40403
|
+
contour = [];
|
|
40404
|
+
} else addCap(points[points.length - 1], points[points.length - 2]);
|
|
40405
|
+
for (let i = points.length - (closed ? 1 : 2); i >= (closed ? 0 : 1); i--) {
|
|
40406
|
+
addJoin(points[(i + 1) % points.length], points[i], points[(i + points.length - 1) % points.length]);
|
|
40407
|
+
}
|
|
40408
|
+
contours.push(contour);
|
|
40409
|
+
}
|
|
40410
|
+
}
|
|
40411
|
+
}
|
|
40412
|
+
return contours;
|
|
40413
|
+
}
|
|
40414
|
+
|
|
40159
40415
|
// src/render/raster.ts
|
|
40160
40416
|
function encodePng(bitmap) {
|
|
40161
40417
|
return encodeRgbaToPng(bitmap.width, bitmap.height, bitmap.data);
|
|
@@ -41247,111 +41503,60 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
|
|
|
41247
41503
|
rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
|
|
41248
41504
|
rgba[idx + 3] = Math.round(outA * 255);
|
|
41249
41505
|
}
|
|
41250
|
-
function
|
|
41251
|
-
const
|
|
41252
|
-
|
|
41253
|
-
|
|
41254
|
-
const lenSq = dx * dx + dy * dy;
|
|
41255
|
-
const segLen = Math.sqrt(lenSq);
|
|
41256
|
-
const pad = lineCap === 2 ? halfW + 2 : halfW + 1;
|
|
41257
|
-
const minX = Math.max(0, Math.floor(Math.min(x0, x1) - pad));
|
|
41258
|
-
const maxX = Math.min(width - 1, Math.ceil(Math.max(x0, x1) + pad));
|
|
41259
|
-
const minY = Math.max(0, Math.floor(Math.min(y0, y1) - pad));
|
|
41260
|
-
const maxY = Math.min(height - 1, Math.ceil(Math.max(y0, y1) + pad));
|
|
41261
|
-
for (let py = minY; py <= maxY; py++) {
|
|
41262
|
-
for (let px = minX; px <= maxX; px++) {
|
|
41263
|
-
const cx = px + 0.5;
|
|
41264
|
-
const cy = py + 0.5;
|
|
41265
|
-
if (segLen > 1e-6 && (lineCap === 0 || lineCap === 2)) {
|
|
41266
|
-
const ux = dx / segLen;
|
|
41267
|
-
const uy = dy / segLen;
|
|
41268
|
-
const along = (cx - x0) * ux + (cy - y0) * uy;
|
|
41269
|
-
const perp = Math.abs(-(cx - x0) * uy + (cy - y0) * ux);
|
|
41270
|
-
const minAlong = lineCap === 2 ? -halfW : 0;
|
|
41271
|
-
const maxAlong = lineCap === 2 ? segLen + halfW : segLen;
|
|
41272
|
-
const overAlong = along < minAlong ? minAlong - along : along > maxAlong ? along - maxAlong : 0;
|
|
41273
|
-
const dist2 = overAlong > 0 ? Math.max(perp, halfW + overAlong) : perp;
|
|
41274
|
-
if (dist2 <= halfW + 0.75) {
|
|
41275
|
-
const cov = antialias ? Math.max(0, Math.min(1, halfW + 0.5 - dist2)) : dist2 <= halfW + 0.25 ? 1 : 0;
|
|
41276
|
-
blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask);
|
|
41277
|
-
}
|
|
41278
|
-
continue;
|
|
41279
|
-
}
|
|
41280
|
-
let t = lenSq > 1e-6 ? ((cx - x0) * dx + (cy - y0) * dy) / lenSq : 0;
|
|
41281
|
-
t = Math.max(0, Math.min(1, t));
|
|
41282
|
-
const projX = x0 + t * dx;
|
|
41283
|
-
const projY = y0 + t * dy;
|
|
41284
|
-
const dist = Math.hypot(cx - projX, cy - projY);
|
|
41285
|
-
if (dist <= halfW + 0.75) {
|
|
41286
|
-
const cov = antialias ? Math.max(0, Math.min(1, halfW + 0.5 - dist)) : dist <= halfW + 0.25 ? 1 : 0;
|
|
41287
|
-
blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask);
|
|
41288
|
-
}
|
|
41289
|
-
}
|
|
41290
|
-
}
|
|
41291
|
-
}
|
|
41292
|
-
function segmentsToScreenEdges(segments, pageHeight, scale, closeSubpaths = false) {
|
|
41293
|
-
const edges = [];
|
|
41294
|
-
let curX = 0;
|
|
41295
|
-
let curY = 0;
|
|
41296
|
-
let startX = 0;
|
|
41297
|
-
let startY = 0;
|
|
41298
|
-
let hasOpenSubpath = false;
|
|
41506
|
+
function segmentsToScreenPaths(segments, pageHeight, scale) {
|
|
41507
|
+
const paths = [];
|
|
41508
|
+
let points = [];
|
|
41509
|
+
let current = [0, 0];
|
|
41299
41510
|
const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
|
|
41300
|
-
for (const
|
|
41301
|
-
if (
|
|
41302
|
-
if (
|
|
41303
|
-
|
|
41304
|
-
|
|
41305
|
-
|
|
41306
|
-
|
|
41307
|
-
|
|
41308
|
-
|
|
41309
|
-
} else if (
|
|
41310
|
-
|
|
41311
|
-
|
|
41312
|
-
|
|
41313
|
-
|
|
41314
|
-
|
|
41315
|
-
|
|
41316
|
-
|
|
41317
|
-
|
|
41318
|
-
|
|
41319
|
-
|
|
41320
|
-
|
|
41321
|
-
|
|
41322
|
-
|
|
41323
|
-
|
|
41324
|
-
|
|
41325
|
-
|
|
41326
|
-
|
|
41327
|
-
|
|
41328
|
-
|
|
41329
|
-
|
|
41330
|
-
|
|
41331
|
-
|
|
41332
|
-
|
|
41333
|
-
|
|
41334
|
-
|
|
41335
|
-
|
|
41336
|
-
|
|
41337
|
-
|
|
41338
|
-
|
|
41339
|
-
|
|
41340
|
-
|
|
41341
|
-
|
|
41342
|
-
const [
|
|
41343
|
-
|
|
41344
|
-
|
|
41345
|
-
|
|
41346
|
-
|
|
41347
|
-
|
|
41348
|
-
{ x0: rx0, y0: ry1, x1: rx0, y1: ry0 }
|
|
41349
|
-
);
|
|
41350
|
-
hasOpenSubpath = false;
|
|
41511
|
+
for (const segment of segments) {
|
|
41512
|
+
if (segment.kind === "move") {
|
|
41513
|
+
if (points.length) paths.push({ points, closed: false });
|
|
41514
|
+
current = toScreen(segment.x, segment.y);
|
|
41515
|
+
points = [current];
|
|
41516
|
+
} else if (segment.kind === "line") {
|
|
41517
|
+
if (!points.length) points = [current];
|
|
41518
|
+
current = toScreen(segment.x, segment.y);
|
|
41519
|
+
points.push(current);
|
|
41520
|
+
} else if (segment.kind === "cubic") {
|
|
41521
|
+
if (!points.length) points = [current];
|
|
41522
|
+
const a = toScreen(segment.x1, segment.y1), b = toScreen(segment.x2, segment.y2);
|
|
41523
|
+
const end = toScreen(segment.x, segment.y);
|
|
41524
|
+
const curve = flattenCubic(current[0], current[1], a[0], a[1], b[0], b[1], end[0], end[1]);
|
|
41525
|
+
for (let i = 1; i < curve.length; i++) points.push(curve[i]);
|
|
41526
|
+
current = end;
|
|
41527
|
+
} else if (segment.kind === "close") {
|
|
41528
|
+
if (points.length) {
|
|
41529
|
+
paths.push({ points, closed: true });
|
|
41530
|
+
current = points[0];
|
|
41531
|
+
points = [];
|
|
41532
|
+
}
|
|
41533
|
+
} else if (segment.kind === "rect") {
|
|
41534
|
+
if (points.length) paths.push({ points, closed: false });
|
|
41535
|
+
const first = toScreen(segment.x, segment.y);
|
|
41536
|
+
paths.push({ points: [
|
|
41537
|
+
first,
|
|
41538
|
+
toScreen(segment.x + segment.width, segment.y),
|
|
41539
|
+
toScreen(segment.x + segment.width, segment.y + segment.height),
|
|
41540
|
+
toScreen(segment.x, segment.y + segment.height)
|
|
41541
|
+
], closed: true });
|
|
41542
|
+
current = first;
|
|
41543
|
+
points = [];
|
|
41544
|
+
}
|
|
41545
|
+
}
|
|
41546
|
+
if (points.length) paths.push({ points, closed: false });
|
|
41547
|
+
return paths;
|
|
41548
|
+
}
|
|
41549
|
+
function pathsToEdges(paths, closeSubpaths = false) {
|
|
41550
|
+
const edges = [];
|
|
41551
|
+
for (const { points, closed } of paths) {
|
|
41552
|
+
for (let i = 1; i < points.length; i++) {
|
|
41553
|
+
const a = points[i - 1], b = points[i];
|
|
41554
|
+
edges.push({ x0: a[0], y0: a[1], x1: b[0], y1: b[1] });
|
|
41555
|
+
}
|
|
41556
|
+
if ((closed || closeSubpaths) && points.length > 1) {
|
|
41557
|
+
const a = points[points.length - 1], b = points[0];
|
|
41558
|
+
edges.push({ x0: a[0], y0: a[1], x1: b[0], y1: b[1] });
|
|
41351
41559
|
}
|
|
41352
|
-
}
|
|
41353
|
-
if (closeSubpaths && hasOpenSubpath && (curX !== startX || curY !== startY)) {
|
|
41354
|
-
edges.push({ x0: curX, y0: curY, x1: startX, y1: startY });
|
|
41355
41560
|
}
|
|
41356
41561
|
return edges;
|
|
41357
41562
|
}
|
|
@@ -41462,6 +41667,30 @@ function paintOperations(displayList) {
|
|
|
41462
41667
|
...displayList.glyphs.map((value) => ({ kind: "glyph", value }))
|
|
41463
41668
|
];
|
|
41464
41669
|
}
|
|
41670
|
+
function renderSoftMask(mask, displayList, scale) {
|
|
41671
|
+
const bitmap = renderDisplayListToBitmap({
|
|
41672
|
+
...displayList,
|
|
41673
|
+
rotation: 0,
|
|
41674
|
+
glyphs: [],
|
|
41675
|
+
paths: [],
|
|
41676
|
+
images: [],
|
|
41677
|
+
operations: mask.operations
|
|
41678
|
+
}, { scale, transparent: true });
|
|
41679
|
+
const { data } = bitmap;
|
|
41680
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
41681
|
+
let value = data[i + 3];
|
|
41682
|
+
if (mask.subtype === "Luminosity") {
|
|
41683
|
+
const alpha = value / 255;
|
|
41684
|
+
const r = Math.round(data[i] * alpha + mask.backdrop.r * 255 * (1 - alpha));
|
|
41685
|
+
const g = Math.round(data[i + 1] * alpha + mask.backdrop.g * 255 * (1 - alpha));
|
|
41686
|
+
const b = Math.round(data[i + 2] * alpha + mask.backdrop.b * 255 * (1 - alpha));
|
|
41687
|
+
value = Math.round(pdfLum(r, g, b));
|
|
41688
|
+
}
|
|
41689
|
+
data[i] = data[i + 1] = data[i + 2] = 0;
|
|
41690
|
+
data[i + 3] = mask.transferMap?.[value] ?? value;
|
|
41691
|
+
}
|
|
41692
|
+
return bitmap;
|
|
41693
|
+
}
|
|
41465
41694
|
function renderDisplayListToBitmap(displayList, options = {}) {
|
|
41466
41695
|
const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
|
|
41467
41696
|
const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
|
|
@@ -41485,10 +41714,28 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41485
41714
|
const aaTxt = options.antialiasText !== false;
|
|
41486
41715
|
let cachedClips;
|
|
41487
41716
|
let cachedClipMask;
|
|
41717
|
+
let cachedSoftMask;
|
|
41718
|
+
let cachedSoftMaskPixels;
|
|
41488
41719
|
const imageClipMasks = /* @__PURE__ */ new Map();
|
|
41489
41720
|
for (const original of paintOperations(displayList)) {
|
|
41490
41721
|
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
41491
|
-
|
|
41722
|
+
let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
41723
|
+
if (operation.kind === "group") {
|
|
41724
|
+
const group = operation.value;
|
|
41725
|
+
const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations: group.operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, transparent: true });
|
|
41726
|
+
for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
|
|
41727
|
+
operation = { kind: "image", value: {
|
|
41728
|
+
name: "TransparencyGroup",
|
|
41729
|
+
width: bitmap.width,
|
|
41730
|
+
height: bitmap.height,
|
|
41731
|
+
decodedRgba: bitmap.data,
|
|
41732
|
+
matrix: [bitmap.width / scale, 0, 0, bitmap.height / scale, 0, displayList.height - bitmap.height / scale],
|
|
41733
|
+
colorSpace: "DeviceRGB",
|
|
41734
|
+
bitsPerComponent: 8,
|
|
41735
|
+
blendMode: group.blendMode,
|
|
41736
|
+
clipRect: group.clipRect
|
|
41737
|
+
} };
|
|
41738
|
+
}
|
|
41492
41739
|
const clips = original.value.clipPaths;
|
|
41493
41740
|
let clipMask = clips && clips === cachedClips ? cachedClipMask : void 0;
|
|
41494
41741
|
if (clips && !clipMask) {
|
|
@@ -41496,12 +41743,25 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41496
41743
|
for (const clip of clips) {
|
|
41497
41744
|
const { segments, fillRule } = "segments" in clip ? clip : { segments: clip, fillRule: "nonzero" };
|
|
41498
41745
|
const layer = new Uint8Array(width * height * 4);
|
|
41499
|
-
fillEdgesScanline4x4(layer, width, height,
|
|
41746
|
+
fillEdgesScanline4x4(layer, width, height, pathsToEdges(segmentsToScreenPaths(segments, displayList.height, scale), true), { r: 1, g: 1, b: 1 }, 1, fillRule);
|
|
41500
41747
|
for (let i = 3; i < layer.length; i += 4) clipMask[i] = Math.round(clipMask[i] * layer[i] / 255);
|
|
41501
41748
|
}
|
|
41502
41749
|
cachedClips = clips;
|
|
41503
41750
|
cachedClipMask = clipMask;
|
|
41504
41751
|
}
|
|
41752
|
+
const softMask = original.value.softMask;
|
|
41753
|
+
if (softMask) {
|
|
41754
|
+
if (softMask !== cachedSoftMask) {
|
|
41755
|
+
cachedSoftMaskPixels = renderSoftMask(softMask, displayList, scale).data;
|
|
41756
|
+
cachedSoftMask = softMask;
|
|
41757
|
+
}
|
|
41758
|
+
if (clipMask) {
|
|
41759
|
+
clipMask = clipMask.slice();
|
|
41760
|
+
for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * cachedSoftMaskPixels[i] / 255);
|
|
41761
|
+
} else {
|
|
41762
|
+
clipMask = cachedSoftMaskPixels;
|
|
41763
|
+
}
|
|
41764
|
+
}
|
|
41505
41765
|
const imageClips = original.value.clipImages;
|
|
41506
41766
|
if (imageClips) {
|
|
41507
41767
|
let imageMask = imageClipMasks.get(imageClips);
|
|
@@ -41530,62 +41790,38 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
41530
41790
|
if (operation.kind === "path") {
|
|
41531
41791
|
const path = operation.value;
|
|
41532
41792
|
if (path.fillColor) {
|
|
41533
|
-
const edges =
|
|
41793
|
+
const edges = pathsToEdges(segmentsToScreenPaths(path.segments, displayList.height, scale), true);
|
|
41534
41794
|
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;
|
|
41535
41795
|
fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
|
|
41536
41796
|
}
|
|
41537
41797
|
if (path.strokeColor) {
|
|
41538
|
-
const edges = segmentsToScreenEdges(path.segments, displayList.height, scale, false);
|
|
41539
41798
|
const rawSw = path.strokeWidth * scale;
|
|
41540
41799
|
const sw = Math.max(1, rawSw);
|
|
41541
41800
|
const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
|
|
41542
|
-
const
|
|
41543
|
-
|
|
41544
|
-
|
|
41545
|
-
|
|
41546
|
-
|
|
41547
|
-
|
|
41548
|
-
|
|
41549
|
-
|
|
41550
|
-
|
|
41551
|
-
|
|
41552
|
-
|
|
41553
|
-
|
|
41554
|
-
|
|
41555
|
-
|
|
41556
|
-
|
|
41557
|
-
|
|
41558
|
-
|
|
41559
|
-
|
|
41560
|
-
|
|
41561
|
-
|
|
41562
|
-
|
|
41563
|
-
|
|
41564
|
-
|
|
41565
|
-
|
|
41566
|
-
const t1 = (pos + step) / edgeLen;
|
|
41567
|
-
drawAntiAliasedSegment(
|
|
41568
|
-
rgba,
|
|
41569
|
-
width,
|
|
41570
|
-
height,
|
|
41571
|
-
e.x0 + dx * t0,
|
|
41572
|
-
e.y0 + dy * t0,
|
|
41573
|
-
e.x0 + dx * t1,
|
|
41574
|
-
e.y0 + dy * t1,
|
|
41575
|
-
sw,
|
|
41576
|
-
path.strokeColor,
|
|
41577
|
-
strokeAlpha,
|
|
41578
|
-
path.lineCap ?? 0,
|
|
41579
|
-
original.kind === "glyph" ? aaTxt : aaVec,
|
|
41580
|
-
path.blendMode,
|
|
41581
|
-
clipMask
|
|
41582
|
-
);
|
|
41583
|
-
}
|
|
41584
|
-
pos += step;
|
|
41585
|
-
dashDist = (dashDist + step) % dashCycle;
|
|
41586
|
-
}
|
|
41587
|
-
}
|
|
41588
|
-
}
|
|
41801
|
+
const contours = strokeOutlines(
|
|
41802
|
+
segmentsToScreenPaths(path.segments, displayList.height, scale),
|
|
41803
|
+
sw,
|
|
41804
|
+
path.lineCap ?? 0,
|
|
41805
|
+
path.lineJoin ?? 0,
|
|
41806
|
+
path.miterLimit ?? 10,
|
|
41807
|
+
path.dashArray?.map((value) => Math.max(0, value * scale)),
|
|
41808
|
+
(path.dashPhase ?? 0) * scale
|
|
41809
|
+
);
|
|
41810
|
+
const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
|
|
41811
|
+
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;
|
|
41812
|
+
fillEdgesScanline4x4(
|
|
41813
|
+
rgba,
|
|
41814
|
+
width,
|
|
41815
|
+
height,
|
|
41816
|
+
edges,
|
|
41817
|
+
path.strokeColor,
|
|
41818
|
+
strokeAlpha,
|
|
41819
|
+
"nonzero",
|
|
41820
|
+
clipScreen,
|
|
41821
|
+
original.kind === "glyph" ? aaTxt : aaVec,
|
|
41822
|
+
path.blendMode,
|
|
41823
|
+
clipMask
|
|
41824
|
+
);
|
|
41589
41825
|
}
|
|
41590
41826
|
} else if (operation.kind === "image") {
|
|
41591
41827
|
const img = operation.value;
|
|
@@ -41683,6 +41919,27 @@ function renderDisplayListToPng(displayList, options = {}) {
|
|
|
41683
41919
|
const bmp = renderDisplayListToBitmap(displayList, options);
|
|
41684
41920
|
return encodeRgbaToPng(bmp.width, bmp.height, bmp.data);
|
|
41685
41921
|
}
|
|
41922
|
+
function pdfBlendModeToCss(mode) {
|
|
41923
|
+
if (!mode || mode === "Normal" || mode === "Compatible") return void 0;
|
|
41924
|
+
const map = {
|
|
41925
|
+
Multiply: "multiply",
|
|
41926
|
+
Screen: "screen",
|
|
41927
|
+
Overlay: "overlay",
|
|
41928
|
+
Darken: "darken",
|
|
41929
|
+
Lighten: "lighten",
|
|
41930
|
+
ColorDodge: "color-dodge",
|
|
41931
|
+
ColorBurn: "color-burn",
|
|
41932
|
+
HardLight: "hard-light",
|
|
41933
|
+
SoftLight: "soft-light",
|
|
41934
|
+
Difference: "difference",
|
|
41935
|
+
Exclusion: "exclusion",
|
|
41936
|
+
Hue: "hue",
|
|
41937
|
+
Saturation: "saturation",
|
|
41938
|
+
Color: "color",
|
|
41939
|
+
Luminosity: "luminosity"
|
|
41940
|
+
};
|
|
41941
|
+
return map[mode];
|
|
41942
|
+
}
|
|
41686
41943
|
function escapeXmlText(str) {
|
|
41687
41944
|
let valid = "";
|
|
41688
41945
|
for (const char of str) {
|
|
@@ -41744,44 +42001,74 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
41744
42001
|
parts.push(`<g transform="matrix(${a} ${b} ${-c} ${-d} ${e + c * displayList.height} ${f + d * displayList.height})">`);
|
|
41745
42002
|
}
|
|
41746
42003
|
let clipId = 0;
|
|
41747
|
-
|
|
41748
|
-
|
|
41749
|
-
const
|
|
41750
|
-
|
|
41751
|
-
|
|
41752
|
-
|
|
41753
|
-
const
|
|
41754
|
-
const
|
|
41755
|
-
|
|
41756
|
-
|
|
41757
|
-
|
|
41758
|
-
|
|
41759
|
-
|
|
41760
|
-
|
|
41761
|
-
|
|
41762
|
-
|
|
41763
|
-
|
|
41764
|
-
|
|
41765
|
-
|
|
41766
|
-
|
|
41767
|
-
|
|
41768
|
-
|
|
41769
|
-
|
|
41770
|
-
|
|
41771
|
-
|
|
41772
|
-
|
|
41773
|
-
|
|
41774
|
-
|
|
41775
|
-
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
41776
|
-
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
41777
|
-
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
41778
|
-
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
42004
|
+
const softMaskIds = /* @__PURE__ */ new Map();
|
|
42005
|
+
const appendOperations = (operations) => {
|
|
42006
|
+
for (const original of operations) {
|
|
42007
|
+
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
42008
|
+
const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
42009
|
+
const clips = original.value.clipPaths ?? [];
|
|
42010
|
+
const imageClips = original.value.clipImages ?? [];
|
|
42011
|
+
const blend = pdfBlendModeToCss(original.value.blendMode);
|
|
42012
|
+
if (blend) parts.push(`<g style="mix-blend-mode:${blend}">`);
|
|
42013
|
+
const softMask = original.value.softMask;
|
|
42014
|
+
if (softMask) {
|
|
42015
|
+
let id = softMaskIds.get(softMask);
|
|
42016
|
+
if (!id) {
|
|
42017
|
+
id = `soft-mask-${clipId++}`;
|
|
42018
|
+
softMaskIds.set(softMask, id);
|
|
42019
|
+
const bitmap = renderSoftMask(softMask, displayList, Math.max(scaleX, scaleY));
|
|
42020
|
+
const image = {
|
|
42021
|
+
name: id,
|
|
42022
|
+
width: bitmap.width,
|
|
42023
|
+
height: bitmap.height,
|
|
42024
|
+
decodedRgba: bitmap.data,
|
|
42025
|
+
matrix: [displayList.width, 0, 0, displayList.height, 0, 0],
|
|
42026
|
+
colorSpace: "DeviceGray",
|
|
42027
|
+
bitsPerComponent: 8
|
|
42028
|
+
};
|
|
42029
|
+
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>`);
|
|
42030
|
+
}
|
|
42031
|
+
parts.push(`<g mask="url(#${id})">`);
|
|
41779
42032
|
}
|
|
41780
|
-
|
|
41781
|
-
|
|
42033
|
+
for (const clip of clips) {
|
|
42034
|
+
const { segments, fillRule } = "segments" in clip ? clip : { segments: clip, fillRule: "nonzero" };
|
|
42035
|
+
const id = `text-clip-${clipId++}`;
|
|
42036
|
+
const path = `<path d="${svgPathData(segments, displayList.height)}" clip-rule="${fillRule}"/>`;
|
|
42037
|
+
parts.push(`<defs><clipPath id="${id}" clipPathUnits="userSpaceOnUse">${path}</clipPath></defs><g clip-path="url(#${id})">`);
|
|
42038
|
+
}
|
|
42039
|
+
for (const image of imageClips) {
|
|
42040
|
+
const id = `image-clip-${clipId++}`;
|
|
42041
|
+
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})">`);
|
|
42042
|
+
}
|
|
42043
|
+
if (operation.kind === "group") {
|
|
42044
|
+
parts.push(`<g opacity="${operation.value.alpha}" style="isolation:isolate">`);
|
|
42045
|
+
appendOperations(operation.value.operations);
|
|
42046
|
+
parts.push("</g>");
|
|
42047
|
+
} else if (operation.kind === "path") {
|
|
42048
|
+
const p = operation.value;
|
|
42049
|
+
const pathData = svgPathData(p.segments, displayList.height);
|
|
42050
|
+
if (pathData) {
|
|
42051
|
+
const fill = p.fillColor ? `rgb(${Math.round(p.fillColor.r * 255)},${Math.round(p.fillColor.g * 255)},${Math.round(p.fillColor.b * 255)})` : "none";
|
|
42052
|
+
const stroke = p.strokeColor ? `rgb(${Math.round(p.strokeColor.r * 255)},${Math.round(p.strokeColor.g * 255)},${Math.round(p.strokeColor.b * 255)})` : "none";
|
|
42053
|
+
const fillRuleAttr = p.fillRule === "evenodd" ? ` fill-rule="evenodd"` : "";
|
|
42054
|
+
const fillOpacityAttr = p.fillAlpha !== void 0 && p.fillAlpha < 1 ? ` fill-opacity="${p.fillAlpha}"` : "";
|
|
42055
|
+
const strokeOpacityAttr = p.strokeAlpha !== void 0 && p.strokeAlpha < 1 ? ` stroke-opacity="${p.strokeAlpha}"` : "";
|
|
42056
|
+
const strokeWidthAttr = p.strokeWidth <= 0 ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${p.strokeWidth}"`;
|
|
42057
|
+
const lineCapAttr = p.lineCap === 1 ? ` stroke-linecap="round"` : p.lineCap === 2 ? ` stroke-linecap="square"` : "";
|
|
42058
|
+
const lineJoinAttr = p.lineJoin === 1 ? ` stroke-linejoin="round"` : p.lineJoin === 2 ? ` stroke-linejoin="bevel"` : "";
|
|
42059
|
+
const miterLimitAttr = p.miterLimit !== void 0 && p.miterLimit !== 10 ? ` stroke-miterlimit="${p.miterLimit}"` : "";
|
|
42060
|
+
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
42061
|
+
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
42062
|
+
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
42063
|
+
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
42064
|
+
}
|
|
42065
|
+
} else if (operation.kind === "image") {
|
|
42066
|
+
parts.push(` ${svgImage(operation.value, displayList.height)}`);
|
|
42067
|
+
}
|
|
42068
|
+
for (let i = 0; i < clips.length + imageClips.length + (softMask ? 1 : 0) + (blend ? 1 : 0); i++) parts.push("</g>");
|
|
41782
42069
|
}
|
|
41783
|
-
|
|
41784
|
-
|
|
42070
|
+
};
|
|
42071
|
+
appendOperations(paintOperations(displayList));
|
|
41785
42072
|
if (displayList.rotation) parts.push("</g>");
|
|
41786
42073
|
parts.push("</svg>\n");
|
|
41787
42074
|
return parts.join("\n");
|
|
@@ -42746,3 +43033,15 @@ export {
|
|
|
42746
43033
|
* Copyright 2012 Mozilla Foundation. Licensed under Apache-2.0.
|
|
42747
43034
|
* See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
|
|
42748
43035
|
*/
|
|
43036
|
+
/*!
|
|
43037
|
+
* Anti-Grain Geometry - Version 2.3
|
|
43038
|
+
* Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
|
43039
|
+
*
|
|
43040
|
+
* Permission to copy, use, modify, sell and distribute this software
|
|
43041
|
+
* is granted provided this copyright notice appears in all copies.
|
|
43042
|
+
* This software is provided "as is" without express or implied
|
|
43043
|
+
* warranty, and with no claim as to its suitability for any purpose.
|
|
43044
|
+
*
|
|
43045
|
+
* Adapted from PDFium agg_math_stroke.h and agg_vcgen_stroke.cpp.
|
|
43046
|
+
* See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
|
|
43047
|
+
*/
|