@poe-platform/safe-bash 0.1.764 → 0.1.765

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.
@@ -28,8 +28,8 @@ import {
28
28
  thresholdImage,
29
29
  tintImage,
30
30
  trimImage
31
- } from "../safe-bash/command-chunks/chunk-RDPJGIQF.js";
32
- import "../safe-bash/command-chunks/chunk-G3IIEU2N.js";
31
+ } from "../safe-bash/command-chunks/chunk-SVL6HYQL.js";
32
+ import "../safe-bash/command-chunks/chunk-KO4PXCNL.js";
33
33
  import {
34
34
  init_buffer
35
35
  } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
@@ -2,11 +2,11 @@ import {
2
2
  createPandocCommand,
3
3
  createPandocCommands,
4
4
  pandocCommands
5
- } from "../safe-bash/command-chunks/chunk-B7YLGJRF.js";
5
+ } from "../safe-bash/command-chunks/chunk-DT4MFWV4.js";
6
6
  import "../safe-bash/command-chunks/chunk-MKQVQMXO.js";
7
7
  import "../safe-bash/command-chunks/chunk-RDV7UCYZ.js";
8
- import "../safe-bash/command-chunks/chunk-RDPJGIQF.js";
9
- import "../safe-bash/command-chunks/chunk-G3IIEU2N.js";
8
+ import "../safe-bash/command-chunks/chunk-SVL6HYQL.js";
9
+ import "../safe-bash/command-chunks/chunk-KO4PXCNL.js";
10
10
  import "../safe-bash/command-chunks/chunk-Y2KHC6TZ.js";
11
11
  import "../safe-bash/command-chunks/chunk-YGYOVXTO.js";
12
12
  import "../safe-bash/command-chunks/chunk-I5GLTNVH.js";
@@ -21,11 +21,11 @@ import {
21
21
  readDocument,
22
22
  resolveConversionArgs,
23
23
  writeDocument
24
- } from "../safe-bash/command-chunks/chunk-B7YLGJRF.js";
24
+ } from "../safe-bash/command-chunks/chunk-DT4MFWV4.js";
25
25
  import "../safe-bash/command-chunks/chunk-MKQVQMXO.js";
26
26
  import "../safe-bash/command-chunks/chunk-RDV7UCYZ.js";
27
- import "../safe-bash/command-chunks/chunk-RDPJGIQF.js";
28
- import "../safe-bash/command-chunks/chunk-G3IIEU2N.js";
27
+ import "../safe-bash/command-chunks/chunk-SVL6HYQL.js";
28
+ import "../safe-bash/command-chunks/chunk-KO4PXCNL.js";
29
29
  import {
30
30
  createLuaFilterCapability
31
31
  } from "../safe-bash/command-chunks/chunk-Y2KHC6TZ.js";
