@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.
@@ -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 ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
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) * ctmScale;
35904
+ st.dashPhase = num(1, 0);
35906
35905
  } else {
35907
35906
  st.dashArray = void 0;
35908
35907
  st.dashPhase = void 0;
@@ -36438,15 +36437,14 @@ function evaluateContentStreamToDisplayList(params) {
36438
36437
  break;
36439
36438
  }
36440
36439
  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
36440
  emit({ kind: "path", value: {
36444
36441
  segments: transformedSegments,
36445
36442
  fillColor: isFill && !evaluatedFillPattern ? st.fillColor : void 0,
36446
36443
  fillAlpha: isFill && !evaluatedFillPattern ? st.fillAlpha : void 0,
36447
36444
  strokeColor: isStroke ? st.strokeColor : void 0,
36448
36445
  strokeAlpha: isStroke ? st.strokeAlpha : void 0,
36449
- strokeWidth: scaledStrokeWidth,
36446
+ strokeWidth: st.strokeWidth,
36447
+ ...isStroke ? { strokeMatrix: [...st.ctm] } : {},
36450
36448
  ...st.lineCap !== 0 ? { lineCap: st.lineCap } : {},
36451
36449
  ...st.lineJoin !== 0 ? { lineJoin: st.lineJoin } : {},
36452
36450
  ...st.miterLimit !== 10 ? { miterLimit: st.miterLimit } : {},
@@ -36634,14 +36632,14 @@ function evaluateContentStreamToDisplayList(params) {
36634
36632
  if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
36635
36633
  const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
36636
36634
  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
36635
  const paint = {
36639
36636
  segments: transformedGlyphSegs,
36640
36637
  fillColor: isFillGlyph ? st.fillColor : void 0,
36641
36638
  fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
36642
36639
  strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
36643
36640
  strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
36644
- strokeWidth: isStrokeGlyph ? st.strokeWidth * ctmScale : 0,
36641
+ strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
36642
+ ...isStrokeGlyph ? { strokeMatrix: [...st.ctm] } : {},
36645
36643
  fillRule: "nonzero",
36646
36644
  ...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
36647
36645
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
@@ -40287,11 +40285,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
40287
40285
  rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
40288
40286
  rgba[idx + 3] = Math.round(outA * 255);
40289
40287
  }
40290
- function segmentsToScreenPaths(segments, pageHeight, scale) {
40288
+ function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
40291
40289
  const paths = [];
40292
40290
  let points = [];
40293
40291
  let current = [0, 0];
40294
- const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
40295
40292
  for (const segment of segments) {
40296
40293
  if (segment.kind === "move") {
40297
40294
  if (points.length) paths.push({ points, closed: false });
@@ -40330,6 +40327,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
40330
40327
  if (points.length) paths.push({ points, closed: false });
40331
40328
  return paths;
40332
40329
  }
40330
+ function inverseStrokeMatrix(matrix) {
40331
+ const [a, b, c, d, e, f] = matrix;
40332
+ const det = a * d - b * c;
40333
+ if (!Number.isFinite(det) || det === 0) return void 0;
40334
+ return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
40335
+ }
40336
+ function prepareStroke(path, scale) {
40337
+ const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
40338
+ const [a, b, c, d] = matrix;
40339
+ const area = Math.abs(a * d - b * c) * scale * scale;
40340
+ if (!(area > 0) || !Number.isFinite(area)) return void 0;
40341
+ const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
40342
+ let width = path.strokeWidth || 1;
40343
+ const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
40344
+ const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
40345
+ let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
40346
+ if (scaleX === scaleY) {
40347
+ width *= scaleX;
40348
+ } else {
40349
+ matrix[0] *= scaleX;
40350
+ matrix[1] *= scaleX;
40351
+ matrix[2] *= scaleY;
40352
+ matrix[3] *= scaleY;
40353
+ if (dashArray?.length) {
40354
+ const dashScale = Math.max(scaleX, scaleY);
40355
+ dashArray = dashArray.map((value) => value / dashScale);
40356
+ dashPhase /= dashScale;
40357
+ }
40358
+ }
40359
+ return { matrix, width, dashArray, dashPhase };
40360
+ }
40361
+ function strokeEdges(path, pageHeight, scale) {
40362
+ const stroke = prepareStroke(path, scale);
40363
+ if (!stroke) return [];
40364
+ const inverse = inverseStrokeMatrix(stroke.matrix);
40365
+ if (!inverse) return [];
40366
+ const [a, b, c, d, e, f] = stroke.matrix;
40367
+ const strokeScale = scale * Math.hypot(a, b, c, d);
40368
+ const project = (x, y) => [
40369
+ (inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
40370
+ (inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
40371
+ ];
40372
+ const toScreen = ([x, y]) => [
40373
+ (a * x / strokeScale + c * y / strokeScale + e) * scale,
40374
+ (pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
40375
+ ];
40376
+ const contours = strokeOutlines(
40377
+ segmentsToScreenPaths(path.segments, pageHeight, scale, project),
40378
+ stroke.width * strokeScale,
40379
+ path.lineCap ?? 0,
40380
+ path.lineJoin ?? 0,
40381
+ path.miterLimit ?? 10,
40382
+ stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
40383
+ stroke.dashPhase * strokeScale
40384
+ );
40385
+ return pathsToEdges(contours.map((points) => ({ points: points.map(toScreen), closed: true })));
40386
+ }
40333
40387
  function pathsToEdges(paths, closeSubpaths = false) {
40334
40388
  const edges = [];
40335
40389
  for (const { points, closed } of paths) {
@@ -40579,19 +40633,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40579
40633
  fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
40580
40634
  }
40581
40635
  if (path.strokeColor) {
40582
- const rawSw = path.strokeWidth * scale;
40583
- const sw = Math.max(1, rawSw);
40636
+ const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
40584
40637
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
40585
- const contours = strokeOutlines(
40586
- segmentsToScreenPaths(path.segments, displayList.height, scale),
40587
- sw,
40588
- path.lineCap ?? 0,
40589
- path.lineJoin ?? 0,
40590
- path.miterLimit ?? 10,
40591
- path.dashArray?.map((value) => Math.max(0, value * scale)),
40592
- (path.dashPhase ?? 0) * scale
40593
- );
40594
- const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
40638
+ const edges = strokeEdges(path, displayList.height, scale);
40595
40639
  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
40640
  fillEdgesScanline4x4(
40597
40641
  rgba,
@@ -40741,17 +40785,19 @@ function svgImage(image, pageHeight) {
40741
40785
  const [a, b, c, d, e, f] = image.matrix;
40742
40786
  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
40787
  }
40744
- function svgPathData(segments, height) {
40788
+ function svgPathData(segments, height, matrix) {
40745
40789
  const dParts = [];
40790
+ 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
40791
  for (const seg of segments) {
40747
40792
  if (seg.kind === "move") {
40748
- dParts.push(`M ${seg.x} ${height - seg.y}`);
40793
+ dParts.push(`M ${point(seg.x, seg.y)}`);
40749
40794
  } else if (seg.kind === "line") {
40750
- dParts.push(`L ${seg.x} ${height - seg.y}`);
40795
+ dParts.push(`L ${point(seg.x, seg.y)}`);
40751
40796
  } else if (seg.kind === "cubic") {
40752
- dParts.push(`C ${seg.x1} ${height - seg.y1} ${seg.x2} ${height - seg.y2} ${seg.x} ${height - seg.y}`);
40797
+ dParts.push(`C ${point(seg.x1, seg.y1)} ${point(seg.x2, seg.y2)} ${point(seg.x, seg.y)}`);
40753
40798
  } else if (seg.kind === "rect") {
40754
- dParts.push(`M ${seg.x} ${height - seg.y} h ${seg.width} v ${-seg.height} h ${-seg.width} Z`);
40799
+ 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`);
40800
+ else dParts.push(`M ${seg.x} ${height - seg.y} h ${seg.width} v ${-seg.height} h ${-seg.width} Z`);
40755
40801
  } else if (seg.kind === "close") {
40756
40802
  dParts.push("Z");
40757
40803
  }
@@ -40830,21 +40876,25 @@ function renderDisplayListToSvg(displayList, options = {}) {
40830
40876
  parts.push("</g>");
40831
40877
  } else if (operation.kind === "path") {
40832
40878
  const p = operation.value;
40833
- const pathData = svgPathData(p.segments, displayList.height);
40879
+ const prepared = p.strokeColor ? prepareStroke(p, Math.max(scaleX, scaleY)) : void 0;
40880
+ const matrix = prepared && (prepared.matrix[0] !== 1 || prepared.matrix[1] !== 0 || prepared.matrix[2] !== 0 || prepared.matrix[3] !== 1) ? prepared.matrix : void 0;
40881
+ const inverse = matrix ? inverseStrokeMatrix(matrix) : void 0;
40882
+ const pathData = svgPathData(p.segments, inverse ? 0 : displayList.height, inverse);
40883
+ const transformAttr = inverse && matrix ? ` transform="matrix(${matrix[0]} ${-matrix[1]} ${-matrix[2]} ${matrix[3]} ${matrix[4]} ${displayList.height - matrix[5]})"` : "";
40834
40884
  if (pathData) {
40835
40885
  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";
40886
+ 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
40887
  const fillRuleAttr = p.fillRule === "evenodd" ? ` fill-rule="evenodd"` : "";
40838
40888
  const fillOpacityAttr = p.fillAlpha !== void 0 && p.fillAlpha < 1 ? ` fill-opacity="${p.fillAlpha}"` : "";
40839
40889
  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}"`;
40890
+ const strokeWidthAttr = p.strokeWidth <= 0 && !matrix && !p.dashArray?.length ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${prepared?.width ?? p.strokeWidth}"`;
40841
40891
  const lineCapAttr = p.lineCap === 1 ? ` stroke-linecap="round"` : p.lineCap === 2 ? ` stroke-linecap="square"` : "";
40842
40892
  const lineJoinAttr = p.lineJoin === 1 ? ` stroke-linejoin="round"` : p.lineJoin === 2 ? ` stroke-linejoin="bevel"` : "";
40843
40893
  const miterLimitAttr = p.miterLimit !== void 0 && p.miterLimit !== 10 ? ` stroke-miterlimit="${p.miterLimit}"` : "";
40844
- const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
40845
- const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
40894
+ const dashArrayAttr = prepared?.dashArray?.length ? ` stroke-dasharray="${prepared.dashArray.join(" ")}"` : "";
40895
+ const dashOffsetAttr = prepared?.dashPhase ? ` stroke-dashoffset="${prepared.dashPhase}"` : "";
40846
40896
  const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
40847
- parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
40897
+ parts.push(` <path${labelAttr}${transformAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
40848
40898
  }
40849
40899
  } else if (operation.kind === "image") {
40850
40900
  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 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] } : {}
@@ -40269,11 +40267,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
40269
40267
  rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
40270
40268
  rgba[idx + 3] = Math.round(outA * 255);
40271
40269
  }
40272
- function segmentsToScreenPaths(segments, pageHeight, scale) {
40270
+ function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
40273
40271
  const paths = [];
40274
40272
  let points = [];
40275
40273
  let current = [0, 0];
40276
- const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
40277
40274
  for (const segment of segments) {
40278
40275
  if (segment.kind === "move") {
40279
40276
  if (points.length) paths.push({ points, closed: false });
@@ -40312,6 +40309,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
40312
40309
  if (points.length) paths.push({ points, closed: false });
40313
40310
  return paths;
40314
40311
  }
40312
+ function inverseStrokeMatrix(matrix) {
40313
+ const [a, b, c, d, e, f] = matrix;
40314
+ const det = a * d - b * c;
40315
+ if (!Number.isFinite(det) || det === 0) return void 0;
40316
+ return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
40317
+ }
40318
+ function prepareStroke(path, scale) {
40319
+ const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
40320
+ const [a, b, c, d] = matrix;
40321
+ const area = Math.abs(a * d - b * c) * scale * scale;
40322
+ if (!(area > 0) || !Number.isFinite(area)) return void 0;
40323
+ const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
40324
+ let width = path.strokeWidth || 1;
40325
+ const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
40326
+ const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
40327
+ let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
40328
+ if (scaleX === scaleY) {
40329
+ width *= scaleX;
40330
+ } else {
40331
+ matrix[0] *= scaleX;
40332
+ matrix[1] *= scaleX;
40333
+ matrix[2] *= scaleY;
40334
+ matrix[3] *= scaleY;
40335
+ if (dashArray?.length) {
40336
+ const dashScale = Math.max(scaleX, scaleY);
40337
+ dashArray = dashArray.map((value) => value / dashScale);
40338
+ dashPhase /= dashScale;
40339
+ }
40340
+ }
40341
+ return { matrix, width, dashArray, dashPhase };
40342
+ }
40343
+ function strokeEdges(path, pageHeight, scale) {
40344
+ const stroke = prepareStroke(path, scale);
40345
+ if (!stroke) return [];
40346
+ const inverse = inverseStrokeMatrix(stroke.matrix);
40347
+ if (!inverse) return [];
40348
+ const [a, b, c, d, e, f] = stroke.matrix;
40349
+ const strokeScale = scale * Math.hypot(a, b, c, d);
40350
+ const project = (x, y) => [
40351
+ (inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
40352
+ (inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
40353
+ ];
40354
+ const toScreen = ([x, y]) => [
40355
+ (a * x / strokeScale + c * y / strokeScale + e) * scale,
40356
+ (pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
40357
+ ];
40358
+ const contours = strokeOutlines(
40359
+ segmentsToScreenPaths(path.segments, pageHeight, scale, project),
40360
+ stroke.width * strokeScale,
40361
+ path.lineCap ?? 0,
40362
+ path.lineJoin ?? 0,
40363
+ path.miterLimit ?? 10,
40364
+ stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
40365
+ stroke.dashPhase * strokeScale
40366
+ );
40367
+ return pathsToEdges(contours.map((points) => ({ points: points.map(toScreen), closed: true })));
40368
+ }
40315
40369
  function pathsToEdges(paths, closeSubpaths = false) {
40316
40370
  const edges = [];
40317
40371
  for (const { points, closed } of paths) {
@@ -40561,19 +40615,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40561
40615
  fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
40562
40616
  }
40563
40617
  if (path.strokeColor) {
40564
- const rawSw = path.strokeWidth * scale;
40565
- const sw = Math.max(1, rawSw);
40618
+ const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
40566
40619
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
40567
- const contours = strokeOutlines(
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 })));
40620
+ const edges = strokeEdges(path, displayList.height, scale);
40577
40621
  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
40622
  fillEdgesScanline4x4(
40579
40623
  rgba,
@@ -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] } : {}
@@ -39807,11 +39805,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
39807
39805
  rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
39808
39806
  rgba[idx + 3] = Math.round(outA * 255);
39809
39807
  }
39810
- function segmentsToScreenPaths(segments, pageHeight, scale) {
39808
+ function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
39811
39809
  const paths = [];
39812
39810
  let points = [];
39813
39811
  let current = [0, 0];
39814
- const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
39815
39812
  for (const segment of segments) {
39816
39813
  if (segment.kind === "move") {
39817
39814
  if (points.length) paths.push({ points, closed: false });
@@ -39850,6 +39847,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
39850
39847
  if (points.length) paths.push({ points, closed: false });
39851
39848
  return paths;
39852
39849
  }
39850
+ function inverseStrokeMatrix(matrix) {
39851
+ const [a, b, c, d, e, f] = matrix;
39852
+ const det = a * d - b * c;
39853
+ if (!Number.isFinite(det) || det === 0) return void 0;
39854
+ return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
39855
+ }
39856
+ function prepareStroke(path, scale) {
39857
+ const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
39858
+ const [a, b, c, d] = matrix;
39859
+ const area = Math.abs(a * d - b * c) * scale * scale;
39860
+ if (!(area > 0) || !Number.isFinite(area)) return void 0;
39861
+ const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
39862
+ let width = path.strokeWidth || 1;
39863
+ const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
39864
+ const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
39865
+ let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
39866
+ if (scaleX === scaleY) {
39867
+ width *= scaleX;
39868
+ } else {
39869
+ matrix[0] *= scaleX;
39870
+ matrix[1] *= scaleX;
39871
+ matrix[2] *= scaleY;
39872
+ matrix[3] *= scaleY;
39873
+ if (dashArray?.length) {
39874
+ const dashScale = Math.max(scaleX, scaleY);
39875
+ dashArray = dashArray.map((value) => value / dashScale);
39876
+ dashPhase /= dashScale;
39877
+ }
39878
+ }
39879
+ return { matrix, width, dashArray, dashPhase };
39880
+ }
39881
+ function strokeEdges(path, pageHeight, scale) {
39882
+ const stroke = prepareStroke(path, scale);
39883
+ if (!stroke) return [];
39884
+ const inverse = inverseStrokeMatrix(stroke.matrix);
39885
+ if (!inverse) return [];
39886
+ const [a, b, c, d, e, f] = stroke.matrix;
39887
+ const strokeScale = scale * Math.hypot(a, b, c, d);
39888
+ const project = (x, y) => [
39889
+ (inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
39890
+ (inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
39891
+ ];
39892
+ const toScreen = ([x, y]) => [
39893
+ (a * x / strokeScale + c * y / strokeScale + e) * scale,
39894
+ (pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
39895
+ ];
39896
+ const contours = strokeOutlines(
39897
+ segmentsToScreenPaths(path.segments, pageHeight, scale, project),
39898
+ stroke.width * strokeScale,
39899
+ path.lineCap ?? 0,
39900
+ path.lineJoin ?? 0,
39901
+ path.miterLimit ?? 10,
39902
+ stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
39903
+ stroke.dashPhase * strokeScale
39904
+ );
39905
+ return pathsToEdges(contours.map((points) => ({ points: points.map(toScreen), closed: true })));
39906
+ }
39853
39907
  function pathsToEdges(paths, closeSubpaths = false) {
39854
39908
  const edges = [];
39855
39909
  for (const { points, closed } of paths) {
@@ -40099,19 +40153,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
40099
40153
  fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
40100
40154
  }
40101
40155
  if (path.strokeColor) {
40102
- const rawSw = path.strokeWidth * scale;
40103
- const sw = Math.max(1, rawSw);
40156
+ const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
40104
40157
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
40105
- const contours = strokeOutlines(
40106
- segmentsToScreenPaths(path.segments, displayList.height, scale),
40107
- sw,
40108
- path.lineCap ?? 0,
40109
- path.lineJoin ?? 0,
40110
- path.miterLimit ?? 10,
40111
- path.dashArray?.map((value) => Math.max(0, value * scale)),
40112
- (path.dashPhase ?? 0) * scale
40113
- );
40114
- const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
40158
+ const edges = strokeEdges(path, displayList.height, scale);
40115
40159
  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;
40116
40160
  fillEdgesScanline4x4(
40117
40161
  rgba,
@@ -11,8 +11,8 @@ import {
11
11
  readImageMetadata,
12
12
  resizeImage,
13
13
  rotateImage
14
- } from "../safe-bash/command-chunks/chunk-RDPJGIQF.js";
15
- import "../safe-bash/command-chunks/chunk-G3IIEU2N.js";
14
+ } from "../safe-bash/command-chunks/chunk-SVL6HYQL.js";
15
+ import "../safe-bash/command-chunks/chunk-KO4PXCNL.js";
16
16
  import {
17
17
  init_buffer
18
18
  } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";
@@ -31,7 +31,7 @@ import {
31
31
  PdfDocument,
32
32
  decodeFlate,
33
33
  rgb
34
- } from "../safe-bash/command-chunks/chunk-G3IIEU2N.js";
34
+ } from "../safe-bash/command-chunks/chunk-KO4PXCNL.js";
35
35
  import {
36
36
  init_buffer
37
37
  } from "../safe-bash/command-chunks/chunk-HX3SHTCE.js";