@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.
@@ -36417,11 +36417,10 @@ function evaluateContentStreamToDisplayList(params) {
36417
36417
  } else if (operator === "d") {
36418
36418
  const arrNode = ops[0]?.kind === "array" ? ops[0] : void 0;
36419
36419
  if (arrNode) {
36420
- const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
36421
- const nums = arrNode.items.map((it) => it.kind === "number" ? it.value * ctmScale : 0).filter((v) => v >= 0);
36420
+ const nums = arrNode.items.map((it) => it.kind === "number" ? it.value : 0).filter((v) => v >= 0);
36422
36421
  const sum = nums.reduce((a, b) => a + b, 0);
36423
36422
  st.dashArray = sum > 0 ? nums : void 0;
36424
- st.dashPhase = num(1, 0) * ctmScale;
36423
+ st.dashPhase = num(1, 0);
36425
36424
  } else {
36426
36425
  st.dashArray = void 0;
36427
36426
  st.dashPhase = void 0;
@@ -36553,10 +36552,11 @@ function evaluateContentStreamToDisplayList(params) {
36553
36552
  const patArr = params.cosDoc.resolveArray(dArr.items[0]);
36554
36553
  const phaseNode = params.cosDoc.resolve(dArr.items[1]);
36555
36554
  if (patArr) {
36556
- st.dashArray = patArr.items.map((it) => {
36555
+ const dashArray = patArr.items.map((it) => {
36557
36556
  const r = params.cosDoc.resolve(it);
36558
36557
  return r?.kind === "number" ? r.value : 0;
36559
- }).filter((n) => n > 0);
36558
+ }).filter((n) => n >= 0);
36559
+ st.dashArray = dashArray.some((value) => value > 0) ? dashArray : void 0;
36560
36560
  st.dashPhase = phaseNode?.kind === "number" ? phaseNode.value : 0;
36561
36561
  }
36562
36562
  }
@@ -36957,15 +36957,14 @@ function evaluateContentStreamToDisplayList(params) {
36957
36957
  break;
36958
36958
  }
36959
36959
  const fillRule = node.paint.includes("*") ? "evenodd" : "nonzero";
36960
- const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
36961
- const scaledStrokeWidth = st.strokeWidth === 0 ? 0 : st.strokeWidth * ctmScale;
36962
36960
  emit({ kind: "path", value: {
36963
36961
  segments: transformedSegments,
36964
36962
  fillColor: isFill && !evaluatedFillPattern ? st.fillColor : void 0,
36965
36963
  fillAlpha: isFill && !evaluatedFillPattern ? st.fillAlpha : void 0,
36966
36964
  strokeColor: isStroke ? st.strokeColor : void 0,
36967
36965
  strokeAlpha: isStroke ? st.strokeAlpha : void 0,
36968
- strokeWidth: scaledStrokeWidth,
36966
+ strokeWidth: st.strokeWidth,
36967
+ ...isStroke ? { strokeMatrix: [...st.ctm] } : {},
36969
36968
  ...st.lineCap !== 0 ? { lineCap: st.lineCap } : {},
36970
36969
  ...st.lineJoin !== 0 ? { lineJoin: st.lineJoin } : {},
36971
36970
  ...st.miterLimit !== 10 ? { miterLimit: st.miterLimit } : {},
@@ -37153,14 +37152,14 @@ function evaluateContentStreamToDisplayList(params) {
37153
37152
  if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
37154
37153
  const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
37155
37154
  const isStrokeGlyph = st.textRenderMode === 1 || st.textRenderMode === 2 || st.textRenderMode === 5 || st.textRenderMode === 6;
37156
- const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
37157
37155
  const paint = {
37158
37156
  segments: transformedGlyphSegs,
37159
37157
  fillColor: isFillGlyph ? st.fillColor : void 0,
37160
37158
  fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
37161
37159
  strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
37162
37160
  strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
37163
- strokeWidth: isStrokeGlyph ? st.strokeWidth * ctmScale : 0,
37161
+ strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
37162
+ ...isStrokeGlyph ? { strokeMatrix: [...st.ctm] } : {},
37164
37163
  fillRule: "nonzero",
37165
37164
  ...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
37166
37165
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
@@ -40256,7 +40255,7 @@ function dashSubpath(path, pattern, phase) {
40256
40255
  while (remaining <= 0) {
40257
40256
  if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
40258
40257
  if (index % 2 === 0) {
40259
- if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
40258
+ if (pattern[index] === 0) result.push({ points: [point, point], closed: false, zeroLengthDash: true });
40260
40259
  flush();
40261
40260
  }
40262
40261
  index = (index + 1) % pattern.length;
@@ -40271,7 +40270,7 @@ function dashSubpath(path, pattern, phase) {
40271
40270
  throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
40272
40271
  }
40273
40272
  let distance = 0;
40274
- while (distance < length) {
40273
+ while (length - distance > 8 * Number.EPSILON * Math.max(1, length)) {
40275
40274
  const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
40276
40275
  advance(point);
40277
40276
  const step = Math.min(remaining, length - distance);
@@ -40386,7 +40385,15 @@ function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], das
40386
40385
  let closed = subpath.closed;
40387
40386
  if (closed && points.length > 1 && Math.hypot(points[0][0] - points[points.length - 1][0], points[0][1] - points[points.length - 1][1]) <= 1e-14) points.pop();
40388
40387
  if (points.length < 3) closed = false;
40389
- if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
40388
+ if (points.length === 1 && cap === 2 && subpath.zeroLengthDash) {
40389
+ contour = [];
40390
+ const [x, y] = points[0];
40391
+ add(x - half, y - half);
40392
+ add(x + half, y - half);
40393
+ add(x + half, y + half);
40394
+ add(x - half, y + half);
40395
+ contours.push(contour);
40396
+ } else if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
40390
40397
  contour = [];
40391
40398
  const [x, y] = points[0];
40392
40399
  addCap([x, y], [x + 1, y]);
@@ -41503,11 +41510,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
41503
41510
  rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
41504
41511
  rgba[idx + 3] = Math.round(outA * 255);
41505
41512
  }
41506
- function segmentsToScreenPaths(segments, pageHeight, scale) {
41513
+ function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
41507
41514
  const paths = [];
41508
41515
  let points = [];
41509
41516
  let current = [0, 0];
41510
- const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
41511
41517
  for (const segment of segments) {
41512
41518
  if (segment.kind === "move") {
41513
41519
  if (points.length) paths.push({ points, closed: false });
@@ -41546,6 +41552,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
41546
41552
  if (points.length) paths.push({ points, closed: false });
41547
41553
  return paths;
41548
41554
  }
41555
+ function inverseStrokeMatrix(matrix) {
41556
+ const [a, b, c, d, e, f] = matrix;
41557
+ const det = a * d - b * c;
41558
+ if (!Number.isFinite(det) || det === 0) return void 0;
41559
+ return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
41560
+ }
41561
+ function prepareStroke(path, scale) {
41562
+ const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
41563
+ const [a, b, c, d] = matrix;
41564
+ const area = Math.abs(a * d - b * c) * scale * scale;
41565
+ if (!(area > 0) || !Number.isFinite(area)) return void 0;
41566
+ const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
41567
+ let width = path.strokeWidth || 1;
41568
+ const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
41569
+ const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
41570
+ let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
41571
+ if (scaleX === scaleY) {
41572
+ width *= scaleX;
41573
+ } else {
41574
+ matrix[0] *= scaleX;
41575
+ matrix[1] *= scaleX;
41576
+ matrix[2] *= scaleY;
41577
+ matrix[3] *= scaleY;
41578
+ if (dashArray?.length) {
41579
+ const dashScale = Math.max(scaleX, scaleY);
41580
+ dashArray = dashArray.map((value) => value / dashScale);
41581
+ dashPhase /= dashScale;
41582
+ }
41583
+ }
41584
+ return { matrix, width, dashArray, dashPhase };
41585
+ }
41586
+ function strokeContours(path, pageHeight, scale) {
41587
+ const stroke = prepareStroke(path, scale);
41588
+ if (!stroke) return [];
41589
+ const inverse = inverseStrokeMatrix(stroke.matrix);
41590
+ if (!inverse) return [];
41591
+ const [a, b, c, d, e, f] = stroke.matrix;
41592
+ const strokeScale = scale * Math.hypot(a, b, c, d);
41593
+ const project = (x, y) => [
41594
+ (inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
41595
+ (inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
41596
+ ];
41597
+ const toScreen = ([x, y]) => [
41598
+ (a * x / strokeScale + c * y / strokeScale + e) * scale,
41599
+ (pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
41600
+ ];
41601
+ const contours = strokeOutlines(
41602
+ segmentsToScreenPaths(path.segments, pageHeight, scale, project),
41603
+ stroke.width * strokeScale,
41604
+ path.lineCap ?? 0,
41605
+ path.lineJoin ?? 0,
41606
+ path.miterLimit ?? 10,
41607
+ stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
41608
+ stroke.dashPhase * strokeScale
41609
+ );
41610
+ return contours.map((points) => points.map(toScreen));
41611
+ }
41549
41612
  function pathsToEdges(paths, closeSubpaths = false) {
41550
41613
  const edges = [];
41551
41614
  for (const { points, closed } of paths) {
@@ -41795,19 +41858,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
41795
41858
  fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
41796
41859
  }
41797
41860
  if (path.strokeColor) {
41798
- const rawSw = path.strokeWidth * scale;
41799
- const sw = Math.max(1, rawSw);
41861
+ const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
41800
41862
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
41801
- const contours = strokeOutlines(
41802
- segmentsToScreenPaths(path.segments, displayList.height, scale),
41803
- sw,
41804
- path.lineCap ?? 0,
41805
- path.lineJoin ?? 0,
41806
- path.miterLimit ?? 10,
41807
- path.dashArray?.map((value) => Math.max(0, value * scale)),
41808
- (path.dashPhase ?? 0) * scale
41809
- );
41810
- const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
41863
+ const edges = pathsToEdges(strokeContours(path, displayList.height, scale).map((points) => ({ points, closed: true })));
41811
41864
  const clipScreen = path.clipRect ? [path.clipRect[0] * scale, (displayList.height - path.clipRect[3]) * scale, path.clipRect[2] * scale, (displayList.height - path.clipRect[1]) * scale] : void 0;
41812
41865
  fillEdgesScanline4x4(
41813
41866
  rgba,
@@ -41957,17 +42010,19 @@ function svgImage(image, pageHeight) {
41957
42010
  const [a, b, c, d, e, f] = image.matrix;
41958
42011
  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(""))}"/>`;
41959
42012
  }
41960
- function svgPathData(segments, height) {
42013
+ function svgPathData(segments, height, matrix) {
41961
42014
  const dParts = [];
42015
+ 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}`;
41962
42016
  for (const seg of segments) {
41963
42017
  if (seg.kind === "move") {
41964
- dParts.push(`M ${seg.x} ${height - seg.y}`);
42018
+ dParts.push(`M ${point(seg.x, seg.y)}`);
41965
42019
  } else if (seg.kind === "line") {
41966
- dParts.push(`L ${seg.x} ${height - seg.y}`);
42020
+ dParts.push(`L ${point(seg.x, seg.y)}`);
41967
42021
  } else if (seg.kind === "cubic") {
41968
- dParts.push(`C ${seg.x1} ${height - seg.y1} ${seg.x2} ${height - seg.y2} ${seg.x} ${height - seg.y}`);
42022
+ dParts.push(`C ${point(seg.x1, seg.y1)} ${point(seg.x2, seg.y2)} ${point(seg.x, seg.y)}`);
41969
42023
  } else if (seg.kind === "rect") {
41970
- dParts.push(`M ${seg.x} ${height - seg.y} h ${seg.width} v ${-seg.height} h ${-seg.width} Z`);
42024
+ 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`);
42025
+ else dParts.push(`M ${seg.x} ${height - seg.y} h ${seg.width} v ${-seg.height} h ${-seg.width} Z`);
41971
42026
  } else if (seg.kind === "close") {
41972
42027
  dParts.push("Z");
41973
42028
  }
@@ -42046,21 +42101,34 @@ function renderDisplayListToSvg(displayList, options = {}) {
42046
42101
  parts.push("</g>");
42047
42102
  } else if (operation.kind === "path") {
42048
42103
  const p = operation.value;
42049
- const pathData = svgPathData(p.segments, displayList.height);
42104
+ const prepared = p.strokeColor ? prepareStroke(p, Math.max(scaleX, scaleY)) : void 0;
42105
+ const outlineStroke = prepared && p.dashArray?.includes(0);
42106
+ const matrix = prepared && (prepared.matrix[0] !== 1 || prepared.matrix[1] !== 0 || prepared.matrix[2] !== 0 || prepared.matrix[3] !== 1) ? prepared.matrix : void 0;
42107
+ const inverse = matrix ? inverseStrokeMatrix(matrix) : void 0;
42108
+ const pathData = svgPathData(p.segments, inverse ? 0 : displayList.height, inverse);
42109
+ const transformAttr = inverse && matrix ? ` transform="matrix(${matrix[0]} ${-matrix[1]} ${-matrix[2]} ${matrix[3]} ${matrix[4]} ${displayList.height - matrix[5]})"` : "";
42050
42110
  if (pathData) {
42051
42111
  const fill = p.fillColor ? `rgb(${Math.round(p.fillColor.r * 255)},${Math.round(p.fillColor.g * 255)},${Math.round(p.fillColor.b * 255)})` : "none";
42052
- const stroke = p.strokeColor ? `rgb(${Math.round(p.strokeColor.r * 255)},${Math.round(p.strokeColor.g * 255)},${Math.round(p.strokeColor.b * 255)})` : "none";
42112
+ 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";
42053
42113
  const fillRuleAttr = p.fillRule === "evenodd" ? ` fill-rule="evenodd"` : "";
42054
42114
  const fillOpacityAttr = p.fillAlpha !== void 0 && p.fillAlpha < 1 ? ` fill-opacity="${p.fillAlpha}"` : "";
42055
42115
  const strokeOpacityAttr = p.strokeAlpha !== void 0 && p.strokeAlpha < 1 ? ` stroke-opacity="${p.strokeAlpha}"` : "";
42056
- const strokeWidthAttr = p.strokeWidth <= 0 ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${p.strokeWidth}"`;
42116
+ const strokeWidthAttr = p.strokeWidth <= 0 && !matrix && !p.dashArray?.length ? ` stroke-width="1" vector-effect="non-scaling-stroke"` : ` stroke-width="${prepared?.width ?? p.strokeWidth}"`;
42057
42117
  const lineCapAttr = p.lineCap === 1 ? ` stroke-linecap="round"` : p.lineCap === 2 ? ` stroke-linecap="square"` : "";
42058
42118
  const lineJoinAttr = p.lineJoin === 1 ? ` stroke-linejoin="round"` : p.lineJoin === 2 ? ` stroke-linejoin="bevel"` : "";
42059
42119
  const miterLimitAttr = p.miterLimit !== void 0 && p.miterLimit !== 10 ? ` stroke-miterlimit="${p.miterLimit}"` : "";
42060
- const dashArrayAttr = p.dashArray && p.dashArray.length > 0 ? ` stroke-dasharray="${p.dashArray.join(" ")}"` : "";
42061
- const dashOffsetAttr = p.dashPhase ? ` stroke-dashoffset="${p.dashPhase}"` : "";
42120
+ const dashArrayAttr = !outlineStroke && prepared?.dashArray?.length ? ` stroke-dasharray="${prepared.dashArray.join(" ")}"` : "";
42121
+ const dashOffsetAttr = !outlineStroke && prepared?.dashPhase ? ` stroke-dashoffset="${prepared.dashPhase}"` : "";
42062
42122
  const labelAttr = original.kind === "glyph" ? ` aria-label="${escapeXmlText(original.value.unicode)}"` : "";
42063
- parts.push(` <path${labelAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
42123
+ if (!outlineStroke || p.fillColor) {
42124
+ parts.push(` <path${labelAttr}${transformAttr} d="${pathData}" fill="${fill}"${fillRuleAttr}${fillOpacityAttr} stroke="${outlineStroke ? "none" : stroke}"${strokeOpacityAttr}${strokeWidthAttr}${lineCapAttr}${lineJoinAttr}${miterLimitAttr}${dashArrayAttr}${dashOffsetAttr}/>`);
42125
+ }
42126
+ if (outlineStroke) {
42127
+ const outlineScale = Math.max(scaleX, scaleY);
42128
+ const contours = strokeContours(p, displayList.height, outlineScale);
42129
+ const outlineData = contours.map((points) => points.map(([x, y], i) => `${i === 0 ? "M" : "L"} ${x / outlineScale} ${y / outlineScale}`).join(" ") + " Z").join(" ");
42130
+ if (outlineData) parts.push(` <path${labelAttr} d="${outlineData}" fill="${stroke}" fill-opacity="${p.strokeAlpha ?? 1}"/>`);
42131
+ }
42064
42132
  }
42065
42133
  } else if (operation.kind === "image") {
42066
42134
  parts.push(` ${svgImage(operation.value, displayList.height)}`);
@@ -48,11 +48,11 @@ import {
48
48
  trimImage,
49
49
  unflattenImage,
50
50
  unpremultiplyRgbaImage
51
- } from "./chunk-RDPJGIQF.js";
51
+ } from "./chunk-IOH3F3ZO.js";
52
52
  import {
53
53
  PdfDocument,
54
54
  encodePng
55
- } from "./chunk-G3IIEU2N.js";
55
+ } from "./chunk-XFUFHHLU.js";
56
56
  import {
57
57
  createLuaFilterCapability
58
58
  } from "./chunk-Y2KHC6TZ.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  PdfDocument,
3
3
  renderPdfPageToPng
4
- } from "./chunk-G3IIEU2N.js";
4
+ } from "./chunk-XFUFHHLU.js";
5
5
  import {
6
6
  init_buffer
7
7
  } from "./chunk-HX3SHTCE.js";
@@ -32212,11 +32212,10 @@ function evaluateContentStreamToDisplayList(params) {
32212
32212
  } else if (operator === "d") {
32213
32213
  const arrNode = ops[0]?.kind === "array" ? ops[0] : void 0;
32214
32214
  if (arrNode) {
32215
- const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
32216
- const nums = arrNode.items.map((it) => it.kind === "number" ? it.value * ctmScale : 0).filter((v) => v >= 0);
32215
+ const nums = arrNode.items.map((it) => it.kind === "number" ? it.value : 0).filter((v) => v >= 0);
32217
32216
  const sum = nums.reduce((a, b) => a + b, 0);
32218
32217
  st.dashArray = sum > 0 ? nums : void 0;
32219
- st.dashPhase = num(1, 0) * ctmScale;
32218
+ st.dashPhase = num(1, 0);
32220
32219
  } else {
32221
32220
  st.dashArray = void 0;
32222
32221
  st.dashPhase = void 0;
@@ -32348,10 +32347,11 @@ function evaluateContentStreamToDisplayList(params) {
32348
32347
  const patArr = params.cosDoc.resolveArray(dArr.items[0]);
32349
32348
  const phaseNode = params.cosDoc.resolve(dArr.items[1]);
32350
32349
  if (patArr) {
32351
- st.dashArray = patArr.items.map((it) => {
32350
+ const dashArray = patArr.items.map((it) => {
32352
32351
  const r = params.cosDoc.resolve(it);
32353
32352
  return r?.kind === "number" ? r.value : 0;
32354
- }).filter((n) => n > 0);
32353
+ }).filter((n) => n >= 0);
32354
+ st.dashArray = dashArray.some((value) => value > 0) ? dashArray : void 0;
32355
32355
  st.dashPhase = phaseNode?.kind === "number" ? phaseNode.value : 0;
32356
32356
  }
32357
32357
  }
@@ -32752,15 +32752,14 @@ function evaluateContentStreamToDisplayList(params) {
32752
32752
  break;
32753
32753
  }
32754
32754
  const fillRule = node.paint.includes("*") ? "evenodd" : "nonzero";
32755
- const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
32756
- const scaledStrokeWidth = st.strokeWidth === 0 ? 0 : st.strokeWidth * ctmScale;
32757
32755
  emit({ kind: "path", value: {
32758
32756
  segments: transformedSegments,
32759
32757
  fillColor: isFill && !evaluatedFillPattern ? st.fillColor : void 0,
32760
32758
  fillAlpha: isFill && !evaluatedFillPattern ? st.fillAlpha : void 0,
32761
32759
  strokeColor: isStroke ? st.strokeColor : void 0,
32762
32760
  strokeAlpha: isStroke ? st.strokeAlpha : void 0,
32763
- strokeWidth: scaledStrokeWidth,
32761
+ strokeWidth: st.strokeWidth,
32762
+ ...isStroke ? { strokeMatrix: [...st.ctm] } : {},
32764
32763
  ...st.lineCap !== 0 ? { lineCap: st.lineCap } : {},
32765
32764
  ...st.lineJoin !== 0 ? { lineJoin: st.lineJoin } : {},
32766
32765
  ...st.miterLimit !== 10 ? { miterLimit: st.miterLimit } : {},
@@ -32948,14 +32947,14 @@ function evaluateContentStreamToDisplayList(params) {
32948
32947
  if (st.textRenderMode >= 4 && st.textRenderMode <= 7) pendingTextClip.push(...transformedGlyphSegs);
32949
32948
  const isFillGlyph = st.textRenderMode === 0 || st.textRenderMode === 2 || st.textRenderMode === 4 || st.textRenderMode === 6;
32950
32949
  const isStrokeGlyph = st.textRenderMode === 1 || st.textRenderMode === 2 || st.textRenderMode === 5 || st.textRenderMode === 6;
32951
- const ctmScale = Math.max(1e-6, Math.hypot(st.ctm[0], st.ctm[1]));
32952
32950
  const paint = {
32953
32951
  segments: transformedGlyphSegs,
32954
32952
  fillColor: isFillGlyph ? st.fillColor : void 0,
32955
32953
  fillAlpha: isFillGlyph ? st.fillAlpha : void 0,
32956
32954
  strokeColor: isStrokeGlyph ? st.strokeColor : void 0,
32957
32955
  strokeAlpha: isStrokeGlyph ? st.strokeAlpha : void 0,
32958
- strokeWidth: isStrokeGlyph ? st.strokeWidth * ctmScale : 0,
32956
+ strokeWidth: isStrokeGlyph ? st.strokeWidth : 0,
32957
+ ...isStrokeGlyph ? { strokeMatrix: [...st.ctm] } : {},
32959
32958
  fillRule: "nonzero",
32960
32959
  ...st.blendMode && st.blendMode !== "Normal" ? { blendMode: st.blendMode } : {},
32961
32960
  ...st.clipRect ? { clipRect: [...st.clipRect] } : {}
@@ -34147,7 +34146,7 @@ function dashSubpath(path, pattern, phase) {
34147
34146
  while (remaining <= 0) {
34148
34147
  if (++steps > MAX_STROKE_VERTICES) throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
34149
34148
  if (index % 2 === 0) {
34150
- if (pattern[index] === 0) result.push({ points: [point, point], closed: false });
34149
+ if (pattern[index] === 0) result.push({ points: [point, point], closed: false, zeroLengthDash: true });
34151
34150
  flush();
34152
34151
  }
34153
34152
  index = (index + 1) % pattern.length;
@@ -34162,7 +34161,7 @@ function dashSubpath(path, pattern, phase) {
34162
34161
  throw new PdfError("E_LIMIT", "Stroke dash expansion exceeds the vertex limit");
34163
34162
  }
34164
34163
  let distance = 0;
34165
- while (distance < length) {
34164
+ while (length - distance > 8 * Number.EPSILON * Math.max(1, length)) {
34166
34165
  const point = [start[0] + dx * distance / length, start[1] + dy * distance / length];
34167
34166
  advance(point);
34168
34167
  const step = Math.min(remaining, length - distance);
@@ -34277,7 +34276,15 @@ function strokeOutlines(paths, width, cap, join, miterLimit, dashArray = [], das
34277
34276
  let closed = subpath.closed;
34278
34277
  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();
34279
34278
  if (points.length < 3) closed = false;
34280
- if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
34279
+ if (points.length === 1 && cap === 2 && subpath.zeroLengthDash) {
34280
+ contour = [];
34281
+ const [x, y] = points[0];
34282
+ add(x - half, y - half);
34283
+ add(x + half, y - half);
34284
+ add(x + half, y + half);
34285
+ add(x - half, y + half);
34286
+ contours.push(contour);
34287
+ } else if (points.length === 1 && subpath.points.length > 1 && cap === 1) {
34281
34288
  contour = [];
34282
34289
  const [x, y] = points[0];
34283
34290
  addCap([x, y], [x + 1, y]);
@@ -35001,11 +35008,10 @@ function blendPixel(rgba, width, height, px, py, color, alpha, blendMode, clipMa
35001
35008
  rgba[idx + 2] = Math.round((effB * a + cbB * dstA * (1 - a)) / outA * 255);
35002
35009
  rgba[idx + 3] = Math.round(outA * 255);
35003
35010
  }
35004
- function segmentsToScreenPaths(segments, pageHeight, scale) {
35011
+ function segmentsToScreenPaths(segments, pageHeight, scale, toScreen = (x, y) => [x * scale, (pageHeight - y) * scale]) {
35005
35012
  const paths = [];
35006
35013
  let points = [];
35007
35014
  let current = [0, 0];
35008
- const toScreen = (x, y) => [x * scale, (pageHeight - y) * scale];
35009
35015
  for (const segment of segments) {
35010
35016
  if (segment.kind === "move") {
35011
35017
  if (points.length) paths.push({ points, closed: false });
@@ -35044,6 +35050,63 @@ function segmentsToScreenPaths(segments, pageHeight, scale) {
35044
35050
  if (points.length) paths.push({ points, closed: false });
35045
35051
  return paths;
35046
35052
  }
35053
+ function inverseStrokeMatrix(matrix) {
35054
+ const [a, b, c, d, e, f] = matrix;
35055
+ const det = a * d - b * c;
35056
+ if (!Number.isFinite(det) || det === 0) return void 0;
35057
+ return [d / det, -b / det, -c / det, a / det, (c * f - d * e) / det, (b * e - a * f) / det];
35058
+ }
35059
+ function prepareStroke(path, scale) {
35060
+ const matrix = path.strokeMatrix ? [...path.strokeMatrix] : [1, 0, 0, 1, 0, 0];
35061
+ const [a, b, c, d] = matrix;
35062
+ const area = Math.abs(a * d - b * c) * scale * scale;
35063
+ if (!(area > 0) || !Number.isFinite(area)) return void 0;
35064
+ const normX = Math.hypot(a, b) * scale, normY = Math.hypot(c, d) * scale;
35065
+ let width = path.strokeWidth || 1;
35066
+ const scaleX = path.strokeWidth === 0 ? normY / area : Math.max(1, normY / (width * area));
35067
+ const scaleY = path.strokeWidth === 0 ? normX / area : Math.max(1, normX / (width * area));
35068
+ let dashArray = path.dashArray, dashPhase = path.dashPhase ?? 0;
35069
+ if (scaleX === scaleY) {
35070
+ width *= scaleX;
35071
+ } else {
35072
+ matrix[0] *= scaleX;
35073
+ matrix[1] *= scaleX;
35074
+ matrix[2] *= scaleY;
35075
+ matrix[3] *= scaleY;
35076
+ if (dashArray?.length) {
35077
+ const dashScale = Math.max(scaleX, scaleY);
35078
+ dashArray = dashArray.map((value) => value / dashScale);
35079
+ dashPhase /= dashScale;
35080
+ }
35081
+ }
35082
+ return { matrix, width, dashArray, dashPhase };
35083
+ }
35084
+ function strokeContours(path, pageHeight, scale) {
35085
+ const stroke = prepareStroke(path, scale);
35086
+ if (!stroke) return [];
35087
+ const inverse = inverseStrokeMatrix(stroke.matrix);
35088
+ if (!inverse) return [];
35089
+ const [a, b, c, d, e, f] = stroke.matrix;
35090
+ const strokeScale = scale * Math.hypot(a, b, c, d);
35091
+ const project = (x, y) => [
35092
+ (inverse[0] * x + inverse[2] * y + inverse[4]) * strokeScale,
35093
+ (inverse[1] * x + inverse[3] * y + inverse[5]) * strokeScale
35094
+ ];
35095
+ const toScreen = ([x, y]) => [
35096
+ (a * x / strokeScale + c * y / strokeScale + e) * scale,
35097
+ (pageHeight - b * x / strokeScale - d * y / strokeScale - f) * scale
35098
+ ];
35099
+ const contours = strokeOutlines(
35100
+ segmentsToScreenPaths(path.segments, pageHeight, scale, project),
35101
+ stroke.width * strokeScale,
35102
+ path.lineCap ?? 0,
35103
+ path.lineJoin ?? 0,
35104
+ path.miterLimit ?? 10,
35105
+ stroke.dashArray?.map((value) => Math.max(0, value * strokeScale)),
35106
+ stroke.dashPhase * strokeScale
35107
+ );
35108
+ return contours.map((points) => points.map(toScreen));
35109
+ }
35047
35110
  function pathsToEdges(paths, closeSubpaths = false) {
35048
35111
  const edges = [];
35049
35112
  for (const { points, closed } of paths) {
@@ -35293,19 +35356,9 @@ function renderDisplayListToBitmap(displayList, options = {}) {
35293
35356
  fillEdgesScanline4x4(rgba, width, height, edges, path.fillColor, path.fillAlpha ?? 1, path.fillRule ?? "nonzero", clipScreen, original.kind === "glyph" ? aaTxt : aaVec, path.blendMode, clipMask);
35294
35357
  }
35295
35358
  if (path.strokeColor) {
35296
- const rawSw = path.strokeWidth * scale;
35297
- const sw = Math.max(1, rawSw);
35359
+ const rawSw = path.strokeWidth * scale * (path.strokeMatrix ? Math.hypot(path.strokeMatrix[0], path.strokeMatrix[1]) : 1);
35298
35360
  const strokeAlpha = options.thinLineMode === "shape" && rawSw < 1 ? (path.strokeAlpha ?? 1) * Math.max(0.25, rawSw) : path.strokeAlpha ?? 1;
35299
- const contours = strokeOutlines(
35300
- segmentsToScreenPaths(path.segments, displayList.height, scale),
35301
- sw,
35302
- path.lineCap ?? 0,
35303
- path.lineJoin ?? 0,
35304
- path.miterLimit ?? 10,
35305
- path.dashArray?.map((value) => Math.max(0, value * scale)),
35306
- (path.dashPhase ?? 0) * scale
35307
- );
35308
- const edges = pathsToEdges(contours.map((points) => ({ points, closed: true })));
35361
+ const edges = pathsToEdges(strokeContours(path, displayList.height, scale).map((points) => ({ points, closed: true })));
35309
35362
  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;
35310
35363
  fillEdgesScanline4x4(
35311
35364
  rgba,