@@ -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 ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
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) * ctmScale;
36055
+ st.dashPhase = num(1, 0);
36057
36056
  } else {
36058
36057
  st.dashArray = void 0;
36059
36058
  st.dashPhase = void 0;
@@ -36589,15 +36588,14 @@ function evaluateContentStreamToDisplayList(params) {
36589
36588
  break;
36590
36589
  }
36591
36590
  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
36591
  emit({ kind: "path", value: {
36595
36592
  segments: transformedSegments,
36596
36593
  fillColor: isFill && !evaluatedFillPattern ? st.fillColor : void 0,
36597
36594
  fillAlpha: isFill && !evaluatedFillPattern ? st.fillAlpha : void 0,
36598
36595
  strokeColor: isStroke ? st.strokeColor : void 0,
36599
36596
  strokeAlpha: isStroke ? st.strokeAlpha : void 0,
36600
- strokeWidth: scaledStrokeWidth,
36597
+ strokeWidth: st.strokeWidth,
36598
+ ...isStroke ? { strokeMatrix: [...st.ctm] } : {},
36601
36599
  ...st.lineCap !== 0 ? { lineCap: st.lineCap } : {},
36602
36600
  ...st.lineJoin !== 0 ? { lineJoin: st.lineJoin } : {},
36603
36601
  ...st.miterLimit !== 10 ? { miterLimit: st.miterLimit } : {},
@@ -36785,14 +36783,14 @@ function evaluateContentStreamToDisplayList(params) {
36785
36783
  if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
36786
36784
  const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
36787
36785
  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
36786
  const paint = {
36790
36787
  segments: transformedGlyphSegs,
36791
36788
  fillColor: isFillGlyph ? st.fillColor : void 0,
36792
36789
  fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
36793
36790
  strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
36794
36791
  strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
36795
- strokeWidth: isStrokeGlyph ? st.strokeWidth * ctmScale : 0,
36792
+ strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
36793
+ ...isStrokeGlyph ? { strokeMatrix: [...st.ctm] } : {},
36796
36794
  fillRule: "nonzero",
36797
36795
  ...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
36798
36796
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
@@ -40196,11 +40194,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
40196
40194
  rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
40197
40195
  rgba[idx + 3] = Math.round(outA * 255);
40198
40196
  }
40199
- function segmentsToScreenPaths(segments, pageHeight, scale) {
40197
+ function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
40200
40198
  const paths = [];
40201
40199
  let points = [];
40202
40200
  let current = [0, 0];
40203
- const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
40204
40201
  for (const segment of segments) {
40205
40202
  if (segment.kind === "move") {
40206
40203
  if (points.length) paths.push({ points, closed: false });
@@ -40239,6 +40236,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
40239
40236
  if (points.length) paths.push({ points, closed: false });
40240
40237
  return paths;
40241
40238
  }
40239
+ function inverseStrokeMatrix(matrix) {
40240
+ const [a, b, c, d, e, f] = matrix;
40241
+ const det = a * d - b * c;
40242
+ if (!Number.isFinite(det) || det === 0) return void 0;
40243
+ return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
40244
+ }
40245
+ function prepareStroke(path, scale) {
40246
+ const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
40247
+ const [a, b, c, d] = matrix;
40248
+ const area = Math.abs(a * d - b * c) * scale * scale;
40249
+ if (!(area > 0) || !Number.isFinite(area)) return void 0;
40250
+ const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
40251
+ let width = path.strokeWidth || 1;
40252
+ const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
40253
+ const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
40254
+ let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
40255
+ if (scaleX === scaleY) {
40256
+ width *= scaleX;
40257
+ } else {
40258
+ matrix[0] *= scaleX;
40259
+ matrix[1] *= scaleX;
40260
+ matrix[2] *= scaleY;
40261
+ matrix[3] *= scaleY;
40262
+ if (dashArray?.length) {
40263
+ const dashScale = Math.max(scaleX, scaleY);
40264
+ dashArray = dashArray.map((value) => value / dashScale);
40265
+ dashPhase /= dashScale;
40266
+ }
40267
+ }
40268
+ return { matrix, width, dashArray, dashPhase };
40269
+ }
40270
+ function strokeEdges(path, pageHeight, scale) {
40271
+ const stroke = prepareStroke(path, scale);
40272
+ if (!stroke) return [];
40273
+ const inverse = inverseStrokeMatrix(stroke.matrix);
40274
+ if (!inverse) return [];
40275
+ const [a, b, c, d, e, f] = stroke.matrix;
40276
+ const strokeScale = scale * Math.hypot(a, b, c, d);
40277
+ const project = (x, y) => [
40278
+ (inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
40279
+ (inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
40280
+ ];
40281
+ const toScreen = ([x, y]) => [
40282
+ (a * x / strokeScale + c * y / strokeScale + e) * scale,
40283
+ (pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
40284
+ ];
40285
+ const contours = strokeOutlines(
40286
+ segmentsToScreenPaths(path.segments, pageHeight, scale, project),
40287
+ stroke.width * strokeScale,
40288
+ path.lineCap ?? 0,
40289
+ path.lineJoin ?? 0,
40290
+ path.miterLimit ?? 10,
40291
+ stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
40292
+ stroke.dashPhase * strokeScale
40293
+ );
40294
+ return pathsToEdges(contours.map((points) => ({ points: points.map(toScreen), closed: true })));
40295
+ }
40242
40296
  function pathsToEdges(paths, closeSubpaths = false) {
40243
40297
  const edges = [];
40244
40298
  for (const { points, closed } of paths) {
@@ -40488,19 +40542,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40488
40542
  fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
40489
40543
  }
40490
40544
  if (path.strokeColor) {
40491
- const rawSw = path.strokeWidth * scale;
40492
- const sw = Math.max(1, rawSw);
40545
+ const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
40493
40546
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
40494
- const contours = strokeOutlines(
40495
- segmentsToScreenPaths(path.segments, displayList.height, scale),
40496
- sw,
40497
- path.lineCap ?? 0,
40498
- path.lineJoin ?? 0,
40499
- path.miterLimit ?? 10,
40500
- path.dashArray?.map((value) => Math.max(0, value * scale)),
40501
- (path.dashPhase ?? 0) * scale
40502
- );
40503
- const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
40547
+ const edges = strokeEdges(path, displayList.height, scale);
40504
40548
  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;
40505
40549
  fillEdgesScanline4x4(
40506
40550
  rgba,
@@ -36243,11 +36243,10 @@ function evaluateContentStreamToDisplayList(params) {
36243
36243
  } else if (operator === "d") {
36244
36244
  const arrNode = ops[0]?.kind === "array" ? ops[0] : void 0;
36245
36245
  if (arrNode) {
36246
- const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
36247
- const nums = arrNode.items.map((it) => it.kind === "number" ? it.value * ctmScale : 0).filter((v) => v >= 0);
36246
+ const nums = arrNode.items.map((it) => it.kind === "number" ? it.value : 0).filter((v) => v >= 0);
36248
36247
  const sum = nums.reduce((a, b) => a + b, 0);
36249
36248
  st.dashArray = sum > 0 ? nums : void 0;
36250
- st.dashPhase = num(1, 0) * ctmScale;
36249
+ st.dashPhase = num(1, 0);
36251
36250
  } else {
36252
36251
  st.dashArray = void 0;
36253
36252
  st.dashPhase = void 0;
@@ -36783,15 +36782,14 @@ function evaluateContentStreamToDisplayList(params) {
36783
36782
  break;
36784
36783
  }
36785
36784
  const fillRule = node.paint.includes("*") ? "evenodd" : "nonzero";
36786
- const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
36787
- const scaledStrokeWidth = st.strokeWidth === 0 ? 0 : st.strokeWidth * ctmScale;
36788
36785
  emit({ kind: "path", value: {
36789
36786
  segments: transformedSegments,
36790
36787
  fillColor: isFill && !evaluatedFillPattern ? st.fillColor : void 0,
36791
36788
  fillAlpha: isFill && !evaluatedFillPattern ? st.fillAlpha : void 0,
36792
36789
  strokeColor: isStroke ? st.strokeColor : void 0,
36793
36790
  strokeAlpha: isStroke ? st.strokeAlpha : void 0,
36794
- strokeWidth: scaledStrokeWidth,
36791
+ strokeWidth: st.strokeWidth,
36792
+ ...isStroke ? { strokeMatrix: [...st.ctm] } : {},
36795
36793
  ...st.lineCap !== 0 ? { lineCap: st.lineCap } : {},
36796
36794
  ...st.lineJoin !== 0 ? { lineJoin: st.lineJoin } : {},
36797
36795
  ...st.miterLimit !== 10 ? { miterLimit: st.miterLimit } : {},
@@ -36979,14 +36977,14 @@ function evaluateContentStreamToDisplayList(params) {
36979
36977
  if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
36980
36978
  const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
36981
36979
  const isStrokeGlyph = st.textRenderMode === 1 || st.textRenderMode === 2 || st.textRenderMode === 5 || st.textRenderMode === 6;
36982
- const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
36983
36980
  const paint = {
36984
36981
  segments: transformedGlyphSegs,
36985
36982
  fillColor: isFillGlyph ? st.fillColor : void 0,
36986
36983
  fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
36987
36984
  strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
36988
36985
  strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
36989
- strokeWidth: isStrokeGlyph ? st.strokeWidth * ctmScale : 0,
36986
+ strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
36987
+ ...isStrokeGlyph ? { strokeMatrix: [...st.ctm] } : {},
36990
36988
  fillRule: "nonzero",
36991
36989
  ...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
36992
36990
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
@@ -40632,11 +40630,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
40632
40630
  rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
40633
40631
  rgba[idx + 3] = Math.round(outA * 255);
40634
40632
  }
40635
- function segmentsToScreenPaths(segments, pageHeight, scale) {
40633
+ function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
40636
40634
  const paths = [];
40637
40635
  let points = [];
40638
40636
  let current = [0, 0];
40639
- const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
40640
40637
  for (const segment of segments) {
40641
40638
  if (segment.kind === "move") {
40642
40639
  if (points.length) paths.push({ points, closed: false });
@@ -40675,6 +40672,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
40675
40672
  if (points.length) paths.push({ points, closed: false });
40676
40673
  return paths;
40677
40674
  }
40675
+ function inverseStrokeMatrix(matrix) {
40676
+ const [a, b, c, d, e, f] = matrix;
40677
+ const det = a * d - b * c;
40678
+ if (!Number.isFinite(det) || det === 0) return void 0;
40679
+ return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
40680
+ }
40681
+ function prepareStroke(path, scale) {
40682
+ const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
40683
+ const [a, b, c, d] = matrix;
40684
+ const area = Math.abs(a * d - b * c) * scale * scale;
40685
+ if (!(area > 0) || !Number.isFinite(area)) return void 0;
40686
+ const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
40687
+ let width = path.strokeWidth || 1;
40688
+ const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
40689
+ const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
40690
+ let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
40691
+ if (scaleX === scaleY) {
40692
+ width *= scaleX;
40693
+ } else {
40694
+ matrix[0] *= scaleX;
40695
+ matrix[1] *= scaleX;
40696
+ matrix[2] *= scaleY;
40697
+ matrix[3] *= scaleY;
40698
+ if (dashArray?.length) {
40699
+ const dashScale = Math.max(scaleX, scaleY);
40700
+ dashArray = dashArray.map((value) => value / dashScale);
40701
+ dashPhase /= dashScale;
40702
+ }
40703
+ }
40704
+ return { matrix, width, dashArray, dashPhase };
40705
+ }
40706
+ function strokeEdges(path, pageHeight, scale) {
40707
+ const stroke = prepareStroke(path, scale);
40708
+ if (!stroke) return [];
40709
+ const inverse = inverseStrokeMatrix(stroke.matrix);
40710
+ if (!inverse) return [];
40711
+ const [a, b, c, d, e, f] = stroke.matrix;
40712
+ const strokeScale = scale * Math.hypot(a, b, c, d);
40713
+ const project = (x, y) => [
40714
+ (inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
40715
+ (inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
40716
+ ];
40717
+ const toScreen = ([x, y]) => [
40718
+ (a * x / strokeScale + c * y / strokeScale + e) * scale,
40719
+ (pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
40720
+ ];
40721
+ const contours = strokeOutlines(
40722
+ segmentsToScreenPaths(path.segments, pageHeight, scale, project),
40723
+ stroke.width * strokeScale,
40724
+ path.lineCap ?? 0,
40725
+ path.lineJoin ?? 0,
40726
+ path.miterLimit ?? 10,
40727
+ stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
40728
+ stroke.dashPhase * strokeScale
40729
+ );
40730
+ return pathsToEdges(contours.map((points) => ({ points: points.map(toScreen), closed: true })));
40731
+ }
40678
40732
  function pathsToEdges(paths, closeSubpaths = false) {
40679
40733
  const edges = [];
40680
40734
  for (const { points, closed } of paths) {
@@ -40924,19 +40978,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40924
40978
  fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
40925
40979
  }
40926
40980
  if (path.strokeColor) {
40927
- const rawSw = path.strokeWidth * scale;
40928
- const sw = Math.max(1, rawSw);
40981
+ const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
40929
40982
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
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 })));
40983
+ const edges = strokeEdges(path, displayList.height, scale);
40940
40984
  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
40985
  fillEdgesScanline4x4(
40942
40986
  rgba,
@@ -41086,17 +41130,19 @@ function svgImage(image, pageHeight) {
41086
41130
  const [a, b, c, d, e, f] = image.matrix;
41087
41131
  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(""))}"/>`;
41088
41132
  }
41089
- function svgPathData(segments, height) {
41133
+ function svgPathData(segments, height, matrix) {
41090
41134
  const dParts = [];
41135
+ 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}`;
41091
41136
  for (const seg of segments) {
41092
41137
  if (seg.kind === "move") {
41093
- dParts.push(`M ${seg.x} ${height - seg.y}`);
41138
+ dParts.push(`M ${point(seg.x, seg.y)}`);
41094
41139
  } else if (seg.kind === "line") {
41095
- dParts.push(`L ${seg.x} ${height - seg.y}`);
41140
+ dParts.push(`L ${point(seg.x, seg.y)}`);
41096
41141
  } else if (seg.kind === "cubic") {
41097
- dParts.push(`C ${seg.x1} ${height - seg.y1} ${seg.x2} ${height - seg.y2} ${seg.x} ${height - seg.y}`);
41142
+ dParts.push(`C ${point(seg.x1, seg.y1)} ${point(seg.x2, seg.y2)} ${point(seg.x, seg.y)}`);
41098
41143
  } else if (seg.kind === "rect") {
41099
- dParts.push(`M ${seg.x} ${height - seg.y} h ${seg.width} v ${-seg.height} h ${-seg.width} Z`);
41144
+ 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`);
41145
+ else dParts.push(`M ${seg.x} ${height - seg.y} h ${seg.width} v ${-seg.height} h ${-seg.width} Z`);
41100
41146
  } else if (seg.kind === "close") {
41101
41147
  dParts.push("Z");
41102
41148
  }
@@ -41175,21 +41221,25 @@ function renderDisplayListToSvg(displayList, options = {}) {
41175
41221
  parts.push("</g>");
41176
41222
  } else if (operation.kind === "path") {
41177
41223
  const p = operation.value;
41178
- const pathData = svgPathData(p.segments, displayList.height);
41224
+ const prepared = p.strokeColor ? prepareStroke(p, Math.max(scaleX, scaleY)) : void 0;
41225
+ const matrix = prepared && (prepared.matrix[0] !== 1 || prepared.matrix[1] !== 0 || prepared.matrix[2] !== 0 || prepared.matrix[3] !== 1) ? prepared.matrix : void 0;
41226
+ const inverse = matrix ? inverseStrokeMatrix(matrix) : void 0;
41227
+ const pathData = svgPathData(p.segments, inverse ? 0 : displayList.height, inverse);
41228
+ const transformAttr = inverse && matrix ? ` transform="matrix(${matrix[0]} ${-matrix[1]} ${-matrix[2]} ${matrix[3]} ${matrix[4]} ${displayList.height - matrix[5]})"` : "";
41179
41229
  if (pathData) {
41180
41230
  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";
41231
+ 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";
41182
41232
  const fillRuleAttr = p.fillRule === "evenodd" ? ` fill-rule="evenodd"` : "";
41183
41233
  const fillOpacityAttr = p.fillAlpha !== void 0 && p.fillAlpha < 1 ? ` fill-opacity="${p.fillAlpha}"` : "";
41184
41234
  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}"`;
41235
+ const strokeWidthAttr = p.strokeWidth <= 0 && !matrix && !p.dashArray?.length ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${prepared?.width ?? p.strokeWidth}"`;
41186
41236
  const lineCapAttr = p.lineCap === 1 ? ` stroke-linecap="round"` : p.lineCap === 2 ? ` stroke-linecap="square"` : "";
41187
41237
  const lineJoinAttr = p.lineJoin === 1 ? ` stroke-linejoin="round"` : p.lineJoin === 2 ? ` stroke-linejoin="bevel"` : "";
41188
41238
  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}"` : "";
41239
+ const dashArrayAttr = prepared?.dashArray?.length ? ` stroke-dasharray="${prepared.dashArray.join(" ")}"` : "";
41240
+ const dashOffsetAttr = prepared?.dashPhase ? ` stroke-dashoffset="${prepared.dashPhase}"` : "";
41191
41241
  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}/>`);
41242
+ parts.push(` <path${labelAttr}${transformAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
41193
41243
  }
41194
41244
  } else if (operation.kind === "image") {
41195
41245
  parts.push(` ${svgImage(operation.value, displayList.height)}`);
@@ -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 ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
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) * ctmScale;
35710
+ st.dashPhase = num(1, 0);
35712
35711
  } else {
35713
35712
  st.dashArray = void 0;
35714
35713
  st.dashPhase = void 0;
@@ -36244,15 +36243,14 @@ function evaluateContentStreamToDisplayList(params) {
36244
36243
  break;
36245
36244
  }
36246
36245
  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
36246
  emit({ kind: "path", value: {
36250
36247
  segments: transformedSegments,
36251
36248
  fillColor: isFill && !evaluatedFillPattern ? st.fillColor : void 0,
36252
36249
  fillAlpha: isFill && !evaluatedFillPattern ? st.fillAlpha : void 0,
36253
36250
  strokeColor: isStroke ? st.strokeColor : void 0,
36254
36251
  strokeAlpha: isStroke ? st.strokeAlpha : void 0,
36255
- strokeWidth: scaledStrokeWidth,
36252
+ strokeWidth: st.strokeWidth,
36253
+ ...isStroke ? { strokeMatrix: [...st.ctm] } : {},
36256
36254
  ...st.lineCap !== 0 ? { lineCap: st.lineCap } : {},
36257
36255
  ...st.lineJoin !== 0 ? { lineJoin: st.lineJoin } : {},
36258
36256
  ...st.miterLimit !== 10 ? { miterLimit: st.miterLimit } : {},
@@ -36440,14 +36438,14 @@ function evaluateContentStreamToDisplayList(params) {
36440
36438
  if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
36441
36439
  const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
36442
36440
  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
36441
  const paint = {
36445
36442
  segments: transformedGlyphSegs,
36446
36443
  fillColor: isFillGlyph ? st.fillColor : void 0,
36447
36444
  fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
36448
36445
  strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
36449
36446
  strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
36450
- strokeWidth: isStrokeGlyph ? st.strokeWidth * ctmScale : 0,
36447
+ strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
36448
+ ...isStrokeGlyph ? { strokeMatrix: [...st.ctm] } : {},
36451
36449
  fillRule: "nonzero",
36452
36450
  ...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
36453
36451
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
@@ -40261,11 +40259,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
40261
40259
  rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
40262
40260
  rgba[idx + 3] = Math.round(outA * 255);
40263
40261
  }
40264
- function segmentsToScreenPaths(segments, pageHeight, scale) {
40262
+ function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
40265
40263
  const paths = [];
40266
40264
  let points = [];
40267
40265
  let current = [0, 0];
40268
- const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
40269
40266
  for (const segment of segments) {
40270
40267
  if (segment.kind === "move") {
40271
40268
  if (points.length) paths.push({ points, closed: false });
@@ -40304,6 +40301,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
40304
40301
  if (points.length) paths.push({ points, closed: false });
40305
40302
  return paths;
40306
40303
  }
40304
+ function inverseStrokeMatrix(matrix) {
40305
+ const [a, b, c, d, e, f] = matrix;
40306
+ const det = a * d - b * c;
40307
+ if (!Number.isFinite(det) || det === 0) return void 0;
40308
+ return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
40309
+ }
40310
+ function prepareStroke(path, scale) {
40311
+ const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
40312
+ const [a, b, c, d] = matrix;
40313
+ const area = Math.abs(a * d - b * c) * scale * scale;
40314
+ if (!(area > 0) || !Number.isFinite(area)) return void 0;
40315
+ const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
40316
+ let width = path.strokeWidth || 1;
40317
+ const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
40318
+ const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
40319
+ let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
40320
+ if (scaleX === scaleY) {
40321
+ width *= scaleX;
40322
+ } else {
40323
+ matrix[0] *= scaleX;
40324
+ matrix[1] *= scaleX;
40325
+ matrix[2] *= scaleY;
40326
+ matrix[3] *= scaleY;
40327
+ if (dashArray?.length) {
40328
+ const dashScale = Math.max(scaleX, scaleY);
40329
+ dashArray = dashArray.map((value) => value / dashScale);
40330
+ dashPhase /= dashScale;
40331
+ }
40332
+ }
40333
+ return { matrix, width, dashArray, dashPhase };
40334
+ }
40335
+ function strokeEdges(path, pageHeight, scale) {
40336
+ const stroke = prepareStroke(path, scale);
40337
+ if (!stroke) return [];
40338
+ const inverse = inverseStrokeMatrix(stroke.matrix);
40339
+ if (!inverse) return [];
40340
+ const [a, b, c, d, e, f] = stroke.matrix;
40341
+ const strokeScale = scale * Math.hypot(a, b, c, d);
40342
+ const project = (x, y) => [
40343
+ (inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
40344
+ (inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
40345
+ ];
40346
+ const toScreen = ([x, y]) => [
40347
+ (a * x / strokeScale + c * y / strokeScale + e) * scale,
40348
+ (pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
40349
+ ];
40350
+ const contours = strokeOutlines(
40351
+ segmentsToScreenPaths(path.segments, pageHeight, scale, project),
40352
+ stroke.width * strokeScale,
40353
+ path.lineCap ?? 0,
40354
+ path.lineJoin ?? 0,
40355
+ path.miterLimit ?? 10,
40356
+ stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
40357
+ stroke.dashPhase * strokeScale
40358
+ );
40359
+ return pathsToEdges(contours.map((points) => ({ points: points.map(toScreen), closed: true })));
40360
+ }
40307
40361
  function pathsToEdges(paths, closeSubpaths = false) {
40308
40362
  const edges = [];
40309
40363
  for (const { points, closed } of paths) {
@@ -40553,19 +40607,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40553
40607
  fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
40554
40608
  }
40555
40609
  if (path.strokeColor) {
40556
- const rawSw = path.strokeWidth * scale;
40557
- const sw = Math.max(1, rawSw);
40610
+ const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
40558
40611
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
40559
- const contours = strokeOutlines(
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 })));
40612
+ const edges = strokeEdges(path, displayList.height, scale);
40569
40613
  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
40614
  fillEdgesScanline4x4(
40571
40615
  rgba,