@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
|
@@ -36107,14 +36107,18 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36107
36107
|
const paths = [];
|
|
36108
36108
|
const images = [];
|
|
36109
36109
|
const operations = [];
|
|
36110
|
+
let capturedOperations;
|
|
36111
|
+
let insideSoftMask = false;
|
|
36110
36112
|
const emit = (operation) => {
|
|
36111
|
-
const { clipPaths, clipImages } = curState();
|
|
36112
|
-
if (clipPaths || clipImages) operation = { ...operation, value: {
|
|
36113
|
+
const { clipPaths, clipImages, softMask } = curState();
|
|
36114
|
+
if (clipPaths || clipImages || softMask) operation = { ...operation, value: {
|
|
36113
36115
|
...operation.value,
|
|
36114
36116
|
...clipPaths ? { clipPaths } : {},
|
|
36115
|
-
...clipImages ? { clipImages } : {}
|
|
36117
|
+
...clipImages ? { clipImages } : {},
|
|
36118
|
+
...softMask ? { softMask } : {}
|
|
36116
36119
|
} };
|
|
36117
|
-
operations.push(operation);
|
|
36120
|
+
(capturedOperations ?? operations).push(operation);
|
|
36121
|
+
if (insideSoftMask) return;
|
|
36118
36122
|
switch (operation.kind) {
|
|
36119
36123
|
case "path":
|
|
36120
36124
|
paths.push(operation.value);
|
|
@@ -36220,7 +36224,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36220
36224
|
);
|
|
36221
36225
|
return { r: kClamp(r), g: kClamp(g), b: kClamp(b) };
|
|
36222
36226
|
};
|
|
36223
|
-
const applyStateOperator = (st, operator, ops, activeResources) => {
|
|
36227
|
+
const applyStateOperator = (st, operator, ops, activeResources, activeFonts, depth) => {
|
|
36224
36228
|
const num = (i, fb = 0) => ops[i]?.kind === "number" ? ops[i].value : fb;
|
|
36225
36229
|
if (operator === "cm") {
|
|
36226
36230
|
const m = [num(0, 1), num(1, 0), num(2, 0), num(3, 1), num(4, 0), num(5, 0)];
|
|
@@ -36303,6 +36307,46 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36303
36307
|
const extDict = params.cosDoc.resolveDict(dictGet(activeResources, "ExtGState"));
|
|
36304
36308
|
const gsDict = extDict ? params.cosDoc.resolveDict(dictGet(extDict, ops[0].decoded)) : void 0;
|
|
36305
36309
|
if (gsDict) {
|
|
36310
|
+
const mask = params.cosDoc.resolve(dictGet(gsDict, "SMask"));
|
|
36311
|
+
if (mask?.kind === "name" && mask.decoded === "None") {
|
|
36312
|
+
st.softMask = void 0;
|
|
36313
|
+
} else if (mask?.kind === "dict") {
|
|
36314
|
+
const subtype = params.cosDoc.resolve(dictGet(mask, "S"));
|
|
36315
|
+
const form = params.cosDoc.resolve(dictGet(mask, "G"));
|
|
36316
|
+
if (form?.kind === "stream" && subtype?.kind === "name" && (subtype.decoded === "Alpha" || subtype.decoded === "Luminosity")) {
|
|
36317
|
+
if (depth >= 8) throw new PdfError("E_LIMIT", "Soft-mask nesting exceeds the form depth limit");
|
|
36318
|
+
const parentOperations = capturedOperations;
|
|
36319
|
+
const parentInsideSoftMask = insideSoftMask;
|
|
36320
|
+
const savedTextState = { pendingTextClip, hasTextClip, activeTm, activeTlm };
|
|
36321
|
+
const captured = [];
|
|
36322
|
+
capturedOperations = captured;
|
|
36323
|
+
insideSoftMask = true;
|
|
36324
|
+
const maskState = { ...st, softMask: void 0, fillAlpha: 1, strokeAlpha: 1, blendMode: "Normal" };
|
|
36325
|
+
delete maskState.clipPaths;
|
|
36326
|
+
delete maskState.clipImages;
|
|
36327
|
+
delete maskState.clipRect;
|
|
36328
|
+
stateStack.push(maskState);
|
|
36329
|
+
try {
|
|
36330
|
+
paintForm(form, activeResources, activeFonts, depth, void 0, void 0, true);
|
|
36331
|
+
} finally {
|
|
36332
|
+
stateStack.pop();
|
|
36333
|
+
capturedOperations = parentOperations;
|
|
36334
|
+
insideSoftMask = parentInsideSoftMask;
|
|
36335
|
+
({ pendingTextClip, hasTextClip, activeTm, activeTlm } = savedTextState);
|
|
36336
|
+
}
|
|
36337
|
+
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
36338
|
+
const colorSpace = group ? dictGet(group, "CS") : void 0;
|
|
36339
|
+
const bc = params.cosDoc.resolveArray(dictGet(mask, "BC"));
|
|
36340
|
+
const components = bc?.items.map((item) => {
|
|
36341
|
+
const value = params.cosDoc.resolve(item);
|
|
36342
|
+
return value?.kind === "number" ? value.value : 0;
|
|
36343
|
+
});
|
|
36344
|
+
const [r, g, b] = components ? convertColorSpaceComponentsToRgb(params.cosDoc, colorSpace, "DeviceRGB", components, activeResources) : [0, 0, 0];
|
|
36345
|
+
const transfer = params.cosDoc.resolve(dictGet(mask, "TR"));
|
|
36346
|
+
const transferMap = transfer?.kind === "dict" || transfer?.kind === "stream" ? Uint8Array.from({ length: 256 }, (_, i) => Math.floor(kClamp(Math.fround(evalShadingFunctionToComponents(params.cosDoc, transfer, Math.fround(i / 255))[0] ?? 0)) * 255)) : void 0;
|
|
36347
|
+
st.softMask = { subtype: subtype.decoded, operations: captured, backdrop: { r, g, b }, transferMap };
|
|
36348
|
+
}
|
|
36349
|
+
}
|
|
36306
36350
|
const bmNode = params.cosDoc.resolve(dictGet(gsDict, "BM"));
|
|
36307
36351
|
if (bmNode?.kind === "name") {
|
|
36308
36352
|
st.blendMode = bmNode.decoded === "Compatible" ? "Normal" : bmNode.decoded;
|
|
@@ -36389,6 +36433,84 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36389
36433
|
] }], void 0, void 0, resources, activeFonts, depth);
|
|
36390
36434
|
stateStack.pop();
|
|
36391
36435
|
};
|
|
36436
|
+
const paintForm = (form, activeResources, activeFonts, depth, mcid, actualText, maskGroup = false) => {
|
|
36437
|
+
const st = curState();
|
|
36438
|
+
const group = params.cosDoc.resolveDict(dictGet(form.dict, "Group"));
|
|
36439
|
+
const groupType = group ? params.cosDoc.resolve(dictGet(group, "S")) : void 0;
|
|
36440
|
+
const isolated = group ? params.cosDoc.resolve(dictGet(group, "I")) : void 0;
|
|
36441
|
+
const isolate = !maskGroup && groupType?.kind === "name" && groupType.decoded === "Transparency" && isolated?.kind === "boolean" && isolated.value;
|
|
36442
|
+
const formStreamBytes = params.cosDoc.decodeStream(form);
|
|
36443
|
+
const formNodes = parseContentStream(formStreamBytes);
|
|
36444
|
+
const formResDict = params.cosDoc.resolveDict(dictGet(form.dict, "Resources")) ?? activeResources;
|
|
36445
|
+
const formFonts = new Map(activeFonts);
|
|
36446
|
+
for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
|
|
36447
|
+
formFonts.set(k, v);
|
|
36448
|
+
}
|
|
36449
|
+
let nextCtm = [...st.ctm];
|
|
36450
|
+
const matArr = params.cosDoc.resolveArray(dictGet(form.dict, "Matrix"));
|
|
36451
|
+
if (matArr && matArr.items.length >= 6) {
|
|
36452
|
+
const mn = (idx, fb = 0) => {
|
|
36453
|
+
const resolved = params.cosDoc.resolve(matArr.items[idx]);
|
|
36454
|
+
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36455
|
+
};
|
|
36456
|
+
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36457
|
+
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36458
|
+
}
|
|
36459
|
+
let nextClip = !isolate && st.clipRect ? [...st.clipRect] : void 0;
|
|
36460
|
+
let nextClipPaths = isolate ? void 0 : st.clipPaths;
|
|
36461
|
+
const bboxArr = params.cosDoc.resolveArray(dictGet(form.dict, "BBox"));
|
|
36462
|
+
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36463
|
+
const bn = (idx, fb = 0) => {
|
|
36464
|
+
const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
|
|
36465
|
+
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36466
|
+
};
|
|
36467
|
+
const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
|
|
36468
|
+
const pts = [
|
|
36469
|
+
transformPoint(nextCtm, bx0, by0),
|
|
36470
|
+
transformPoint(nextCtm, bx1, by0),
|
|
36471
|
+
transformPoint(nextCtm, bx1, by1),
|
|
36472
|
+
transformPoint(nextCtm, bx0, by1)
|
|
36473
|
+
];
|
|
36474
|
+
nextClipPaths = [...nextClipPaths ?? [], [
|
|
36475
|
+
...pts.map(([x, y], index) => ({ kind: index === 0 ? "move" : "line", x, y })),
|
|
36476
|
+
{ kind: "close" }
|
|
36477
|
+
]];
|
|
36478
|
+
const fMinX = Math.min(...pts.map((p) => p[0]));
|
|
36479
|
+
const fMinY = Math.min(...pts.map((p) => p[1]));
|
|
36480
|
+
const fMaxX = Math.max(...pts.map((p) => p[0]));
|
|
36481
|
+
const fMaxY = Math.max(...pts.map((p) => p[1]));
|
|
36482
|
+
if (fMaxX > fMinX && fMaxY > fMinY) {
|
|
36483
|
+
nextClip = nextClip ? [
|
|
36484
|
+
Math.max(nextClip[0], fMinX),
|
|
36485
|
+
Math.max(nextClip[1], fMinY),
|
|
36486
|
+
Math.min(nextClip[2], fMaxX),
|
|
36487
|
+
Math.min(nextClip[3], fMaxY)
|
|
36488
|
+
] : [fMinX, fMinY, fMaxX, fMaxY];
|
|
36489
|
+
}
|
|
36490
|
+
}
|
|
36491
|
+
const parentOperations = capturedOperations;
|
|
36492
|
+
const children = [];
|
|
36493
|
+
const nextState = { ...st, ctm: nextCtm };
|
|
36494
|
+
if (isolate) {
|
|
36495
|
+
capturedOperations = children;
|
|
36496
|
+
nextState.fillAlpha = nextState.strokeAlpha = 1;
|
|
36497
|
+
nextState.blendMode = "Normal";
|
|
36498
|
+
nextState.softMask = void 0;
|
|
36499
|
+
delete nextState.clipImages;
|
|
36500
|
+
delete nextState.clipPaths;
|
|
36501
|
+
delete nextState.clipRect;
|
|
36502
|
+
}
|
|
36503
|
+
if (nextClip) nextState.clipRect = nextClip;
|
|
36504
|
+
if (nextClipPaths) nextState.clipPaths = nextClipPaths;
|
|
36505
|
+
stateStack.push(nextState);
|
|
36506
|
+
try {
|
|
36507
|
+
walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
|
|
36508
|
+
} finally {
|
|
36509
|
+
stateStack.pop();
|
|
36510
|
+
capturedOperations = parentOperations;
|
|
36511
|
+
}
|
|
36512
|
+
if (isolate) emit({ kind: "group", value: { operations: children, alpha: st.fillAlpha, blendMode: st.blendMode, clipRect: st.clipRect } });
|
|
36513
|
+
};
|
|
36392
36514
|
const walkNodes = (nodes, mcid, actualText, activeResources = params.resourcesDict, activeFonts = fonts, depth = 0) => {
|
|
36393
36515
|
for (const node of nodes) {
|
|
36394
36516
|
switch (node.kind) {
|
|
@@ -36433,7 +36555,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36433
36555
|
break;
|
|
36434
36556
|
}
|
|
36435
36557
|
case "state-op": {
|
|
36436
|
-
applyStateOperator(curState(), node.operator, node.operands, activeResources);
|
|
36558
|
+
applyStateOperator(curState(), node.operator, node.operands, activeResources, activeFonts, depth);
|
|
36437
36559
|
break;
|
|
36438
36560
|
}
|
|
36439
36561
|
case "path-op": {
|
|
@@ -36719,53 +36841,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36719
36841
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
36720
36842
|
}, patternMask, activeResources, activeFonts, depth);
|
|
36721
36843
|
} else if (sub === "Form" && depth < 8) {
|
|
36722
|
-
|
|
36723
|
-
const formNodes = parseContentStream(formStreamBytes);
|
|
36724
|
-
const formResDict = params.cosDoc.resolveDict(dictGet(xobjNode.dict, "Resources")) ?? activeResources;
|
|
36725
|
-
const formFonts = new Map(activeFonts);
|
|
36726
|
-
for (const [k, v] of resolvePageFonts(params.cosDoc, formResDict).entries()) {
|
|
36727
|
-
formFonts.set(k, v);
|
|
36728
|
-
}
|
|
36729
|
-
let nextCtm = [...st.ctm];
|
|
36730
|
-
const matArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "Matrix"));
|
|
36731
|
-
if (matArr && matArr.items.length >= 6) {
|
|
36732
|
-
const mn = (idx, fb = 0) => {
|
|
36733
|
-
const resolved = params.cosDoc.resolve(matArr.items[idx]);
|
|
36734
|
-
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36735
|
-
};
|
|
36736
|
-
const formMat = [mn(0, 1), mn(1, 0), mn(2, 0), mn(3, 1), mn(4, 0), mn(5, 0)];
|
|
36737
|
-
nextCtm = multiplyMatrices(formMat, nextCtm);
|
|
36738
|
-
}
|
|
36739
|
-
let nextClip = st.clipRect ? [...st.clipRect] : void 0;
|
|
36740
|
-
const bboxArr = params.cosDoc.resolveArray(dictGet(xobjNode.dict, "BBox"));
|
|
36741
|
-
if (bboxArr && bboxArr.items.length >= 4) {
|
|
36742
|
-
const bn = (idx, fb = 0) => {
|
|
36743
|
-
const resolved = params.cosDoc.resolve(bboxArr.items[idx]);
|
|
36744
|
-
return resolved?.kind === "number" ? resolved.value : fb;
|
|
36745
|
-
};
|
|
36746
|
-
const bx0 = bn(0, 0), by0 = bn(1, 0), bx1 = bn(2, 0), by1 = bn(3, 0);
|
|
36747
|
-
const pts = [
|
|
36748
|
-
transformPoint(nextCtm, bx0, by0),
|
|
36749
|
-
transformPoint(nextCtm, bx1, by0),
|
|
36750
|
-
transformPoint(nextCtm, bx0, by1),
|
|
36751
|
-
transformPoint(nextCtm, bx1, by1)
|
|
36752
|
-
];
|
|
36753
|
-
const fMinX = Math.min(...pts.map((p) => p[0]));
|
|
36754
|
-
const fMinY = Math.min(...pts.map((p) => p[1]));
|
|
36755
|
-
const fMaxX = Math.max(...pts.map((p) => p[0]));
|
|
36756
|
-
const fMaxY = Math.max(...pts.map((p) => p[1]));
|
|
36757
|
-
if (fMaxX > fMinX && fMaxY > fMinY) {
|
|
36758
|
-
nextClip = nextClip ? [
|
|
36759
|
-
Math.max(nextClip[0], fMinX),
|
|
36760
|
-
Math.max(nextClip[1], fMinY),
|
|
36761
|
-
Math.min(nextClip[2], fMaxX),
|
|
36762
|
-
Math.min(nextClip[3], fMaxY)
|
|
36763
|
-
] : [fMinX, fMinY, fMaxX, fMaxY];
|
|
36764
|
-
}
|
|
36765
|
-
}
|
|
36766
|
-
stateStack.push({ ...st, ctm: nextCtm, ...nextClip ? { clipRect: nextClip } : {} });
|
|
36767
|
-
walkNodes(formNodes, mcid, actualText, formResDict, formFonts, depth + 1);
|
|
36768
|
-
if (stateStack.length > 1) stateStack.pop();
|
|
36844
|
+
paintForm(xobjNode, activeResources, activeFonts, depth, mcid, actualText);
|
|
36769
36845
|
}
|
|
36770
36846
|
}
|
|
36771
36847
|
}
|
|
@@ -36984,7 +37060,7 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36984
37060
|
st.textRenderMode = cmd.mode;
|
|
36985
37061
|
break;
|
|
36986
37062
|
case "state-op":
|
|
36987
|
-
applyStateOperator(st, cmd.operator, cmd.operands, activeResources);
|
|
37063
|
+
applyStateOperator(st, cmd.operator, cmd.operands, activeResources, activeFonts, depth);
|
|
36988
37064
|
break;
|
|
36989
37065
|
case "show-text":
|
|
36990
37066
|
emitTokenBytes(cmd.token.bytes);
|
|
@@ -39288,6 +39364,184 @@ function downscaleImage(image, widthScale, heightScale) {
|
|
|
39288
39364
|
}
|
|
39289
39365
|
return image;
|
|
39290
39366
|
}
|
|
39367
|
+
var MAX_STROKE_VERTICES = 1e6;
|
|
39368
|
+
function dashSubpath(path, pattern, phase) {
|
|
39369
|
+
const cycle = pattern.reduce((sum, value) => sum + value, 0);
|
|
39370
|
+
if (!(cycle > 0)) return [path];
|
|
39371
|
+
let offset = (phase % cycle + cycle) % cycle, index = 0;
|
|
39372
|
+
while (offset > 0) {
|
|
39373
|
+
if (offset < pattern[index]) break;
|
|
39374
|
+
offset -= pattern[index];
|
|
39375
|
+
index = (index + 1) % pattern.length;
|
|
39376
|
+
}
|
|
39377
|
+
let remaining = pattern[index] - offset;
|
|
39378
|
+
const points = path.closed ? [...path.points, path.points[0]] : path.points;
|
|
39379
|
+
const result = [];
|
|
39380
|
+
let current = [];
|
|
39381
|
+
let steps = 0;
|
|
39382
|
+
const flush = () => {
|
|
39383
|
+
if (current.length) result.push({ points: current, closed: false });
|
|
39384
|
+
current = [];
|
|
39385
|
+
};
|
|
39386
|
+
const advance = (point) => {
|
|
39387
|
+
while (remaining <= 0) {
|
|
39388
|
+
if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39389
|
+
if (index % 2 === 0) {
|
|
39390
|
+
if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
|
|
39391
|
+
flush();
|
|
39392
|
+
}
|
|
39393
|
+
index = (index + 1) % pattern.length;
|
|
39394
|
+
remaining = pattern[index];
|
|
39395
|
+
}
|
|
39396
|
+
};
|
|
39397
|
+
for (let i = 1; i < points.length; i++) {
|
|
39398
|
+
const start = points[i - 1], end = points[i];
|
|
39399
|
+
const dx = end[0] - start[0], dy = end[1] - start[1];
|
|
39400
|
+
const length = Math.hypot(dx, dy);
|
|
39401
|
+
if (!Number.isFinite(length) || length / cycle * pattern.length > MAX_STROKE_VERTICES) {
|
|
39402
|
+
throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39403
|
+
}
|
|
39404
|
+
let distance = 0;
|
|
39405
|
+
while (distance < length) {
|
|
39406
|
+
const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
|
|
39407
|
+
advance(point);
|
|
39408
|
+
const step = Math.min(remaining, length - distance);
|
|
39409
|
+
if (distance + step === distance || ++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39410
|
+
distance += step;
|
|
39411
|
+
remaining -= step;
|
|
39412
|
+
if (index % 2 === 0) {
|
|
39413
|
+
if (!current.length) current.push(point);
|
|
39414
|
+
current.push([start[0] + dx * distance / length, start[1] + dy * distance / length]);
|
|
39415
|
+
}
|
|
39416
|
+
}
|
|
39417
|
+
}
|
|
39418
|
+
flush();
|
|
39419
|
+
if (path.closed && result.length) {
|
|
39420
|
+
const first = result[0], last = result[result.length - 1];
|
|
39421
|
+
const start = path.points[0];
|
|
39422
|
+
const firstPoint = first.points[0], lastPoint = last.points[last.points.length - 1];
|
|
39423
|
+
if (firstPoint[0] === start[0] && firstPoint[1] === start[1] && lastPoint[0] === start[0] && lastPoint[1] === start[1]) {
|
|
39424
|
+
if (first === last) result[0] = { points: first.points, closed: true };
|
|
39425
|
+
else {
|
|
39426
|
+
result[0] = { points: [...last.points, ...first.points.slice(1)], closed: false };
|
|
39427
|
+
result.pop();
|
|
39428
|
+
}
|
|
39429
|
+
}
|
|
39430
|
+
}
|
|
39431
|
+
return result;
|
|
39432
|
+
}
|
|
39433
|
+
function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], dashPhase = 0) {
|
|
39434
|
+
const half = width / 2;
|
|
39435
|
+
const contours = [];
|
|
39436
|
+
const pattern = dashArray.length % 2 ? [...dashArray, ...dashArray] : dashArray;
|
|
39437
|
+
let count = 0;
|
|
39438
|
+
let contour = [];
|
|
39439
|
+
const add = (x, y) => {
|
|
39440
|
+
if (++count > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke outline exceeds the vertex limit");
|
|
39441
|
+
contour.push([x, y]);
|
|
39442
|
+
};
|
|
39443
|
+
const arc = (point, dx1, dy1, dx2, dy2) => {
|
|
39444
|
+
let a1 = Math.atan2(dy1, dx1), a2 = Math.atan2(dy2, dx2);
|
|
39445
|
+
const ccw = a1 - a2 > 0 && a1 - a2 < Math.PI;
|
|
39446
|
+
const step = Math.acos(half / (half + 0.125)) * 2;
|
|
39447
|
+
add(point[0] + dx1, point[1] + dy1);
|
|
39448
|
+
if (step > 0) {
|
|
39449
|
+
if (!ccw) {
|
|
39450
|
+
if (a1 > a2) a2 += 2 * Math.PI;
|
|
39451
|
+
a2 -= step / 4;
|
|
39452
|
+
if ((a2 - a1) / step > MAX_STROKE_VERTICES - count) throw new PdfError("E_LIMIT", "Stroke arc exceeds the vertex limit");
|
|
39453
|
+
for (a1 += step; a1 < a2; a1 += step) add(point[0] + half * Math.cos(a1), point[1] + half * Math.sin(a1));
|
|
39454
|
+
} else {
|
|
39455
|
+
if (a1 < a2) a2 -= 2 * Math.PI;
|
|
39456
|
+
a2 += step / 4;
|
|
39457
|
+
if ((a1 - a2) / step > MAX_STROKE_VERTICES - count) throw new PdfError("E_LIMIT", "Stroke arc exceeds the vertex limit");
|
|
39458
|
+
for (a1 -= step; a1 > a2; a1 -= step) add(point[0] + half * Math.cos(a1), point[1] + half * Math.sin(a1));
|
|
39459
|
+
}
|
|
39460
|
+
}
|
|
39461
|
+
add(point[0] + dx2, point[1] + dy2);
|
|
39462
|
+
};
|
|
39463
|
+
const addCap = (point, next) => {
|
|
39464
|
+
const length = Math.hypot(next[0] - point[0], next[1] - point[1]);
|
|
39465
|
+
const dx = half * (next[1] - point[1]) / length;
|
|
39466
|
+
const dy = half * (next[0] - point[0]) / length;
|
|
39467
|
+
if (cap !== 1) {
|
|
39468
|
+
const sx = cap === 2 ? dy : 0, sy = cap === 2 ? dx : 0;
|
|
39469
|
+
add(point[0] - dx - sx, point[1] + dy - sy);
|
|
39470
|
+
add(point[0] + dx - sx, point[1] - dy - sy);
|
|
39471
|
+
} else {
|
|
39472
|
+
const angle = Math.atan2(dy, -dx);
|
|
39473
|
+
const step = Math.max(1e-3, Math.acos(half / (half + 0.125)) * 2);
|
|
39474
|
+
add(point[0] - dx, point[1] + dy);
|
|
39475
|
+
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));
|
|
39476
|
+
add(point[0] + dx, point[1] - dy);
|
|
39477
|
+
}
|
|
39478
|
+
};
|
|
39479
|
+
const addJoin = (prev, point, next) => {
|
|
39480
|
+
const len1 = Math.hypot(point[0] - prev[0], point[1] - prev[1]);
|
|
39481
|
+
const len2 = Math.hypot(next[0] - point[0], next[1] - point[1]);
|
|
39482
|
+
const dx1 = half * (point[1] - prev[1]) / len1, dy1 = half * (point[0] - prev[0]) / len1;
|
|
39483
|
+
const dx2 = half * (next[1] - point[1]) / len2, dy2 = half * (next[0] - point[0]) / len2;
|
|
39484
|
+
const inner = (next[0] - point[0]) * (point[1] - prev[1]) - (next[1] - point[1]) * (point[0] - prev[0]) > 0;
|
|
39485
|
+
if (!inner && join === 1) {
|
|
39486
|
+
arc(point, dx1, -dy1, dx2, -dy2);
|
|
39487
|
+
return;
|
|
39488
|
+
}
|
|
39489
|
+
if (inner || join === 0) {
|
|
39490
|
+
const ax = prev[0] + dx1, ay = prev[1] - dy1;
|
|
39491
|
+
const bx = point[0] + dx1, by = point[1] - dy1;
|
|
39492
|
+
const cx = point[0] + dx2, cy = point[1] - dy2;
|
|
39493
|
+
const dx = next[0] + dx2, dy = next[1] - dy2;
|
|
39494
|
+
const den = (bx - ax) * (dy - cy) - (by - ay) * (dx - cx);
|
|
39495
|
+
if (Math.abs(den) >= 1e-30) {
|
|
39496
|
+
const t = ((ay - cy) * (dx - cx) - (ax - cx) * (dy - cy)) / den;
|
|
39497
|
+
const x = ax + (bx - ax) * t, y = ay + (by - ay) * t;
|
|
39498
|
+
if (Math.hypot(x - point[0], y - point[1]) <= half * (inner ? 1.01 : miterLimit)) {
|
|
39499
|
+
add(x, y);
|
|
39500
|
+
return;
|
|
39501
|
+
}
|
|
39502
|
+
} else if ((bx - prev[0]) * dy1 - (prev[1] - by) * dx1 < 0 !== (bx - next[0]) * dy1 - (next[1] - by) * dx1 < 0) {
|
|
39503
|
+
add(bx, by);
|
|
39504
|
+
return;
|
|
39505
|
+
}
|
|
39506
|
+
}
|
|
39507
|
+
add(point[0] + dx1, point[1] - dy1);
|
|
39508
|
+
add(point[0] + dx2, point[1] - dy2);
|
|
39509
|
+
};
|
|
39510
|
+
for (const path of paths) {
|
|
39511
|
+
for (const subpath of pattern.length ? dashSubpath(path, pattern, dashPhase) : [path]) {
|
|
39512
|
+
const points = [];
|
|
39513
|
+
for (const point of subpath.points) {
|
|
39514
|
+
const prev = points[points.length - 1];
|
|
39515
|
+
if (!prev || Math.hypot(prev[0] - point[0], prev[1] - point[1]) > 1e-14) points.push(point);
|
|
39516
|
+
}
|
|
39517
|
+
let closed = subpath.closed;
|
|
39518
|
+
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();
|
|
39519
|
+
if (points.length < 3) closed = false;
|
|
39520
|
+
if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
|
|
39521
|
+
contour = [];
|
|
39522
|
+
const [x, y] = points[0];
|
|
39523
|
+
addCap([x, y], [x + 1, y]);
|
|
39524
|
+
addCap([x, y], [x - 1, y]);
|
|
39525
|
+
contours.push(contour);
|
|
39526
|
+
} else if (points.length >= 2) {
|
|
39527
|
+
contour = [];
|
|
39528
|
+
if (!closed) addCap(points[0], points[1]);
|
|
39529
|
+
for (let i = closed ? 0 : 1; i < points.length - (closed ? 0 : 1); i++) {
|
|
39530
|
+
addJoin(points[(i + points.length - 1) % points.length], points[i], points[(i + 1) % points.length]);
|
|
39531
|
+
}
|
|
39532
|
+
if (closed) {
|
|
39533
|
+
contours.push(contour);
|
|
39534
|
+
contour = [];
|
|
39535
|
+
} else addCap(points[points.length - 1], points[points.length - 2]);
|
|
39536
|
+
for (let i = points.length - (closed ? 1 : 2); i >= (closed ? 0 : 1); i--) {
|
|
39537
|
+
addJoin(points[(i + 1) % points.length], points[i], points[(i + points.length - 1) % points.length]);
|
|
39538
|
+
}
|
|
39539
|
+
contours.push(contour);
|
|
39540
|
+
}
|
|
39541
|
+
}
|
|
39542
|
+
}
|
|
39543
|
+
return contours;
|
|
39544
|
+
}
|
|
39291
39545
|
function encodePng(bitmap) {
|
|
39292
39546
|
return encodeRgbaToPng(bitmap.width, bitmap.height, bitmap.data);
|
|
39293
39547
|
}
|
|
@@ -40378,111 +40632,60 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
|
|
|
40378
40632
|
rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
|
|
40379
40633
|
rgba[idx + 3] = Math.round(outA * 255);
|
|
40380
40634
|
}
|
|
40381
|
-
function
|
|
40382
|
-
const
|
|
40383
|
-
|
|
40384
|
-
|
|
40385
|
-
const lenSq = dx * dx + dy * dy;
|
|
40386
|
-
const segLen = Math.sqrt(lenSq);
|
|
40387
|
-
const pad = lineCap === 2 ? halfW + 2 : halfW + 1;
|
|
40388
|
-
const minX = Math.max(0, Math.floor(Math.min(x0, x1) - pad));
|
|
40389
|
-
const maxX = Math.min(width - 1, Math.ceil(Math.max(x0, x1) + pad));
|
|
40390
|
-
const minY = Math.max(0, Math.floor(Math.min(y0, y1) - pad));
|
|
40391
|
-
const maxY = Math.min(height - 1, Math.ceil(Math.max(y0, y1) + pad));
|
|
40392
|
-
for (let py = minY; py <= maxY; py++) {
|
|
40393
|
-
for (let px = minX; px <= maxX; px++) {
|
|
40394
|
-
const cx = px + 0.5;
|
|
40395
|
-
const cy = py + 0.5;
|
|
40396
|
-
if (segLen > 1e-6 && (lineCap === 0 || lineCap === 2)) {
|
|
40397
|
-
const ux = dx / segLen;
|
|
40398
|
-
const uy = dy / segLen;
|
|
40399
|
-
const along = (cx - x0) * ux + (cy - y0) * uy;
|
|
40400
|
-
const perp = Math.abs(-(cx - x0) * uy + (cy - y0) * ux);
|
|
40401
|
-
const minAlong = lineCap === 2 ? -halfW : 0;
|
|
40402
|
-
const maxAlong = lineCap === 2 ? segLen + halfW : segLen;
|
|
40403
|
-
const overAlong = along < minAlong ? minAlong - along : along > maxAlong ? along - maxAlong : 0;
|
|
40404
|
-
const dist2 = overAlong > 0 ? Math.max(perp, halfW + overAlong) : perp;
|
|
40405
|
-
if (dist2 <= halfW + 0.75) {
|
|
40406
|
-
const cov = antialias ? Math.max(0, Math.min(1, halfW + 0.5 - dist2)) : dist2 <= halfW + 0.25 ? 1 : 0;
|
|
40407
|
-
blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask);
|
|
40408
|
-
}
|
|
40409
|
-
continue;
|
|
40410
|
-
}
|
|
40411
|
-
let t = lenSq > 1e-6 ? ((cx - x0) * dx + (cy - y0) * dy) / lenSq : 0;
|
|
40412
|
-
t = Math.max(0, Math.min(1, t));
|
|
40413
|
-
const projX = x0 + t * dx;
|
|
40414
|
-
const projY = y0 + t * dy;
|
|
40415
|
-
const dist = Math.hypot(cx - projX, cy - projY);
|
|
40416
|
-
if (dist <= halfW + 0.75) {
|
|
40417
|
-
const cov = antialias ? Math.max(0, Math.min(1, halfW + 0.5 - dist)) : dist <= halfW + 0.25 ? 1 : 0;
|
|
40418
|
-
blendPixel(rgba, width, height, px, py, color, cov * alpha, blendMode, clipMask);
|
|
40419
|
-
}
|
|
40420
|
-
}
|
|
40421
|
-
}
|
|
40422
|
-
}
|
|
40423
|
-
function segmentsToScreenEdges(segments, pageHeight, scale, closeSubpaths = false) {
|
|
40424
|
-
const edges = [];
|
|
40425
|
-
let curX = 0;
|
|
40426
|
-
let curY = 0;
|
|
40427
|
-
let startX = 0;
|
|
40428
|
-
let startY = 0;
|
|
40429
|
-
let hasOpenSubpath = false;
|
|
40635
|
+
function segmentsToScreenPaths(segments, pageHeight, scale) {
|
|
40636
|
+
const paths = [];
|
|
40637
|
+
let points = [];
|
|
40638
|
+
let current = [0, 0];
|
|
40430
40639
|
const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
|
|
40431
|
-
for (const
|
|
40432
|
-
if (
|
|
40433
|
-
if (
|
|
40434
|
-
|
|
40435
|
-
|
|
40436
|
-
|
|
40437
|
-
|
|
40438
|
-
|
|
40439
|
-
|
|
40440
|
-
} else if (
|
|
40441
|
-
|
|
40442
|
-
|
|
40443
|
-
|
|
40444
|
-
|
|
40445
|
-
|
|
40446
|
-
|
|
40447
|
-
|
|
40448
|
-
|
|
40449
|
-
|
|
40450
|
-
|
|
40451
|
-
|
|
40452
|
-
|
|
40453
|
-
|
|
40454
|
-
|
|
40455
|
-
|
|
40456
|
-
|
|
40457
|
-
|
|
40458
|
-
|
|
40459
|
-
|
|
40460
|
-
|
|
40461
|
-
|
|
40462
|
-
|
|
40463
|
-
|
|
40464
|
-
|
|
40465
|
-
|
|
40466
|
-
|
|
40467
|
-
|
|
40468
|
-
|
|
40469
|
-
|
|
40470
|
-
|
|
40471
|
-
|
|
40472
|
-
|
|
40473
|
-
const [
|
|
40474
|
-
|
|
40475
|
-
|
|
40476
|
-
|
|
40477
|
-
|
|
40478
|
-
|
|
40479
|
-
{ x0: rx0, y0: ry1, x1: rx0, y1: ry0 }
|
|
40480
|
-
);
|
|
40481
|
-
hasOpenSubpath = false;
|
|
40640
|
+
for (const segment of segments) {
|
|
40641
|
+
if (segment.kind === "move") {
|
|
40642
|
+
if (points.length) paths.push({ points, closed: false });
|
|
40643
|
+
current = toScreen(segment.x, segment.y);
|
|
40644
|
+
points = [current];
|
|
40645
|
+
} else if (segment.kind === "line") {
|
|
40646
|
+
if (!points.length) points = [current];
|
|
40647
|
+
current = toScreen(segment.x, segment.y);
|
|
40648
|
+
points.push(current);
|
|
40649
|
+
} else if (segment.kind === "cubic") {
|
|
40650
|
+
if (!points.length) points = [current];
|
|
40651
|
+
const a = toScreen(segment.x1, segment.y1), b = toScreen(segment.x2, segment.y2);
|
|
40652
|
+
const end = toScreen(segment.x, segment.y);
|
|
40653
|
+
const curve = flattenCubic(current[0], current[1], a[0], a[1], b[0], b[1], end[0], end[1]);
|
|
40654
|
+
for (let i = 1; i < curve.length; i++) points.push(curve[i]);
|
|
40655
|
+
current = end;
|
|
40656
|
+
} else if (segment.kind === "close") {
|
|
40657
|
+
if (points.length) {
|
|
40658
|
+
paths.push({ points, closed: true });
|
|
40659
|
+
current = points[0];
|
|
40660
|
+
points = [];
|
|
40661
|
+
}
|
|
40662
|
+
} else if (segment.kind === "rect") {
|
|
40663
|
+
if (points.length) paths.push({ points, closed: false });
|
|
40664
|
+
const first = toScreen(segment.x, segment.y);
|
|
40665
|
+
paths.push({ points: [
|
|
40666
|
+
first,
|
|
40667
|
+
toScreen(segment.x + segment.width, segment.y),
|
|
40668
|
+
toScreen(segment.x + segment.width, segment.y + segment.height),
|
|
40669
|
+
toScreen(segment.x, segment.y + segment.height)
|
|
40670
|
+
], closed: true });
|
|
40671
|
+
current = first;
|
|
40672
|
+
points = [];
|
|
40673
|
+
}
|
|
40674
|
+
}
|
|
40675
|
+
if (points.length) paths.push({ points, closed: false });
|
|
40676
|
+
return paths;
|
|
40677
|
+
}
|
|
40678
|
+
function pathsToEdges(paths, closeSubpaths = false) {
|
|
40679
|
+
const edges = [];
|
|
40680
|
+
for (const { points, closed } of paths) {
|
|
40681
|
+
for (let i = 1; i < points.length; i++) {
|
|
40682
|
+
const a = points[i - 1], b = points[i];
|
|
40683
|
+
edges.push({ x0: a[0], y0: a[1], x1: b[0], y1: b[1] });
|
|
40684
|
+
}
|
|
40685
|
+
if ((closed || closeSubpaths) && points.length > 1) {
|
|
40686
|
+
const a = points[points.length - 1], b = points[0];
|
|
40687
|
+
edges.push({ x0: a[0], y0: a[1], x1: b[0], y1: b[1] });
|
|
40482
40688
|
}
|
|
40483
|
-
}
|
|
40484
|
-
if (closeSubpaths && hasOpenSubpath && (curX !== startX || curY !== startY)) {
|
|
40485
|
-
edges.push({ x0: curX, y0: curY, x1: startX, y1: startY });
|
|
40486
40689
|
}
|
|
40487
40690
|
return edges;
|
|
40488
40691
|
}
|
|
@@ -40593,6 +40796,30 @@ function paintOperations(displayList) {
|
|
|
40593
40796
|
...displayList.glyphs.map((value) => ({ kind: "glyph", value }))
|
|
40594
40797
|
];
|
|
40595
40798
|
}
|
|
40799
|
+
function renderSoftMask(mask, displayList, scale) {
|
|
40800
|
+
const bitmap = renderDisplayListToBitmap({
|
|
40801
|
+
...displayList,
|
|
40802
|
+
rotation: 0,
|
|
40803
|
+
glyphs: [],
|
|
40804
|
+
paths: [],
|
|
40805
|
+
images: [],
|
|
40806
|
+
operations: mask.operations
|
|
40807
|
+
}, { scale, transparent: true });
|
|
40808
|
+
const { data } = bitmap;
|
|
40809
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
40810
|
+
let value = data[i + 3];
|
|
40811
|
+
if (mask.subtype === "Luminosity") {
|
|
40812
|
+
const alpha = value / 255;
|
|
40813
|
+
const r = Math.round(data[i] * alpha + mask.backdrop.r * 255 * (1 - alpha));
|
|
40814
|
+
const g = Math.round(data[i + 1] * alpha + mask.backdrop.g * 255 * (1 - alpha));
|
|
40815
|
+
const b = Math.round(data[i + 2] * alpha + mask.backdrop.b * 255 * (1 - alpha));
|
|
40816
|
+
value = Math.round(pdfLum(r, g, b));
|
|
40817
|
+
}
|
|
40818
|
+
data[i] = data[i + 1] = data[i + 2] = 0;
|
|
40819
|
+
data[i + 3] = mask.transferMap?.[value] ?? value;
|
|
40820
|
+
}
|
|
40821
|
+
return bitmap;
|
|
40822
|
+
}
|
|
40596
40823
|
function renderDisplayListToBitmap(displayList, options = {}) {
|
|
40597
40824
|
const baseScale = options.scale ?? (options.dpi ? options.dpi / 72 : 1.5);
|
|
40598
40825
|
const scaleX = options.dpiX !== void 0 ? options.dpiX / 72 : baseScale;
|
|
@@ -40616,10 +40843,28 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40616
40843
|
const aaTxt = options.antialiasText !== false;
|
|
40617
40844
|
let cachedClips;
|
|
40618
40845
|
let cachedClipMask;
|
|
40846
|
+
let cachedSoftMask;
|
|
40847
|
+
let cachedSoftMaskPixels;
|
|
40619
40848
|
const imageClipMasks = /* @__PURE__ */ new Map();
|
|
40620
40849
|
for (const original of paintOperations(displayList)) {
|
|
40621
40850
|
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
40622
|
-
|
|
40851
|
+
let operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
40852
|
+
if (operation.kind === "group") {
|
|
40853
|
+
const group = operation.value;
|
|
40854
|
+
const bitmap = renderDisplayListToBitmap({ ...displayList, rotation: 0, operations: group.operations }, { ...options, scale, dpiX: void 0, dpiY: void 0, cropRect: void 0, transparent: true });
|
|
40855
|
+
for (let i = 3; i < bitmap.data.length; i += 4) bitmap.data[i] = Math.round(bitmap.data[i] * group.alpha);
|
|
40856
|
+
operation = { kind: "image", value: {
|
|
40857
|
+
name: "TransparencyGroup",
|
|
40858
|
+
width: bitmap.width,
|
|
40859
|
+
height: bitmap.height,
|
|
40860
|
+
decodedRgba: bitmap.data,
|
|
40861
|
+
matrix: [bitmap.width / scale, 0, 0, bitmap.height / scale, 0, displayList.height - bitmap.height / scale],
|
|
40862
|
+
colorSpace: "DeviceRGB",
|
|
40863
|
+
bitsPerComponent: 8,
|
|
40864
|
+
blendMode: group.blendMode,
|
|
40865
|
+
clipRect: group.clipRect
|
|
40866
|
+
} };
|
|
40867
|
+
}
|
|
40623
40868
|
const clips = original.value.clipPaths;
|
|
40624
40869
|
let clipMask = clips && clips === cachedClips ? cachedClipMask : void 0;
|
|
40625
40870
|
if (clips && !clipMask) {
|
|
@@ -40627,12 +40872,25 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40627
40872
|
for (const clip of clips) {
|
|
40628
40873
|
const { segments, fillRule } = "segments" in clip ? clip : { segments: clip, fillRule: "nonzero" };
|
|
40629
40874
|
const layer = new Uint8Array(width * height * 4);
|
|
40630
|
-
fillEdgesScanline4x4(layer, width, height,
|
|
40875
|
+
fillEdgesScanline4x4(layer, width, height, pathsToEdges(segmentsToScreenPaths(segments, displayList.height, scale), true), { r: 1, g: 1, b: 1 }, 1, fillRule);
|
|
40631
40876
|
for (let i = 3; i < layer.length; i += 4) clipMask[i] = Math.round(clipMask[i] * layer[i] / 255);
|
|
40632
40877
|
}
|
|
40633
40878
|
cachedClips = clips;
|
|
40634
40879
|
cachedClipMask = clipMask;
|
|
40635
40880
|
}
|
|
40881
|
+
const softMask = original.value.softMask;
|
|
40882
|
+
if (softMask) {
|
|
40883
|
+
if (softMask !== cachedSoftMask) {
|
|
40884
|
+
cachedSoftMaskPixels = renderSoftMask(softMask, displayList, scale).data;
|
|
40885
|
+
cachedSoftMask = softMask;
|
|
40886
|
+
}
|
|
40887
|
+
if (clipMask) {
|
|
40888
|
+
clipMask = clipMask.slice();
|
|
40889
|
+
for (let i = 3; i < clipMask.length; i += 4) clipMask[i] = Math.round(clipMask[i] * cachedSoftMaskPixels[i] / 255);
|
|
40890
|
+
} else {
|
|
40891
|
+
clipMask = cachedSoftMaskPixels;
|
|
40892
|
+
}
|
|
40893
|
+
}
|
|
40636
40894
|
const imageClips = original.value.clipImages;
|
|
40637
40895
|
if (imageClips) {
|
|
40638
40896
|
let imageMask = imageClipMasks.get(imageClips);
|
|
@@ -40661,62 +40919,38 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40661
40919
|
if (operation.kind === "path") {
|
|
40662
40920
|
const path = operation.value;
|
|
40663
40921
|
if (path.fillColor) {
|
|
40664
|
-
const edges =
|
|
40922
|
+
const edges = pathsToEdges(segmentsToScreenPaths(path.segments, displayList.height, scale), true);
|
|
40665
40923
|
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;
|
|
40666
40924
|
fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
|
|
40667
40925
|
}
|
|
40668
40926
|
if (path.strokeColor) {
|
|
40669
|
-
const edges = segmentsToScreenEdges(path.segments, displayList.height, scale, false);
|
|
40670
40927
|
const rawSw = path.strokeWidth * scale;
|
|
40671
40928
|
const sw = Math.max(1, rawSw);
|
|
40672
40929
|
const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
|
|
40673
|
-
const
|
|
40674
|
-
|
|
40675
|
-
|
|
40676
|
-
|
|
40677
|
-
|
|
40678
|
-
|
|
40679
|
-
|
|
40680
|
-
|
|
40681
|
-
|
|
40682
|
-
|
|
40683
|
-
|
|
40684
|
-
|
|
40685
|
-
|
|
40686
|
-
|
|
40687
|
-
|
|
40688
|
-
|
|
40689
|
-
|
|
40690
|
-
|
|
40691
|
-
|
|
40692
|
-
|
|
40693
|
-
|
|
40694
|
-
|
|
40695
|
-
|
|
40696
|
-
|
|
40697
|
-
const t1 = (pos + step) / edgeLen;
|
|
40698
|
-
drawAntiAliasedSegment(
|
|
40699
|
-
rgba,
|
|
40700
|
-
width,
|
|
40701
|
-
height,
|
|
40702
|
-
e.x0 + dx * t0,
|
|
40703
|
-
e.y0 + dy * t0,
|
|
40704
|
-
e.x0 + dx * t1,
|
|
40705
|
-
e.y0 + dy * t1,
|
|
40706
|
-
sw,
|
|
40707
|
-
path.strokeColor,
|
|
40708
|
-
strokeAlpha,
|
|
40709
|
-
path.lineCap ?? 0,
|
|
40710
|
-
original.kind === "glyph" ? aaTxt : aaVec,
|
|
40711
|
-
path.blendMode,
|
|
40712
|
-
clipMask
|
|
40713
|
-
);
|
|
40714
|
-
}
|
|
40715
|
-
pos += step;
|
|
40716
|
-
dashDist = (dashDist + step) % dashCycle;
|
|
40717
|
-
}
|
|
40718
|
-
}
|
|
40719
|
-
}
|
|
40930
|
+
const contours = strokeOutlines(
|
|
40931
|
+
segmentsToScreenPaths(path.segments, displayList.height, scale),
|
|
40932
|
+
sw,
|
|
40933
|
+
path.lineCap ?? 0,
|
|
40934
|
+
path.lineJoin ?? 0,
|
|
40935
|
+
path.miterLimit ?? 10,
|
|
40936
|
+
path.dashArray?.map((value) => Math.max(0, value * scale)),
|
|
40937
|
+
(path.dashPhase ?? 0) * scale
|
|
40938
|
+
);
|
|
40939
|
+
const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
|
|
40940
|
+
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;
|
|
40941
|
+
fillEdgesScanline4x4(
|
|
40942
|
+
rgba,
|
|
40943
|
+
width,
|
|
40944
|
+
height,
|
|
40945
|
+
edges,
|
|
40946
|
+
path.strokeColor,
|
|
40947
|
+
strokeAlpha,
|
|
40948
|
+
"nonzero",
|
|
40949
|
+
clipScreen,
|
|
40950
|
+
original.kind === "glyph" ? aaTxt : aaVec,
|
|
40951
|
+
path.blendMode,
|
|
40952
|
+
clipMask
|
|
40953
|
+
);
|
|
40720
40954
|
}
|
|
40721
40955
|
} else if (operation.kind === "image") {
|
|
40722
40956
|
const img = operation.value;
|
|
@@ -40814,6 +41048,27 @@ function renderDisplayListToPng(displayList, options = {}) {
|
|
|
40814
41048
|
const bmp = renderDisplayListToBitmap(displayList, options);
|
|
40815
41049
|
return encodeRgbaToPng(bmp.width, bmp.height, bmp.data);
|
|
40816
41050
|
}
|
|
41051
|
+
function pdfBlendModeToCss(mode) {
|
|
41052
|
+
if (!mode || mode === "Normal" || mode === "Compatible") return void 0;
|
|
41053
|
+
const map = {
|
|
41054
|
+
Multiply: "multiply",
|
|
41055
|
+
Screen: "screen",
|
|
41056
|
+
Overlay: "overlay",
|
|
41057
|
+
Darken: "darken",
|
|
41058
|
+
Lighten: "lighten",
|
|
41059
|
+
ColorDodge: "color-dodge",
|
|
41060
|
+
ColorBurn: "color-burn",
|
|
41061
|
+
HardLight: "hard-light",
|
|
41062
|
+
SoftLight: "soft-light",
|
|
41063
|
+
Difference: "difference",
|
|
41064
|
+
Exclusion: "exclusion",
|
|
41065
|
+
Hue: "hue",
|
|
41066
|
+
Saturation: "saturation",
|
|
41067
|
+
Color: "color",
|
|
41068
|
+
Luminosity: "luminosity"
|
|
41069
|
+
};
|
|
41070
|
+
return map[mode];
|
|
41071
|
+
}
|
|
40817
41072
|
function escapeXmlText(str) {
|
|
40818
41073
|
let valid = "";
|
|
40819
41074
|
for (const char of str) {
|
|
@@ -40875,44 +41130,74 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
40875
41130
|
parts.push(`<g transform="matrix(${a} ${b} ${-c} ${-d} ${e + c * displayList.height} ${f + d * displayList.height})">`);
|
|
40876
41131
|
}
|
|
40877
41132
|
let clipId = 0;
|
|
40878
|
-
|
|
40879
|
-
|
|
40880
|
-
const
|
|
40881
|
-
|
|
40882
|
-
|
|
40883
|
-
|
|
40884
|
-
const
|
|
40885
|
-
const
|
|
40886
|
-
|
|
40887
|
-
|
|
40888
|
-
|
|
40889
|
-
|
|
40890
|
-
|
|
40891
|
-
|
|
40892
|
-
|
|
40893
|
-
|
|
40894
|
-
|
|
40895
|
-
|
|
40896
|
-
|
|
40897
|
-
|
|
40898
|
-
|
|
40899
|
-
|
|
40900
|
-
|
|
40901
|
-
|
|
40902
|
-
|
|
40903
|
-
|
|
40904
|
-
|
|
40905
|
-
|
|
40906
|
-
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
40907
|
-
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
40908
|
-
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
40909
|
-
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
41133
|
+
const softMaskIds = /* @__PURE__ */ new Map();
|
|
41134
|
+
const appendOperations = (operations) => {
|
|
41135
|
+
for (const original of operations) {
|
|
41136
|
+
if (original.kind === "glyph" && (original.value.renderMode === 3 || !original.value.outline && !original.value.unicode.trim())) continue;
|
|
41137
|
+
const operation = original.kind === "glyph" ? { kind: "path", value: glyphPaint(original.value) } : original;
|
|
41138
|
+
const clips = original.value.clipPaths ?? [];
|
|
41139
|
+
const imageClips = original.value.clipImages ?? [];
|
|
41140
|
+
const blend = pdfBlendModeToCss(original.value.blendMode);
|
|
41141
|
+
if (blend) parts.push(`<g style="mix-blend-mode:${blend}">`);
|
|
41142
|
+
const softMask = original.value.softMask;
|
|
41143
|
+
if (softMask) {
|
|
41144
|
+
let id = softMaskIds.get(softMask);
|
|
41145
|
+
if (!id) {
|
|
41146
|
+
id = `soft-mask-${clipId++}`;
|
|
41147
|
+
softMaskIds.set(softMask, id);
|
|
41148
|
+
const bitmap = renderSoftMask(softMask, displayList, Math.max(scaleX, scaleY));
|
|
41149
|
+
const image = {
|
|
41150
|
+
name: id,
|
|
41151
|
+
width: bitmap.width,
|
|
41152
|
+
height: bitmap.height,
|
|
41153
|
+
decodedRgba: bitmap.data,
|
|
41154
|
+
matrix: [displayList.width, 0, 0, displayList.height, 0, 0],
|
|
41155
|
+
colorSpace: "DeviceGray",
|
|
41156
|
+
bitsPerComponent: 8
|
|
41157
|
+
};
|
|
41158
|
+
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>`);
|
|
41159
|
+
}
|
|
41160
|
+
parts.push(`<g mask="url(#${id})">`);
|
|
40910
41161
|
}
|
|
40911
|
-
|
|
40912
|
-
|
|
41162
|
+
for (const clip of clips) {
|
|
41163
|
+
const { segments, fillRule } = "segments" in clip ? clip : { segments: clip, fillRule: "nonzero" };
|
|
41164
|
+
const id = `text-clip-${clipId++}`;
|
|
41165
|
+
const path = `<path d="${svgPathData(segments, displayList.height)}" clip-rule="${fillRule}"/>`;
|
|
41166
|
+
parts.push(`<defs><clipPath id="${id}" clipPathUnits="userSpaceOnUse">${path}</clipPath></defs><g clip-path="url(#${id})">`);
|
|
41167
|
+
}
|
|
41168
|
+
for (const image of imageClips) {
|
|
41169
|
+
const id = `image-clip-${clipId++}`;
|
|
41170
|
+
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})">`);
|
|
41171
|
+
}
|
|
41172
|
+
if (operation.kind === "group") {
|
|
41173
|
+
parts.push(`<g opacity="${operation.value.alpha}" style="isolation:isolate">`);
|
|
41174
|
+
appendOperations(operation.value.operations);
|
|
41175
|
+
parts.push("</g>");
|
|
41176
|
+
} else if (operation.kind === "path") {
|
|
41177
|
+
const p = operation.value;
|
|
41178
|
+
const pathData = svgPathData(p.segments, displayList.height);
|
|
41179
|
+
if (pathData) {
|
|
41180
|
+
const fill = p.fillColor ? `rgb(${Math.round(p.fillColor.r * 255)},${Math.round(p.fillColor.g * 255)},${Math.round(p.fillColor.b * 255)})` : "none";
|
|
41181
|
+
const stroke = p.strokeColor ? `rgb(${Math.round(p.strokeColor.r * 255)},${Math.round(p.strokeColor.g * 255)},${Math.round(p.strokeColor.b * 255)})` : "none";
|
|
41182
|
+
const fillRuleAttr = p.fillRule === "evenodd" ? ` fill-rule="evenodd"` : "";
|
|
41183
|
+
const fillOpacityAttr = p.fillAlpha !== void 0 && p.fillAlpha < 1 ? ` fill-opacity="${p.fillAlpha}"` : "";
|
|
41184
|
+
const strokeOpacityAttr = p.strokeAlpha !== void 0 && p.strokeAlpha < 1 ? ` stroke-opacity="${p.strokeAlpha}"` : "";
|
|
41185
|
+
const strokeWidthAttr = p.strokeWidth <= 0 ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${p.strokeWidth}"`;
|
|
41186
|
+
const lineCapAttr = p.lineCap === 1 ? ` stroke-linecap="round"` : p.lineCap === 2 ? ` stroke-linecap="square"` : "";
|
|
41187
|
+
const lineJoinAttr = p.lineJoin === 1 ? ` stroke-linejoin="round"` : p.lineJoin === 2 ? ` stroke-linejoin="bevel"` : "";
|
|
41188
|
+
const miterLimitAttr = p.miterLimit !== void 0 && p.miterLimit !== 10 ? ` stroke-miterlimit="${p.miterLimit}"` : "";
|
|
41189
|
+
const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
|
|
41190
|
+
const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
|
|
41191
|
+
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
41192
|
+
parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
41193
|
+
}
|
|
41194
|
+
} else if (operation.kind === "image") {
|
|
41195
|
+
parts.push(` ${svgImage(operation.value, displayList.height)}`);
|
|
41196
|
+
}
|
|
41197
|
+
for (let i = 0; i < clips.length + imageClips.length + (softMask ? 1 : 0) + (blend ? 1 : 0); i++) parts.push("</g>");
|
|
40913
41198
|
}
|
|
40914
|
-
|
|
40915
|
-
|
|
41199
|
+
};
|
|
41200
|
+
appendOperations(paintOperations(displayList));
|
|
40916
41201
|
if (displayList.rotation) parts.push("</g>");
|
|
40917
41202
|
parts.push("</svg>\n");
|
|
40918
41203
|
return parts.join("\n");
|
|
@@ -44330,3 +44615,15 @@ export {
|
|
|
44330
44615
|
* Copyright 2012 Mozilla Foundation. Licensed under Apache-2.0.
|
|
44331
44616
|
* See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
|
|
44332
44617
|
*/
|
|
44618
|
+
/*!
|
|
44619
|
+
* Anti-Grain Geometry - Version 2.3
|
|
44620
|
+
* Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
|
44621
|
+
*
|
|
44622
|
+
* Permission to copy, use, modify, sell and distribute this software
|
|
44623
|
+
* is granted provided this copyright notice appears in all copies.
|
|
44624
|
+
* This software is provided "as is" without express or implied
|
|
44625
|
+
* warranty, and with no claim as to its suitability for any purpose.
|
|
44626
|
+
*
|
|
44627
|
+
* Adapted from PDFium agg_math_stroke.h and agg_vcgen_stroke.cpp.
|
|
44628
|
+
* See THIRD_PARTY_NOTICES.md for the source revision and adaptations.
|
|
44629
|
+
*/
|