@poe-platform/safe-bash 0.1.764 → 0.1.766
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 +80 -27
- package/dist/image-ast/index.js +80 -27
- package/dist/pdf-ast/ast.d.ts +2 -0
- package/dist/pdf-ast/index.js +106 -38
- package/dist/safe-bash/command-chunks/{chunk-B7YLGJRF.js → chunk-DKWMTHU3.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-RDPJGIQF.js → chunk-IOH3F3ZO.js} +1 -1
- package/dist/safe-bash/command-chunks/{chunk-G3IIEU2N.js → chunk-XFUFHHLU.js} +80 -27
- package/dist/safe-bash-command-ffmpeg/index.js +4270 -4240
- 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 +80 -27
- package/dist/safe-bash-command-pdfinfo/index.js +106 -38
- package/dist/safe-bash-command-pdftk/index.js +80 -27
- package/dist/safe-bash-command-pdftoppm/index.js +106 -38
- package/dist/safe-bash-command-pdftotext/index.js +80 -27
- package/dist/safe-bash-command-qpdf/index.js +80 -27
- 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 +134 -36
- package/dist/safe-bash-command-wkhtmltopdf/index.js +80 -27
- package/package.json +2 -2
- package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +13 -0
|
@@ -35704,11 +35704,10 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
35704
35704
|
} else if (operator === "d") {
|
|
35705
35705
|
const arrNode = ops[0]?.kind === "array" ? ops[0] : void 0;
|
|
35706
35706
|
if (arrNode) {
|
|
35707
|
-
const
|
|
35708
|
-
const nums = arrNode.items.map((it) => it.kind === "number" ? it.value * ctmScale : 0).filter((v) => v >= 0);
|
|
35707
|
+
const nums = arrNode.items.map((it) => it.kind === "number" ? it.value : 0).filter((v) => v >= 0);
|
|
35709
35708
|
const sum = nums.reduce((a, b) => a + b, 0);
|
|
35710
35709
|
st.dashArray = sum > 0 ? nums : void 0;
|
|
35711
|
-
st.dashPhase = num(1, 0)
|
|
35710
|
+
st.dashPhase = num(1, 0);
|
|
35712
35711
|
} else {
|
|
35713
35712
|
st.dashArray = void 0;
|
|
35714
35713
|
st.dashPhase = void 0;
|
|
@@ -35840,10 +35839,11 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
35840
35839
|
const patArr = params.cosDoc.resolveArray(dArr.items[0]);
|
|
35841
35840
|
const phaseNode = params.cosDoc.resolve(dArr.items[1]);
|
|
35842
35841
|
if (patArr) {
|
|
35843
|
-
|
|
35842
|
+
const dashArray = patArr.items.map((it) => {
|
|
35844
35843
|
const r = params.cosDoc.resolve(it);
|
|
35845
35844
|
return r?.kind === "number" ? r.value : 0;
|
|
35846
|
-
}).filter((n) => n
|
|
35845
|
+
}).filter((n) => n >= 0);
|
|
35846
|
+
st.dashArray = dashArray.some((value) => value > 0) ? dashArray : void 0;
|
|
35847
35847
|
st.dashPhase = phaseNode?.kind === "number" ? phaseNode.value : 0;
|
|
35848
35848
|
}
|
|
35849
35849
|
}
|
|
@@ -36244,15 +36244,14 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36244
36244
|
break;
|
|
36245
36245
|
}
|
|
36246
36246
|
const fillRule = node.paint.includes("*") ? "evenodd" : "nonzero";
|
|
36247
|
-
const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
|
|
36248
|
-
const scaledStrokeWidth = st.strokeWidth === 0 ? 0 : st.strokeWidth * ctmScale;
|
|
36249
36247
|
emit({ kind: "path", value: {
|
|
36250
36248
|
segments: transformedSegments,
|
|
36251
36249
|
fillColor: isFill && !evaluatedFillPattern ? st.fillColor : void 0,
|
|
36252
36250
|
fillAlpha: isFill && !evaluatedFillPattern ? st.fillAlpha : void 0,
|
|
36253
36251
|
strokeColor: isStroke ? st.strokeColor : void 0,
|
|
36254
36252
|
strokeAlpha: isStroke ? st.strokeAlpha : void 0,
|
|
36255
|
-
strokeWidth:
|
|
36253
|
+
strokeWidth: st.strokeWidth,
|
|
36254
|
+
...isStroke ? { strokeMatrix: [...st.ctm] } : {},
|
|
36256
36255
|
...st.lineCap !== 0 ? { lineCap: st.lineCap } : {},
|
|
36257
36256
|
...st.lineJoin !== 0 ? { lineJoin: st.lineJoin } : {},
|
|
36258
36257
|
...st.miterLimit !== 10 ? { miterLimit: st.miterLimit } : {},
|
|
@@ -36440,14 +36439,14 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36440
36439
|
if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
|
|
36441
36440
|
const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
|
|
36442
36441
|
const isStrokeGlyph = st.textRenderMode === 1 || st.textRenderMode === 2 || st.textRenderMode === 5 || st.textRenderMode === 6;
|
|
36443
|
-
const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
|
|
36444
36442
|
const paint = {
|
|
36445
36443
|
segments: transformedGlyphSegs,
|
|
36446
36444
|
fillColor: isFillGlyph ? st.fillColor : void 0,
|
|
36447
36445
|
fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
|
|
36448
36446
|
strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
|
|
36449
36447
|
strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
|
|
36450
|
-
strokeWidth: isStrokeGlyph ? st.strokeWidth
|
|
36448
|
+
strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
|
|
36449
|
+
...isStrokeGlyph ? { strokeMatrix: [...st.ctm] } : {},
|
|
36451
36450
|
fillRule: "nonzero",
|
|
36452
36451
|
...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
|
|
36453
36452
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
@@ -39412,7 +39411,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
39412
39411
|
while (remaining <= 0) {
|
|
39413
39412
|
if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39414
39413
|
if (index % 2 === 0) {
|
|
39415
|
-
if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
|
|
39414
|
+
if (pattern[index] === 0) result.push({ points: [point, point], closed: false, zeroLengthDash: true });
|
|
39416
39415
|
flush();
|
|
39417
39416
|
}
|
|
39418
39417
|
index = (index + 1) % pattern.length;
|
|
@@ -39427,7 +39426,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
39427
39426
|
throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39428
39427
|
}
|
|
39429
39428
|
let distance = 0;
|
|
39430
|
-
while (distance
|
|
39429
|
+
while (length - distance > 8 * Number.EPSILON * Math.max(1, length)) {
|
|
39431
39430
|
const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
|
|
39432
39431
|
advance(point);
|
|
39433
39432
|
const step = Math.min(remaining, length - distance);
|
|
@@ -39542,7 +39541,15 @@ function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], das
|
|
|
39542
39541
|
let closed = subpath.closed;
|
|
39543
39542
|
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();
|
|
39544
39543
|
if (points.length < 3) closed = false;
|
|
39545
|
-
if (points.length === 1 &&
|
|
39544
|
+
if (points.length === 1 && cap === 2 && subpath.zeroLengthDash) {
|
|
39545
|
+
contour = [];
|
|
39546
|
+
const [x, y] = points[0];
|
|
39547
|
+
add(x - half, y - half);
|
|
39548
|
+
add(x + half, y - half);
|
|
39549
|
+
add(x + half, y + half);
|
|
39550
|
+
add(x - half, y + half);
|
|
39551
|
+
contours.push(contour);
|
|
39552
|
+
} else if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
|
|
39546
39553
|
contour = [];
|
|
39547
39554
|
const [x, y] = points[0];
|
|
39548
39555
|
addCap([x, y], [x + 1, y]);
|
|
@@ -40261,11 +40268,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
|
|
|
40261
40268
|
rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
|
|
40262
40269
|
rgba[idx + 3] = Math.round(outA * 255);
|
|
40263
40270
|
}
|
|
40264
|
-
function segmentsToScreenPaths(segments, pageHeight, scale) {
|
|
40271
|
+
function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
|
|
40265
40272
|
const paths = [];
|
|
40266
40273
|
let points = [];
|
|
40267
40274
|
let current = [0, 0];
|
|
40268
|
-
const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
|
|
40269
40275
|
for (const segment of segments) {
|
|
40270
40276
|
if (segment.kind === "move") {
|
|
40271
40277
|
if (points.length) paths.push({ points, closed: false });
|
|
@@ -40304,6 +40310,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
|
|
|
40304
40310
|
if (points.length) paths.push({ points, closed: false });
|
|
40305
40311
|
return paths;
|
|
40306
40312
|
}
|
|
40313
|
+
function inverseStrokeMatrix(matrix) {
|
|
40314
|
+
const [a, b, c, d, e, f] = matrix;
|
|
40315
|
+
const det = a * d - b * c;
|
|
40316
|
+
if (!Number.isFinite(det) || det === 0) return void 0;
|
|
40317
|
+
return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
|
|
40318
|
+
}
|
|
40319
|
+
function prepareStroke(path, scale) {
|
|
40320
|
+
const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
|
|
40321
|
+
const [a, b, c, d] = matrix;
|
|
40322
|
+
const area = Math.abs(a * d - b * c) * scale * scale;
|
|
40323
|
+
if (!(area > 0) || !Number.isFinite(area)) return void 0;
|
|
40324
|
+
const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
|
|
40325
|
+
let width = path.strokeWidth || 1;
|
|
40326
|
+
const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
|
|
40327
|
+
const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
|
|
40328
|
+
let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
|
|
40329
|
+
if (scaleX === scaleY) {
|
|
40330
|
+
width *= scaleX;
|
|
40331
|
+
} else {
|
|
40332
|
+
matrix[0] *= scaleX;
|
|
40333
|
+
matrix[1] *= scaleX;
|
|
40334
|
+
matrix[2] *= scaleY;
|
|
40335
|
+
matrix[3] *= scaleY;
|
|
40336
|
+
if (dashArray?.length) {
|
|
40337
|
+
const dashScale = Math.max(scaleX, scaleY);
|
|
40338
|
+
dashArray = dashArray.map((value) => value / dashScale);
|
|
40339
|
+
dashPhase /= dashScale;
|
|
40340
|
+
}
|
|
40341
|
+
}
|
|
40342
|
+
return { matrix, width, dashArray, dashPhase };
|
|
40343
|
+
}
|
|
40344
|
+
function strokeContours(path, pageHeight, scale) {
|
|
40345
|
+
const stroke = prepareStroke(path, scale);
|
|
40346
|
+
if (!stroke) return [];
|
|
40347
|
+
const inverse = inverseStrokeMatrix(stroke.matrix);
|
|
40348
|
+
if (!inverse) return [];
|
|
40349
|
+
const [a, b, c, d, e, f] = stroke.matrix;
|
|
40350
|
+
const strokeScale = scale * Math.hypot(a, b, c, d);
|
|
40351
|
+
const project = (x, y) => [
|
|
40352
|
+
(inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
|
|
40353
|
+
(inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
|
|
40354
|
+
];
|
|
40355
|
+
const toScreen = ([x, y]) => [
|
|
40356
|
+
(a * x / strokeScale + c * y / strokeScale + e) * scale,
|
|
40357
|
+
(pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
|
|
40358
|
+
];
|
|
40359
|
+
const contours = strokeOutlines(
|
|
40360
|
+
segmentsToScreenPaths(path.segments, pageHeight, scale, project),
|
|
40361
|
+
stroke.width * strokeScale,
|
|
40362
|
+
path.lineCap ?? 0,
|
|
40363
|
+
path.lineJoin ?? 0,
|
|
40364
|
+
path.miterLimit ?? 10,
|
|
40365
|
+
stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
|
|
40366
|
+
stroke.dashPhase * strokeScale
|
|
40367
|
+
);
|
|
40368
|
+
return contours.map((points) => points.map(toScreen));
|
|
40369
|
+
}
|
|
40307
40370
|
function pathsToEdges(paths, closeSubpaths = false) {
|
|
40308
40371
|
const edges = [];
|
|
40309
40372
|
for (const { points, closed } of paths) {
|
|
@@ -40553,19 +40616,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40553
40616
|
fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
|
|
40554
40617
|
}
|
|
40555
40618
|
if (path.strokeColor) {
|
|
40556
|
-
const rawSw = path.strokeWidth * scale;
|
|
40557
|
-
const sw = Math.max(1, rawSw);
|
|
40619
|
+
const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
|
|
40558
40620
|
const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
|
|
40559
|
-
const
|
|
40560
|
-
segmentsToScreenPaths(path.segments, displayList.height, scale),
|
|
40561
|
-
sw,
|
|
40562
|
-
path.lineCap ?? 0,
|
|
40563
|
-
path.lineJoin ?? 0,
|
|
40564
|
-
path.miterLimit ?? 10,
|
|
40565
|
-
path.dashArray?.map((value) => Math.max(0, value * scale)),
|
|
40566
|
-
(path.dashPhase ?? 0) * scale
|
|
40567
|
-
);
|
|
40568
|
-
const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
|
|
40621
|
+
const edges = pathsToEdges(strokeContours(path, displayList.height, scale).map((points) => ({ points, closed: true })));
|
|
40569
40622
|
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;
|
|
40570
40623
|
fillEdgesScanline4x4(
|
|
40571
40624
|
rgba,
|
|
@@ -35898,11 +35898,10 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
35898
35898
|
} else if (operator === "d") {
|
|
35899
35899
|
const arrNode = ops[0]?.kind === "array" ? ops[0] : void 0;
|
|
35900
35900
|
if (arrNode) {
|
|
35901
|
-
const
|
|
35902
|
-
const nums = arrNode.items.map((it) => it.kind === "number" ? it.value * ctmScale : 0).filter((v) => v >= 0);
|
|
35901
|
+
const nums = arrNode.items.map((it) => it.kind === "number" ? it.value : 0).filter((v) => v >= 0);
|
|
35903
35902
|
const sum = nums.reduce((a, b) => a + b, 0);
|
|
35904
35903
|
st.dashArray = sum > 0 ? nums : void 0;
|
|
35905
|
-
st.dashPhase = num(1, 0)
|
|
35904
|
+
st.dashPhase = num(1, 0);
|
|
35906
35905
|
} else {
|
|
35907
35906
|
st.dashArray = void 0;
|
|
35908
35907
|
st.dashPhase = void 0;
|
|
@@ -36034,10 +36033,11 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36034
36033
|
const patArr = params.cosDoc.resolveArray(dArr.items[0]);
|
|
36035
36034
|
const phaseNode = params.cosDoc.resolve(dArr.items[1]);
|
|
36036
36035
|
if (patArr) {
|
|
36037
|
-
|
|
36036
|
+
const dashArray = patArr.items.map((it) => {
|
|
36038
36037
|
const r = params.cosDoc.resolve(it);
|
|
36039
36038
|
return r?.kind === "number" ? r.value : 0;
|
|
36040
|
-
}).filter((n) => n
|
|
36039
|
+
}).filter((n) => n >= 0);
|
|
36040
|
+
st.dashArray = dashArray.some((value) => value > 0) ? dashArray : void 0;
|
|
36041
36041
|
st.dashPhase = phaseNode?.kind === "number" ? phaseNode.value : 0;
|
|
36042
36042
|
}
|
|
36043
36043
|
}
|
|
@@ -36438,15 +36438,14 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36438
36438
|
break;
|
|
36439
36439
|
}
|
|
36440
36440
|
const fillRule = node.paint.includes("*") ? "evenodd" : "nonzero";
|
|
36441
|
-
const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
|
|
36442
|
-
const scaledStrokeWidth = st.strokeWidth === 0 ? 0 : st.strokeWidth * ctmScale;
|
|
36443
36441
|
emit({ kind: "path", value: {
|
|
36444
36442
|
segments: transformedSegments,
|
|
36445
36443
|
fillColor: isFill && !evaluatedFillPattern ? st.fillColor : void 0,
|
|
36446
36444
|
fillAlpha: isFill && !evaluatedFillPattern ? st.fillAlpha : void 0,
|
|
36447
36445
|
strokeColor: isStroke ? st.strokeColor : void 0,
|
|
36448
36446
|
strokeAlpha: isStroke ? st.strokeAlpha : void 0,
|
|
36449
|
-
strokeWidth:
|
|
36447
|
+
strokeWidth: st.strokeWidth,
|
|
36448
|
+
...isStroke ? { strokeMatrix: [...st.ctm] } : {},
|
|
36450
36449
|
...st.lineCap !== 0 ? { lineCap: st.lineCap } : {},
|
|
36451
36450
|
...st.lineJoin !== 0 ? { lineJoin: st.lineJoin } : {},
|
|
36452
36451
|
...st.miterLimit !== 10 ? { miterLimit: st.miterLimit } : {},
|
|
@@ -36634,14 +36633,14 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36634
36633
|
if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
|
|
36635
36634
|
const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
|
|
36636
36635
|
const isStrokeGlyph = st.textRenderMode === 1 || st.textRenderMode === 2 || st.textRenderMode === 5 || st.textRenderMode === 6;
|
|
36637
|
-
const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
|
|
36638
36636
|
const paint = {
|
|
36639
36637
|
segments: transformedGlyphSegs,
|
|
36640
36638
|
fillColor: isFillGlyph ? st.fillColor : void 0,
|
|
36641
36639
|
fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
|
|
36642
36640
|
strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
|
|
36643
36641
|
strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
|
|
36644
|
-
strokeWidth: isStrokeGlyph ? st.strokeWidth
|
|
36642
|
+
strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
|
|
36643
|
+
...isStrokeGlyph ? { strokeMatrix: [...st.ctm] } : {},
|
|
36645
36644
|
fillRule: "nonzero",
|
|
36646
36645
|
...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
|
|
36647
36646
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
@@ -39042,7 +39041,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
39042
39041
|
while (remaining <= 0) {
|
|
39043
39042
|
if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39044
39043
|
if (index % 2 === 0) {
|
|
39045
|
-
if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
|
|
39044
|
+
if (pattern[index] === 0) result.push({ points: [point, point], closed: false, zeroLengthDash: true });
|
|
39046
39045
|
flush();
|
|
39047
39046
|
}
|
|
39048
39047
|
index = (index + 1) % pattern.length;
|
|
@@ -39057,7 +39056,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
39057
39056
|
throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39058
39057
|
}
|
|
39059
39058
|
let distance = 0;
|
|
39060
|
-
while (distance
|
|
39059
|
+
while (length - distance > 8 * Number.EPSILON * Math.max(1, length)) {
|
|
39061
39060
|
const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
|
|
39062
39061
|
advance(point);
|
|
39063
39062
|
const step = Math.min(remaining, length - distance);
|
|
@@ -39172,7 +39171,15 @@ function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], das
|
|
|
39172
39171
|
let closed = subpath.closed;
|
|
39173
39172
|
if (closed && points.length > 1 && Math.hypot(points[0][0] - points[points.length - 1][0], points[0][1] - points[points.length - 1][1]) <= 1e-14) points.pop();
|
|
39174
39173
|
if (points.length < 3) closed = false;
|
|
39175
|
-
if (points.length === 1 &&
|
|
39174
|
+
if (points.length === 1 && cap === 2 && subpath.zeroLengthDash) {
|
|
39175
|
+
contour = [];
|
|
39176
|
+
const [x, y] = points[0];
|
|
39177
|
+
add(x - half, y - half);
|
|
39178
|
+
add(x + half, y - half);
|
|
39179
|
+
add(x + half, y + half);
|
|
39180
|
+
add(x - half, y + half);
|
|
39181
|
+
contours.push(contour);
|
|
39182
|
+
} else if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
|
|
39176
39183
|
contour = [];
|
|
39177
39184
|
const [x, y] = points[0];
|
|
39178
39185
|
addCap([x, y], [x + 1, y]);
|
|
@@ -40287,11 +40294,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
|
|
|
40287
40294
|
rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
|
|
40288
40295
|
rgba[idx + 3] = Math.round(outA * 255);
|
|
40289
40296
|
}
|
|
40290
|
-
function segmentsToScreenPaths(segments, pageHeight, scale) {
|
|
40297
|
+
function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
|
|
40291
40298
|
const paths = [];
|
|
40292
40299
|
let points = [];
|
|
40293
40300
|
let current = [0, 0];
|
|
40294
|
-
const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
|
|
40295
40301
|
for (const segment of segments) {
|
|
40296
40302
|
if (segment.kind === "move") {
|
|
40297
40303
|
if (points.length) paths.push({ points, closed: false });
|
|
@@ -40330,6 +40336,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
|
|
|
40330
40336
|
if (points.length) paths.push({ points, closed: false });
|
|
40331
40337
|
return paths;
|
|
40332
40338
|
}
|
|
40339
|
+
function inverseStrokeMatrix(matrix) {
|
|
40340
|
+
const [a, b, c, d, e, f] = matrix;
|
|
40341
|
+
const det = a * d - b * c;
|
|
40342
|
+
if (!Number.isFinite(det) || det === 0) return void 0;
|
|
40343
|
+
return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
|
|
40344
|
+
}
|
|
40345
|
+
function prepareStroke(path, scale) {
|
|
40346
|
+
const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
|
|
40347
|
+
const [a, b, c, d] = matrix;
|
|
40348
|
+
const area = Math.abs(a * d - b * c) * scale * scale;
|
|
40349
|
+
if (!(area > 0) || !Number.isFinite(area)) return void 0;
|
|
40350
|
+
const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
|
|
40351
|
+
let width = path.strokeWidth || 1;
|
|
40352
|
+
const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
|
|
40353
|
+
const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
|
|
40354
|
+
let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
|
|
40355
|
+
if (scaleX === scaleY) {
|
|
40356
|
+
width *= scaleX;
|
|
40357
|
+
} else {
|
|
40358
|
+
matrix[0] *= scaleX;
|
|
40359
|
+
matrix[1] *= scaleX;
|
|
40360
|
+
matrix[2] *= scaleY;
|
|
40361
|
+
matrix[3] *= scaleY;
|
|
40362
|
+
if (dashArray?.length) {
|
|
40363
|
+
const dashScale = Math.max(scaleX, scaleY);
|
|
40364
|
+
dashArray = dashArray.map((value) => value / dashScale);
|
|
40365
|
+
dashPhase /= dashScale;
|
|
40366
|
+
}
|
|
40367
|
+
}
|
|
40368
|
+
return { matrix, width, dashArray, dashPhase };
|
|
40369
|
+
}
|
|
40370
|
+
function strokeContours(path, pageHeight, scale) {
|
|
40371
|
+
const stroke = prepareStroke(path, scale);
|
|
40372
|
+
if (!stroke) return [];
|
|
40373
|
+
const inverse = inverseStrokeMatrix(stroke.matrix);
|
|
40374
|
+
if (!inverse) return [];
|
|
40375
|
+
const [a, b, c, d, e, f] = stroke.matrix;
|
|
40376
|
+
const strokeScale = scale * Math.hypot(a, b, c, d);
|
|
40377
|
+
const project = (x, y) => [
|
|
40378
|
+
(inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
|
|
40379
|
+
(inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
|
|
40380
|
+
];
|
|
40381
|
+
const toScreen = ([x, y]) => [
|
|
40382
|
+
(a * x / strokeScale + c * y / strokeScale + e) * scale,
|
|
40383
|
+
(pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
|
|
40384
|
+
];
|
|
40385
|
+
const contours = strokeOutlines(
|
|
40386
|
+
segmentsToScreenPaths(path.segments, pageHeight, scale, project),
|
|
40387
|
+
stroke.width * strokeScale,
|
|
40388
|
+
path.lineCap ?? 0,
|
|
40389
|
+
path.lineJoin ?? 0,
|
|
40390
|
+
path.miterLimit ?? 10,
|
|
40391
|
+
stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
|
|
40392
|
+
stroke.dashPhase * strokeScale
|
|
40393
|
+
);
|
|
40394
|
+
return contours.map((points) => points.map(toScreen));
|
|
40395
|
+
}
|
|
40333
40396
|
function pathsToEdges(paths, closeSubpaths = false) {
|
|
40334
40397
|
const edges = [];
|
|
40335
40398
|
for (const { points, closed } of paths) {
|
|
@@ -40579,19 +40642,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40579
40642
|
fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
|
|
40580
40643
|
}
|
|
40581
40644
|
if (path.strokeColor) {
|
|
40582
|
-
const rawSw = path.strokeWidth * scale;
|
|
40583
|
-
const sw = Math.max(1, rawSw);
|
|
40645
|
+
const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
|
|
40584
40646
|
const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
|
|
40585
|
-
const
|
|
40586
|
-
segmentsToScreenPaths(path.segments, displayList.height, scale),
|
|
40587
|
-
sw,
|
|
40588
|
-
path.lineCap ?? 0,
|
|
40589
|
-
path.lineJoin ?? 0,
|
|
40590
|
-
path.miterLimit ?? 10,
|
|
40591
|
-
path.dashArray?.map((value) => Math.max(0, value * scale)),
|
|
40592
|
-
(path.dashPhase ?? 0) * scale
|
|
40593
|
-
);
|
|
40594
|
-
const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
|
|
40647
|
+
const edges = pathsToEdges(strokeContours(path, displayList.height, scale).map((points) => ({ points, closed: true })));
|
|
40595
40648
|
const clipScreen = path.clipRect ? [path.clipRect[0] * scale, (displayList.height - path.clipRect[3]) * scale, path.clipRect[2] * scale, (displayList.height - path.clipRect[1]) * scale] : void 0;
|
|
40596
40649
|
fillEdgesScanline4x4(
|
|
40597
40650
|
rgba,
|
|
@@ -40741,17 +40794,19 @@ function svgImage(image, pageHeight) {
|
|
|
40741
40794
|
const [a, b, c, d, e, f] = image.matrix;
|
|
40742
40795
|
return `<image width="1" height="1" preserveAspectRatio="none" transform="matrix(${a} ${-b} ${-c} ${d} ${e + c} ${pageHeight - f - d})" href="data:image/png;base64,${btoa(chunks.join(""))}"/>`;
|
|
40743
40796
|
}
|
|
40744
|
-
function svgPathData(segments, height) {
|
|
40797
|
+
function svgPathData(segments, height, matrix) {
|
|
40745
40798
|
const dParts = [];
|
|
40799
|
+
const point = (x, y) => matrix ? `${matrix[0] * x + matrix[2] * y + matrix[4]} ${height - matrix[1] * x - matrix[3] * y - matrix[5]}` : `${x} ${height - y}`;
|
|
40746
40800
|
for (const seg of segments) {
|
|
40747
40801
|
if (seg.kind === "move") {
|
|
40748
|
-
dParts.push(`M ${seg.x
|
|
40802
|
+
dParts.push(`M ${point(seg.x, seg.y)}`);
|
|
40749
40803
|
} else if (seg.kind === "line") {
|
|
40750
|
-
dParts.push(`L ${seg.x
|
|
40804
|
+
dParts.push(`L ${point(seg.x, seg.y)}`);
|
|
40751
40805
|
} else if (seg.kind === "cubic") {
|
|
40752
|
-
dParts.push(`C ${seg.x1
|
|
40806
|
+
dParts.push(`C ${point(seg.x1, seg.y1)} ${point(seg.x2, seg.y2)} ${point(seg.x, seg.y)}`);
|
|
40753
40807
|
} else if (seg.kind === "rect") {
|
|
40754
|
-
dParts.push(`M ${seg.x} ${
|
|
40808
|
+
if (matrix) dParts.push(`M ${point(seg.x, seg.y)} L ${point(seg.x + seg.width, seg.y)} L ${point(seg.x + seg.width, seg.y + seg.height)} L ${point(seg.x, seg.y + seg.height)} Z`);
|
|
40809
|
+
else dParts.push(`M ${seg.x} ${height - seg.y} h ${seg.width} v ${-seg.height} h ${-seg.width} Z`);
|
|
40755
40810
|
} else if (seg.kind === "close") {
|
|
40756
40811
|
dParts.push("Z");
|
|
40757
40812
|
}
|
|
@@ -40830,21 +40885,34 @@ function renderDisplayListToSvg(displayList, options = {}) {
|
|
|
40830
40885
|
parts.push("</g>");
|
|
40831
40886
|
} else if (operation.kind === "path") {
|
|
40832
40887
|
const p = operation.value;
|
|
40833
|
-
const
|
|
40888
|
+
const prepared = p.strokeColor ? prepareStroke(p, Math.max(scaleX, scaleY)) : void 0;
|
|
40889
|
+
const outlineStroke = prepared && p.dashArray?.includes(0);
|
|
40890
|
+
const matrix = prepared && (prepared.matrix[0] !== 1 || prepared.matrix[1] !== 0 || prepared.matrix[2] !== 0 || prepared.matrix[3] !== 1) ? prepared.matrix : void 0;
|
|
40891
|
+
const inverse = matrix ? inverseStrokeMatrix(matrix) : void 0;
|
|
40892
|
+
const pathData = svgPathData(p.segments, inverse ? 0 : displayList.height, inverse);
|
|
40893
|
+
const transformAttr = inverse && matrix ? ` transform="matrix(${matrix[0]} ${-matrix[1]} ${-matrix[2]} ${matrix[3]} ${matrix[4]} ${displayList.height - matrix[5]})"` : "";
|
|
40834
40894
|
if (pathData) {
|
|
40835
40895
|
const fill = p.fillColor ? `rgb(${Math.round(p.fillColor.r * 255)},${Math.round(p.fillColor.g * 255)},${Math.round(p.fillColor.b * 255)})` : "none";
|
|
40836
|
-
const stroke = p.strokeColor ? `rgb(${Math.round(p.strokeColor.r * 255)},${Math.round(p.strokeColor.g * 255)},${Math.round(p.strokeColor.b * 255)})` : "none";
|
|
40896
|
+
const stroke = p.strokeColor && prepared ? `rgb(${Math.round(p.strokeColor.r * 255)},${Math.round(p.strokeColor.g * 255)},${Math.round(p.strokeColor.b * 255)})` : "none";
|
|
40837
40897
|
const fillRuleAttr = p.fillRule === "evenodd" ? ` fill-rule="evenodd"` : "";
|
|
40838
40898
|
const fillOpacityAttr = p.fillAlpha !== void 0 && p.fillAlpha < 1 ? ` fill-opacity="${p.fillAlpha}"` : "";
|
|
40839
40899
|
const strokeOpacityAttr = p.strokeAlpha !== void 0 && p.strokeAlpha < 1 ? ` stroke-opacity="${p.strokeAlpha}"` : "";
|
|
40840
|
-
const strokeWidthAttr = p.strokeWidth <= 0 ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${p.strokeWidth}"`;
|
|
40900
|
+
const strokeWidthAttr = p.strokeWidth <= 0 && !matrix && !p.dashArray?.length ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${prepared?.width ?? p.strokeWidth}"`;
|
|
40841
40901
|
const lineCapAttr = p.lineCap === 1 ? ` stroke-linecap="round"` : p.lineCap === 2 ? ` stroke-linecap="square"` : "";
|
|
40842
40902
|
const lineJoinAttr = p.lineJoin === 1 ? ` stroke-linejoin="round"` : p.lineJoin === 2 ? ` stroke-linejoin="bevel"` : "";
|
|
40843
40903
|
const miterLimitAttr = p.miterLimit !== void 0 && p.miterLimit !== 10 ? ` stroke-miterlimit="${p.miterLimit}"` : "";
|
|
40844
|
-
const dashArrayAttr =
|
|
40845
|
-
const dashOffsetAttr =
|
|
40904
|
+
const dashArrayAttr = !outlineStroke && prepared?.dashArray?.length ? ` stroke-dasharray="${prepared.dashArray.join(" ")}"` : "";
|
|
40905
|
+
const dashOffsetAttr = !outlineStroke && prepared?.dashPhase ? ` stroke-dashoffset="${prepared.dashPhase}"` : "";
|
|
40846
40906
|
const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
|
|
40847
|
-
|
|
40907
|
+
if (!outlineStroke || p.fillColor) {
|
|
40908
|
+
parts.push(` <path${labelAttr}${transformAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${outlineStroke ? "none" : stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
|
|
40909
|
+
}
|
|
40910
|
+
if (outlineStroke) {
|
|
40911
|
+
const outlineScale = Math.max(scaleX, scaleY);
|
|
40912
|
+
const contours = strokeContours(p, displayList.height, outlineScale);
|
|
40913
|
+
const outlineData = contours.map((points) => points.map(([x, y], i) => `${i === 0 ? "M" : "L"} ${x / outlineScale} ${y / outlineScale}`).join(" ") + " Z").join(" ");
|
|
40914
|
+
if (outlineData) parts.push(` <path${labelAttr} d="${outlineData}" fill="${stroke}" fill-opacity="${p.strokeAlpha ?? 1}"/>`);
|
|
40915
|
+
}
|
|
40848
40916
|
}
|
|
40849
40917
|
} else if (operation.kind === "image") {
|
|
40850
40918
|
parts.push(` ${svgImage(operation.value, displayList.height)}`);
|
|
@@ -36049,11 +36049,10 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36049
36049
|
} else if (operator === "d") {
|
|
36050
36050
|
const arrNode = ops[0]?.kind === "array" ? ops[0] : void 0;
|
|
36051
36051
|
if (arrNode) {
|
|
36052
|
-
const
|
|
36053
|
-
const nums = arrNode.items.map((it) => it.kind === "number" ? it.value * ctmScale : 0).filter((v) => v >= 0);
|
|
36052
|
+
const nums = arrNode.items.map((it) => it.kind === "number" ? it.value : 0).filter((v) => v >= 0);
|
|
36054
36053
|
const sum = nums.reduce((a, b) => a + b, 0);
|
|
36055
36054
|
st.dashArray = sum > 0 ? nums : void 0;
|
|
36056
|
-
st.dashPhase = num(1, 0)
|
|
36055
|
+
st.dashPhase = num(1, 0);
|
|
36057
36056
|
} else {
|
|
36058
36057
|
st.dashArray = void 0;
|
|
36059
36058
|
st.dashPhase = void 0;
|
|
@@ -36185,10 +36184,11 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36185
36184
|
const patArr = params.cosDoc.resolveArray(dArr.items[0]);
|
|
36186
36185
|
const phaseNode = params.cosDoc.resolve(dArr.items[1]);
|
|
36187
36186
|
if (patArr) {
|
|
36188
|
-
|
|
36187
|
+
const dashArray = patArr.items.map((it) => {
|
|
36189
36188
|
const r = params.cosDoc.resolve(it);
|
|
36190
36189
|
return r?.kind === "number" ? r.value : 0;
|
|
36191
|
-
}).filter((n) => n
|
|
36190
|
+
}).filter((n) => n >= 0);
|
|
36191
|
+
st.dashArray = dashArray.some((value) => value > 0) ? dashArray : void 0;
|
|
36192
36192
|
st.dashPhase = phaseNode?.kind === "number" ? phaseNode.value : 0;
|
|
36193
36193
|
}
|
|
36194
36194
|
}
|
|
@@ -36589,15 +36589,14 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36589
36589
|
break;
|
|
36590
36590
|
}
|
|
36591
36591
|
const fillRule = node.paint.includes("*") ? "evenodd" : "nonzero";
|
|
36592
|
-
const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
|
|
36593
|
-
const scaledStrokeWidth = st.strokeWidth === 0 ? 0 : st.strokeWidth * ctmScale;
|
|
36594
36592
|
emit({ kind: "path", value: {
|
|
36595
36593
|
segments: transformedSegments,
|
|
36596
36594
|
fillColor: isFill && !evaluatedFillPattern ? st.fillColor : void 0,
|
|
36597
36595
|
fillAlpha: isFill && !evaluatedFillPattern ? st.fillAlpha : void 0,
|
|
36598
36596
|
strokeColor: isStroke ? st.strokeColor : void 0,
|
|
36599
36597
|
strokeAlpha: isStroke ? st.strokeAlpha : void 0,
|
|
36600
|
-
strokeWidth:
|
|
36598
|
+
strokeWidth: st.strokeWidth,
|
|
36599
|
+
...isStroke ? { strokeMatrix: [...st.ctm] } : {},
|
|
36601
36600
|
...st.lineCap !== 0 ? { lineCap: st.lineCap } : {},
|
|
36602
36601
|
...st.lineJoin !== 0 ? { lineJoin: st.lineJoin } : {},
|
|
36603
36602
|
...st.miterLimit !== 10 ? { miterLimit: st.miterLimit } : {},
|
|
@@ -36785,14 +36784,14 @@ function evaluateContentStreamToDisplayList(params) {
|
|
|
36785
36784
|
if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
|
|
36786
36785
|
const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
|
|
36787
36786
|
const isStrokeGlyph = st.textRenderMode === 1 || st.textRenderMode === 2 || st.textRenderMode === 5 || st.textRenderMode === 6;
|
|
36788
|
-
const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
|
|
36789
36787
|
const paint = {
|
|
36790
36788
|
segments: transformedGlyphSegs,
|
|
36791
36789
|
fillColor: isFillGlyph ? st.fillColor : void 0,
|
|
36792
36790
|
fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
|
|
36793
36791
|
strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
|
|
36794
36792
|
strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
|
|
36795
|
-
strokeWidth: isStrokeGlyph ? st.strokeWidth
|
|
36793
|
+
strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
|
|
36794
|
+
...isStrokeGlyph ? { strokeMatrix: [...st.ctm] } : {},
|
|
36796
36795
|
fillRule: "nonzero",
|
|
36797
36796
|
...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
|
|
36798
36797
|
...st.clipRect ? { clipRect: [...st.clipRect] } : {}
|
|
@@ -39193,7 +39192,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
39193
39192
|
while (remaining <= 0) {
|
|
39194
39193
|
if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39195
39194
|
if (index % 2 === 0) {
|
|
39196
|
-
if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
|
|
39195
|
+
if (pattern[index] === 0) result.push({ points: [point, point], closed: false, zeroLengthDash: true });
|
|
39197
39196
|
flush();
|
|
39198
39197
|
}
|
|
39199
39198
|
index = (index + 1) % pattern.length;
|
|
@@ -39208,7 +39207,7 @@ function dashSubpath(path, pattern, phase) {
|
|
|
39208
39207
|
throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
|
|
39209
39208
|
}
|
|
39210
39209
|
let distance = 0;
|
|
39211
|
-
while (distance
|
|
39210
|
+
while (length - distance > 8 * Number.EPSILON * Math.max(1, length)) {
|
|
39212
39211
|
const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
|
|
39213
39212
|
advance(point);
|
|
39214
39213
|
const step = Math.min(remaining, length - distance);
|
|
@@ -39323,7 +39322,15 @@ function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], das
|
|
|
39323
39322
|
let closed = subpath.closed;
|
|
39324
39323
|
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();
|
|
39325
39324
|
if (points.length < 3) closed = false;
|
|
39326
|
-
if (points.length === 1 &&
|
|
39325
|
+
if (points.length === 1 && cap === 2 && subpath.zeroLengthDash) {
|
|
39326
|
+
contour = [];
|
|
39327
|
+
const [x, y] = points[0];
|
|
39328
|
+
add(x - half, y - half);
|
|
39329
|
+
add(x + half, y - half);
|
|
39330
|
+
add(x + half, y + half);
|
|
39331
|
+
add(x - half, y + half);
|
|
39332
|
+
contours.push(contour);
|
|
39333
|
+
} else if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
|
|
39327
39334
|
contour = [];
|
|
39328
39335
|
const [x, y] = points[0];
|
|
39329
39336
|
addCap([x, y], [x + 1, y]);
|
|
@@ -40269,11 +40276,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
|
|
|
40269
40276
|
rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
|
|
40270
40277
|
rgba[idx + 3] = Math.round(outA * 255);
|
|
40271
40278
|
}
|
|
40272
|
-
function segmentsToScreenPaths(segments, pageHeight, scale) {
|
|
40279
|
+
function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
|
|
40273
40280
|
const paths = [];
|
|
40274
40281
|
let points = [];
|
|
40275
40282
|
let current = [0, 0];
|
|
40276
|
-
const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
|
|
40277
40283
|
for (const segment of segments) {
|
|
40278
40284
|
if (segment.kind === "move") {
|
|
40279
40285
|
if (points.length) paths.push({ points, closed: false });
|
|
@@ -40312,6 +40318,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
|
|
|
40312
40318
|
if (points.length) paths.push({ points, closed: false });
|
|
40313
40319
|
return paths;
|
|
40314
40320
|
}
|
|
40321
|
+
function inverseStrokeMatrix(matrix) {
|
|
40322
|
+
const [a, b, c, d, e, f] = matrix;
|
|
40323
|
+
const det = a * d - b * c;
|
|
40324
|
+
if (!Number.isFinite(det) || det === 0) return void 0;
|
|
40325
|
+
return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
|
|
40326
|
+
}
|
|
40327
|
+
function prepareStroke(path, scale) {
|
|
40328
|
+
const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
|
|
40329
|
+
const [a, b, c, d] = matrix;
|
|
40330
|
+
const area = Math.abs(a * d - b * c) * scale * scale;
|
|
40331
|
+
if (!(area > 0) || !Number.isFinite(area)) return void 0;
|
|
40332
|
+
const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
|
|
40333
|
+
let width = path.strokeWidth || 1;
|
|
40334
|
+
const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
|
|
40335
|
+
const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
|
|
40336
|
+
let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
|
|
40337
|
+
if (scaleX === scaleY) {
|
|
40338
|
+
width *= scaleX;
|
|
40339
|
+
} else {
|
|
40340
|
+
matrix[0] *= scaleX;
|
|
40341
|
+
matrix[1] *= scaleX;
|
|
40342
|
+
matrix[2] *= scaleY;
|
|
40343
|
+
matrix[3] *= scaleY;
|
|
40344
|
+
if (dashArray?.length) {
|
|
40345
|
+
const dashScale = Math.max(scaleX, scaleY);
|
|
40346
|
+
dashArray = dashArray.map((value) => value / dashScale);
|
|
40347
|
+
dashPhase /= dashScale;
|
|
40348
|
+
}
|
|
40349
|
+
}
|
|
40350
|
+
return { matrix, width, dashArray, dashPhase };
|
|
40351
|
+
}
|
|
40352
|
+
function strokeContours(path, pageHeight, scale) {
|
|
40353
|
+
const stroke = prepareStroke(path, scale);
|
|
40354
|
+
if (!stroke) return [];
|
|
40355
|
+
const inverse = inverseStrokeMatrix(stroke.matrix);
|
|
40356
|
+
if (!inverse) return [];
|
|
40357
|
+
const [a, b, c, d, e, f] = stroke.matrix;
|
|
40358
|
+
const strokeScale = scale * Math.hypot(a, b, c, d);
|
|
40359
|
+
const project = (x, y) => [
|
|
40360
|
+
(inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
|
|
40361
|
+
(inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
|
|
40362
|
+
];
|
|
40363
|
+
const toScreen = ([x, y]) => [
|
|
40364
|
+
(a * x / strokeScale + c * y / strokeScale + e) * scale,
|
|
40365
|
+
(pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
|
|
40366
|
+
];
|
|
40367
|
+
const contours = strokeOutlines(
|
|
40368
|
+
segmentsToScreenPaths(path.segments, pageHeight, scale, project),
|
|
40369
|
+
stroke.width * strokeScale,
|
|
40370
|
+
path.lineCap ?? 0,
|
|
40371
|
+
path.lineJoin ?? 0,
|
|
40372
|
+
path.miterLimit ?? 10,
|
|
40373
|
+
stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
|
|
40374
|
+
stroke.dashPhase * strokeScale
|
|
40375
|
+
);
|
|
40376
|
+
return contours.map((points) => points.map(toScreen));
|
|
40377
|
+
}
|
|
40315
40378
|
function pathsToEdges(paths, closeSubpaths = false) {
|
|
40316
40379
|
const edges = [];
|
|
40317
40380
|
for (const { points, closed } of paths) {
|
|
@@ -40561,19 +40624,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
|
|
|
40561
40624
|
fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
|
|
40562
40625
|
}
|
|
40563
40626
|
if (path.strokeColor) {
|
|
40564
|
-
const rawSw = path.strokeWidth * scale;
|
|
40565
|
-
const sw = Math.max(1, rawSw);
|
|
40627
|
+
const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
|
|
40566
40628
|
const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
|
|
40567
|
-
const
|
|
40568
|
-
segmentsToScreenPaths(path.segments, displayList.height, scale),
|
|
40569
|
-
sw,
|
|
40570
|
-
path.lineCap ?? 0,
|
|
40571
|
-
path.lineJoin ?? 0,
|
|
40572
|
-
path.miterLimit ?? 10,
|
|
40573
|
-
path.dashArray?.map((value) => Math.max(0, value * scale)),
|
|
40574
|
-
(path.dashPhase ?? 0) * scale
|
|
40575
|
-
);
|
|
40576
|
-
const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
|
|
40629
|
+
const edges = pathsToEdges(strokeContours(path, displayList.height, scale).map((points) => ({ points, closed: true })));
|
|
40577
40630
|
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;
|
|
40578
40631
|
fillEdgesScanline4x4(
|
|
40579
40632
|
rgba,
|