emf-converter 4.9.0 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +101 -16
- package/dist/browser.mjs +101 -16
- package/dist/index.js +101 -16
- package/dist/index.mjs +101 -16
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -29238,11 +29238,42 @@ function penPolygon(width, height = width) {
|
|
|
29238
29238
|
penCache.set(key, pen);
|
|
29239
29239
|
return pen;
|
|
29240
29240
|
}
|
|
29241
|
-
|
|
29241
|
+
var matrixPenCache = /* @__PURE__ */ new Map();
|
|
29242
|
+
function penPolygonMatrix(width, m) {
|
|
29243
|
+
const key = `${width},${m.join(",")}`;
|
|
29244
|
+
const cached = matrixPenCache.get(key);
|
|
29245
|
+
if (cached) {
|
|
29246
|
+
return cached;
|
|
29247
|
+
}
|
|
29248
|
+
const r = Math.ceil(width / 2);
|
|
29249
|
+
const mirror2 = m[0] * m[3] - m[1] * m[2] < 0 ? -1 : 1;
|
|
29250
|
+
const bez = ellipseBeziers(-r, -r, r, r);
|
|
29251
|
+
const dev = [];
|
|
29252
|
+
for (let i = 0; i < 14; i += 2) {
|
|
29253
|
+
const x = bez[i];
|
|
29254
|
+
const y = bez[i + 1] * mirror2;
|
|
29255
|
+
dev.push(Math.round(m[0] * x + m[2] * y), Math.round(m[1] * x + m[3] * y));
|
|
29256
|
+
}
|
|
29257
|
+
const f = flattenBezierPath(dev);
|
|
29258
|
+
const half = [];
|
|
29259
|
+
for (let i = 0; i + 1 < f.length; i += 2) {
|
|
29260
|
+
half.push([f[i], f[i + 1]]);
|
|
29261
|
+
}
|
|
29262
|
+
half.pop();
|
|
29263
|
+
const pen = [...half, ...half.map((p) => [0 - p[0] || 0, 0 - p[1] || 0])];
|
|
29264
|
+
matrixPenCache.set(key, pen);
|
|
29265
|
+
return pen;
|
|
29266
|
+
}
|
|
29267
|
+
function drawVertices(pen, dx, dy, width = 1, height = width, matrix) {
|
|
29242
29268
|
const n = pen.length;
|
|
29243
29269
|
const axisVertex = pen.some((q) => q[1] === 0);
|
|
29244
|
-
|
|
29245
|
-
|
|
29270
|
+
let yMagnitude = Math.abs(dy) * (width === height ? 1 : width);
|
|
29271
|
+
let xMagnitude = Math.abs(dx) * (width === height ? 2 : height);
|
|
29272
|
+
if (matrix) {
|
|
29273
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29274
|
+
xMagnitude = Math.abs((matrix[3] * dx - matrix[2] * dy) / det);
|
|
29275
|
+
yMagnitude = Math.abs((-matrix[1] * dx + matrix[0] * dy) / det);
|
|
29276
|
+
}
|
|
29246
29277
|
const steep = yMagnitude > xMagnitude || yMagnitude === xMagnitude && axisVertex;
|
|
29247
29278
|
const s = (steep ? dy < 0 : dx < 0 || dx === 0 && dy < 0) ? -1 : 1;
|
|
29248
29279
|
let best = 0;
|
|
@@ -29262,7 +29293,7 @@ function drawVertices(pen, dx, dy, width = 1, height = width) {
|
|
|
29262
29293
|
function halfPixel(v) {
|
|
29263
29294
|
return Math.sign(v) * 8 * Math.floor((Math.abs(v) + 4) / 8);
|
|
29264
29295
|
}
|
|
29265
|
-
function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
29296
|
+
function perpendicularVectors(width, dx0, dy0, height = width, matrixPen) {
|
|
29266
29297
|
let dx = dx0;
|
|
29267
29298
|
let dy = dy0;
|
|
29268
29299
|
const flip = dx < 0 || dx === 0 && dy < 0;
|
|
@@ -29270,7 +29301,7 @@ function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
|
29270
29301
|
dx = -dx;
|
|
29271
29302
|
dy = -dy;
|
|
29272
29303
|
}
|
|
29273
|
-
const pen = penPolygon(width, height);
|
|
29304
|
+
const pen = matrixPen ?? penPolygon(width, height);
|
|
29274
29305
|
const n = pen.length;
|
|
29275
29306
|
const nx = -dy;
|
|
29276
29307
|
const ny = dx;
|
|
@@ -29309,7 +29340,15 @@ function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
|
29309
29340
|
const vx = rounded[0], vy = rounded[1];
|
|
29310
29341
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29311
29342
|
}
|
|
29312
|
-
function squareExtension(width, dx, dy, scale = 1, height = width) {
|
|
29343
|
+
function squareExtension(width, dx, dy, scale = 1, height = width, matrix) {
|
|
29344
|
+
if (matrix) {
|
|
29345
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29346
|
+
const lx = (matrix[3] * dx - matrix[2] * dy) / det;
|
|
29347
|
+
const ly = (-matrix[1] * dx + matrix[0] * dy) / det;
|
|
29348
|
+
const l = Math.hypot(lx, ly);
|
|
29349
|
+
const q = width / 2 * scale / l;
|
|
29350
|
+
return [Math.floor((matrix[0] * lx + matrix[2] * ly) * q + 0.5), Math.floor((matrix[1] * lx + matrix[3] * ly) * q + 0.5)];
|
|
29351
|
+
}
|
|
29313
29352
|
const len = width === height ? Math.hypot(dx, dy) : Math.hypot(dx, dy * width / height);
|
|
29314
29353
|
const r = width / 2 * scale;
|
|
29315
29354
|
return [Math.floor(dx / len * r + 0.5), Math.floor(dy / len * r + 0.5)];
|
|
@@ -29332,7 +29371,7 @@ var Outliner = class {
|
|
|
29332
29371
|
this.opts = opts;
|
|
29333
29372
|
this.out = out;
|
|
29334
29373
|
this.pts = [];
|
|
29335
|
-
this.pen = penPolygon(opts.width, opts.height);
|
|
29374
|
+
this.pen = opts.matrix && opts.deviceNib ? penPolygonMatrix(opts.width, opts.matrix) : penPolygon(opts.width, opts.height);
|
|
29336
29375
|
this.n = this.pen.length;
|
|
29337
29376
|
this.rr = opts.cap === "round" && opts.join === "round";
|
|
29338
29377
|
this.originalRoundJoinSides = opts.join === "round" && opts.cap !== "flat";
|
|
@@ -29347,10 +29386,11 @@ var Outliner = class {
|
|
|
29347
29386
|
const dx = dir ? dir[0] : b[0] - a[0];
|
|
29348
29387
|
const dy = dir ? dir[1] : b[1] - a[1];
|
|
29349
29388
|
const d = drawDir ?? [dx, dy];
|
|
29350
|
-
const
|
|
29389
|
+
const nibMatrix = this.opts.deviceNib ? this.opts.matrix : void 0;
|
|
29390
|
+
const [L, R] = drawVertices(this.pen, d[0], d[1], this.opts.width, this.opts.height, nibMatrix);
|
|
29351
29391
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29352
|
-
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height);
|
|
29353
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29392
|
+
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height, nibMatrix ? this.pen : void 0);
|
|
29393
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height, nibMatrix), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29354
29394
|
}
|
|
29355
29395
|
push(p, v) {
|
|
29356
29396
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29463,7 +29503,7 @@ var Outliner = class {
|
|
|
29463
29503
|
const sv = this.capSide(s, from);
|
|
29464
29504
|
const ev = this.capSide(s, to);
|
|
29465
29505
|
if (cap === "square") {
|
|
29466
|
-
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale, this.opts.height);
|
|
29506
|
+
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale, this.opts.height, this.opts.deviceNib ? this.opts.matrix : void 0);
|
|
29467
29507
|
const e = start ? [-e0[0], -e0[1]] : e0;
|
|
29468
29508
|
this.push(p, [sv[0] + e[0], sv[1] + e[1]]);
|
|
29469
29509
|
this.push(p, [ev[0] + e[0], ev[1] + e[1]]);
|
|
@@ -29643,7 +29683,7 @@ var Outliner = class {
|
|
|
29643
29683
|
this.flush();
|
|
29644
29684
|
}
|
|
29645
29685
|
};
|
|
29646
|
-
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric) {
|
|
29686
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric, matrix) {
|
|
29647
29687
|
const out = [];
|
|
29648
29688
|
const dashes = [];
|
|
29649
29689
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29663,8 +29703,9 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29663
29703
|
const [x0, y0] = P[i];
|
|
29664
29704
|
const [x1, y1] = P[i + 1];
|
|
29665
29705
|
const dir = [x1 - x0, y1 - y0];
|
|
29666
|
-
const
|
|
29667
|
-
const
|
|
29706
|
+
const det = matrix ? matrix[0] * matrix[3] - matrix[1] * matrix[2] : 1;
|
|
29707
|
+
const real = matrix ? Math.hypot((matrix[3] * dir[0] - matrix[2] * dir[1]) / det, (-matrix[1] * dir[0] + matrix[0] * dir[1]) / det) : metric ? Math.hypot(dir[0] / metric[0], dir[1] / metric[1]) : Math.hypot(dir[0], dir[1]);
|
|
29708
|
+
const len = metric || matrix ? real : wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29668
29709
|
if (len === 0) {
|
|
29669
29710
|
if (on && cur) {
|
|
29670
29711
|
cur.pts.push(P[i + 1]);
|
|
@@ -29708,7 +29749,35 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29708
29749
|
}
|
|
29709
29750
|
return out;
|
|
29710
29751
|
}
|
|
29752
|
+
function widenInLogicalSpace(path, opts, m) {
|
|
29753
|
+
const [a, b, c, d] = m;
|
|
29754
|
+
const det = a * d - b * c;
|
|
29755
|
+
const inverse = (x, y) => [(d * x - c * y) / det, (-b * x + a * y) / det];
|
|
29756
|
+
const logical = new GdiRasterPath();
|
|
29757
|
+
for (const fig of path.figures) {
|
|
29758
|
+
const pts = [];
|
|
29759
|
+
for (let i = 0; i + 1 < fig.pts.length; i += 2) {
|
|
29760
|
+
pts.push(...inverse(fig.pts[i], fig.pts[i + 1]));
|
|
29761
|
+
}
|
|
29762
|
+
const copy = { pts, closed: fig.closed, roundWiden: fig.roundWiden, curveSegs: fig.curveSegs };
|
|
29763
|
+
if (fig.tangents) {
|
|
29764
|
+
copy.tangents = new Map([...fig.tangents].map(([k, v]) => [k, inverse(v[0], v[1])]));
|
|
29765
|
+
}
|
|
29766
|
+
logical.figures.push(copy);
|
|
29767
|
+
}
|
|
29768
|
+
const outline = widenPath(logical, { ...opts, matrix: void 0, height: void 0 });
|
|
29769
|
+
return outline.map((poly) => {
|
|
29770
|
+
const out = [];
|
|
29771
|
+
for (let i = 0; i + 1 < poly.length; i += 2) {
|
|
29772
|
+
out.push(Math.round(a * poly[i] + c * poly[i + 1]), Math.round(b * poly[i] + d * poly[i + 1]));
|
|
29773
|
+
}
|
|
29774
|
+
return out;
|
|
29775
|
+
});
|
|
29776
|
+
}
|
|
29711
29777
|
function widenPath(path, opts) {
|
|
29778
|
+
if (opts.matrix && !(opts.deviceNib && opts.join === "round")) {
|
|
29779
|
+
return widenInLogicalSpace(path, opts, opts.matrix);
|
|
29780
|
+
}
|
|
29712
29781
|
const out = [];
|
|
29713
29782
|
const dashed = !!opts.dashes && opts.dashes.length > 0;
|
|
29714
29783
|
for (const fig of path.figures) {
|
|
@@ -29740,7 +29809,7 @@ function widenPath(path, opts) {
|
|
|
29740
29809
|
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.dashMetric ? opts.width / opts.dashMetric[0] : opts.width;
|
|
29741
29810
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29742
29811
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29743
|
-
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric)) {
|
|
29812
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric, opts.deviceNib ? opts.matrix : void 0)) {
|
|
29744
29813
|
const pts = [piece.pts[0]];
|
|
29745
29814
|
const pdirs = [];
|
|
29746
29815
|
const pdraws = [];
|
|
@@ -30008,8 +30077,24 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30008
30077
|
const capBits = flags & 3840;
|
|
30009
30078
|
const joinBits = flags & 61440;
|
|
30010
30079
|
const ellipse = !rCtx.wholeDevicePixels && state.penWidth * Math.abs(matrix[0]) * 16 >= 1 && state.penWidth * Math.abs(matrix[3]) * 16 >= 1 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6 && Math.abs(Math.abs(matrix[0]) - Math.abs(matrix[3])) > 1e-6;
|
|
30011
|
-
const
|
|
30080
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
30081
|
+
const rotatedOrSheared = Math.abs(matrix[1]) >= 1e-6 || Math.abs(matrix[2]) >= 1e-6;
|
|
30082
|
+
const quarterTurn = Math.abs(matrix[0]) < 1e-9 && Math.abs(matrix[3]) < 1e-9;
|
|
30083
|
+
const general = !rCtx.wholeDevicePixels && rotatedOrSheared && !quarterTurn && Math.abs(det) > 1e-9 && state.penWidth * Math.sqrt(Math.abs(det)) * 16 >= 1;
|
|
30084
|
+
const dashes = state.penExtended ? ellipse || general ? geometricStyle(flags, state.penWidth, state.penUserStyle, 1) : geometricStyle(flags, widthPx, state.penUserStyle, widthPx / (state.penWidth || 1)) : null;
|
|
30012
30085
|
const dashMetric = ellipse && dashes ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : void 0;
|
|
30086
|
+
if (general) {
|
|
30087
|
+
return {
|
|
30088
|
+
width: Math.round(state.penWidth * 16),
|
|
30089
|
+
matrix: [matrix[0], matrix[1], matrix[2], matrix[3]],
|
|
30090
|
+
deviceNib: true,
|
|
30091
|
+
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30092
|
+
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30093
|
+
miterLimit: state.miterLimit ?? 10,
|
|
30094
|
+
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30095
|
+
shortenDashes: (flags & 15) !== 7
|
|
30096
|
+
};
|
|
30097
|
+
}
|
|
30013
30098
|
return {
|
|
30014
30099
|
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : widthPx) * 16),
|
|
30015
30100
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
package/dist/browser.mjs
CHANGED
|
@@ -29236,11 +29236,42 @@ function penPolygon(width, height = width) {
|
|
|
29236
29236
|
penCache.set(key, pen);
|
|
29237
29237
|
return pen;
|
|
29238
29238
|
}
|
|
29239
|
-
|
|
29239
|
+
var matrixPenCache = /* @__PURE__ */ new Map();
|
|
29240
|
+
function penPolygonMatrix(width, m) {
|
|
29241
|
+
const key = `${width},${m.join(",")}`;
|
|
29242
|
+
const cached = matrixPenCache.get(key);
|
|
29243
|
+
if (cached) {
|
|
29244
|
+
return cached;
|
|
29245
|
+
}
|
|
29246
|
+
const r = Math.ceil(width / 2);
|
|
29247
|
+
const mirror2 = m[0] * m[3] - m[1] * m[2] < 0 ? -1 : 1;
|
|
29248
|
+
const bez = ellipseBeziers(-r, -r, r, r);
|
|
29249
|
+
const dev = [];
|
|
29250
|
+
for (let i = 0; i < 14; i += 2) {
|
|
29251
|
+
const x = bez[i];
|
|
29252
|
+
const y = bez[i + 1] * mirror2;
|
|
29253
|
+
dev.push(Math.round(m[0] * x + m[2] * y), Math.round(m[1] * x + m[3] * y));
|
|
29254
|
+
}
|
|
29255
|
+
const f = flattenBezierPath(dev);
|
|
29256
|
+
const half = [];
|
|
29257
|
+
for (let i = 0; i + 1 < f.length; i += 2) {
|
|
29258
|
+
half.push([f[i], f[i + 1]]);
|
|
29259
|
+
}
|
|
29260
|
+
half.pop();
|
|
29261
|
+
const pen = [...half, ...half.map((p) => [0 - p[0] || 0, 0 - p[1] || 0])];
|
|
29262
|
+
matrixPenCache.set(key, pen);
|
|
29263
|
+
return pen;
|
|
29264
|
+
}
|
|
29265
|
+
function drawVertices(pen, dx, dy, width = 1, height = width, matrix) {
|
|
29240
29266
|
const n = pen.length;
|
|
29241
29267
|
const axisVertex = pen.some((q) => q[1] === 0);
|
|
29242
|
-
|
|
29243
|
-
|
|
29268
|
+
let yMagnitude = Math.abs(dy) * (width === height ? 1 : width);
|
|
29269
|
+
let xMagnitude = Math.abs(dx) * (width === height ? 2 : height);
|
|
29270
|
+
if (matrix) {
|
|
29271
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29272
|
+
xMagnitude = Math.abs((matrix[3] * dx - matrix[2] * dy) / det);
|
|
29273
|
+
yMagnitude = Math.abs((-matrix[1] * dx + matrix[0] * dy) / det);
|
|
29274
|
+
}
|
|
29244
29275
|
const steep = yMagnitude > xMagnitude || yMagnitude === xMagnitude && axisVertex;
|
|
29245
29276
|
const s = (steep ? dy < 0 : dx < 0 || dx === 0 && dy < 0) ? -1 : 1;
|
|
29246
29277
|
let best = 0;
|
|
@@ -29260,7 +29291,7 @@ function drawVertices(pen, dx, dy, width = 1, height = width) {
|
|
|
29260
29291
|
function halfPixel(v) {
|
|
29261
29292
|
return Math.sign(v) * 8 * Math.floor((Math.abs(v) + 4) / 8);
|
|
29262
29293
|
}
|
|
29263
|
-
function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
29294
|
+
function perpendicularVectors(width, dx0, dy0, height = width, matrixPen) {
|
|
29264
29295
|
let dx = dx0;
|
|
29265
29296
|
let dy = dy0;
|
|
29266
29297
|
const flip = dx < 0 || dx === 0 && dy < 0;
|
|
@@ -29268,7 +29299,7 @@ function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
|
29268
29299
|
dx = -dx;
|
|
29269
29300
|
dy = -dy;
|
|
29270
29301
|
}
|
|
29271
|
-
const pen = penPolygon(width, height);
|
|
29302
|
+
const pen = matrixPen ?? penPolygon(width, height);
|
|
29272
29303
|
const n = pen.length;
|
|
29273
29304
|
const nx = -dy;
|
|
29274
29305
|
const ny = dx;
|
|
@@ -29307,7 +29338,15 @@ function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
|
29307
29338
|
const vx = rounded[0], vy = rounded[1];
|
|
29308
29339
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29309
29340
|
}
|
|
29310
|
-
function squareExtension(width, dx, dy, scale = 1, height = width) {
|
|
29341
|
+
function squareExtension(width, dx, dy, scale = 1, height = width, matrix) {
|
|
29342
|
+
if (matrix) {
|
|
29343
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29344
|
+
const lx = (matrix[3] * dx - matrix[2] * dy) / det;
|
|
29345
|
+
const ly = (-matrix[1] * dx + matrix[0] * dy) / det;
|
|
29346
|
+
const l = Math.hypot(lx, ly);
|
|
29347
|
+
const q = width / 2 * scale / l;
|
|
29348
|
+
return [Math.floor((matrix[0] * lx + matrix[2] * ly) * q + 0.5), Math.floor((matrix[1] * lx + matrix[3] * ly) * q + 0.5)];
|
|
29349
|
+
}
|
|
29311
29350
|
const len = width === height ? Math.hypot(dx, dy) : Math.hypot(dx, dy * width / height);
|
|
29312
29351
|
const r = width / 2 * scale;
|
|
29313
29352
|
return [Math.floor(dx / len * r + 0.5), Math.floor(dy / len * r + 0.5)];
|
|
@@ -29330,7 +29369,7 @@ var Outliner = class {
|
|
|
29330
29369
|
this.opts = opts;
|
|
29331
29370
|
this.out = out;
|
|
29332
29371
|
this.pts = [];
|
|
29333
|
-
this.pen = penPolygon(opts.width, opts.height);
|
|
29372
|
+
this.pen = opts.matrix && opts.deviceNib ? penPolygonMatrix(opts.width, opts.matrix) : penPolygon(opts.width, opts.height);
|
|
29334
29373
|
this.n = this.pen.length;
|
|
29335
29374
|
this.rr = opts.cap === "round" && opts.join === "round";
|
|
29336
29375
|
this.originalRoundJoinSides = opts.join === "round" && opts.cap !== "flat";
|
|
@@ -29345,10 +29384,11 @@ var Outliner = class {
|
|
|
29345
29384
|
const dx = dir ? dir[0] : b[0] - a[0];
|
|
29346
29385
|
const dy = dir ? dir[1] : b[1] - a[1];
|
|
29347
29386
|
const d = drawDir ?? [dx, dy];
|
|
29348
|
-
const
|
|
29387
|
+
const nibMatrix = this.opts.deviceNib ? this.opts.matrix : void 0;
|
|
29388
|
+
const [L, R] = drawVertices(this.pen, d[0], d[1], this.opts.width, this.opts.height, nibMatrix);
|
|
29349
29389
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29350
|
-
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height);
|
|
29351
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29390
|
+
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height, nibMatrix ? this.pen : void 0);
|
|
29391
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height, nibMatrix), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29352
29392
|
}
|
|
29353
29393
|
push(p, v) {
|
|
29354
29394
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29461,7 +29501,7 @@ var Outliner = class {
|
|
|
29461
29501
|
const sv = this.capSide(s, from);
|
|
29462
29502
|
const ev = this.capSide(s, to);
|
|
29463
29503
|
if (cap === "square") {
|
|
29464
|
-
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale, this.opts.height);
|
|
29504
|
+
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale, this.opts.height, this.opts.deviceNib ? this.opts.matrix : void 0);
|
|
29465
29505
|
const e = start ? [-e0[0], -e0[1]] : e0;
|
|
29466
29506
|
this.push(p, [sv[0] + e[0], sv[1] + e[1]]);
|
|
29467
29507
|
this.push(p, [ev[0] + e[0], ev[1] + e[1]]);
|
|
@@ -29641,7 +29681,7 @@ var Outliner = class {
|
|
|
29641
29681
|
this.flush();
|
|
29642
29682
|
}
|
|
29643
29683
|
};
|
|
29644
|
-
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric) {
|
|
29684
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric, matrix) {
|
|
29645
29685
|
const out = [];
|
|
29646
29686
|
const dashes = [];
|
|
29647
29687
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29661,8 +29701,9 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29661
29701
|
const [x0, y0] = P[i];
|
|
29662
29702
|
const [x1, y1] = P[i + 1];
|
|
29663
29703
|
const dir = [x1 - x0, y1 - y0];
|
|
29664
|
-
const
|
|
29665
|
-
const
|
|
29704
|
+
const det = matrix ? matrix[0] * matrix[3] - matrix[1] * matrix[2] : 1;
|
|
29705
|
+
const real = matrix ? Math.hypot((matrix[3] * dir[0] - matrix[2] * dir[1]) / det, (-matrix[1] * dir[0] + matrix[0] * dir[1]) / det) : metric ? Math.hypot(dir[0] / metric[0], dir[1] / metric[1]) : Math.hypot(dir[0], dir[1]);
|
|
29706
|
+
const len = metric || matrix ? real : wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29666
29707
|
if (len === 0) {
|
|
29667
29708
|
if (on && cur) {
|
|
29668
29709
|
cur.pts.push(P[i + 1]);
|
|
@@ -29706,7 +29747,35 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29706
29747
|
}
|
|
29707
29748
|
return out;
|
|
29708
29749
|
}
|
|
29750
|
+
function widenInLogicalSpace(path, opts, m) {
|
|
29751
|
+
const [a, b, c, d] = m;
|
|
29752
|
+
const det = a * d - b * c;
|
|
29753
|
+
const inverse = (x, y) => [(d * x - c * y) / det, (-b * x + a * y) / det];
|
|
29754
|
+
const logical = new GdiRasterPath();
|
|
29755
|
+
for (const fig of path.figures) {
|
|
29756
|
+
const pts = [];
|
|
29757
|
+
for (let i = 0; i + 1 < fig.pts.length; i += 2) {
|
|
29758
|
+
pts.push(...inverse(fig.pts[i], fig.pts[i + 1]));
|
|
29759
|
+
}
|
|
29760
|
+
const copy = { pts, closed: fig.closed, roundWiden: fig.roundWiden, curveSegs: fig.curveSegs };
|
|
29761
|
+
if (fig.tangents) {
|
|
29762
|
+
copy.tangents = new Map([...fig.tangents].map(([k, v]) => [k, inverse(v[0], v[1])]));
|
|
29763
|
+
}
|
|
29764
|
+
logical.figures.push(copy);
|
|
29765
|
+
}
|
|
29766
|
+
const outline = widenPath(logical, { ...opts, matrix: void 0, height: void 0 });
|
|
29767
|
+
return outline.map((poly) => {
|
|
29768
|
+
const out = [];
|
|
29769
|
+
for (let i = 0; i + 1 < poly.length; i += 2) {
|
|
29770
|
+
out.push(Math.round(a * poly[i] + c * poly[i + 1]), Math.round(b * poly[i] + d * poly[i + 1]));
|
|
29771
|
+
}
|
|
29772
|
+
return out;
|
|
29773
|
+
});
|
|
29774
|
+
}
|
|
29709
29775
|
function widenPath(path, opts) {
|
|
29776
|
+
if (opts.matrix && !(opts.deviceNib && opts.join === "round")) {
|
|
29777
|
+
return widenInLogicalSpace(path, opts, opts.matrix);
|
|
29778
|
+
}
|
|
29710
29779
|
const out = [];
|
|
29711
29780
|
const dashed = !!opts.dashes && opts.dashes.length > 0;
|
|
29712
29781
|
for (const fig of path.figures) {
|
|
@@ -29738,7 +29807,7 @@ function widenPath(path, opts) {
|
|
|
29738
29807
|
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.dashMetric ? opts.width / opts.dashMetric[0] : opts.width;
|
|
29739
29808
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29740
29809
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29741
|
-
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric)) {
|
|
29810
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric, opts.deviceNib ? opts.matrix : void 0)) {
|
|
29742
29811
|
const pts = [piece.pts[0]];
|
|
29743
29812
|
const pdirs = [];
|
|
29744
29813
|
const pdraws = [];
|
|
@@ -30006,8 +30075,24 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30006
30075
|
const capBits = flags & 3840;
|
|
30007
30076
|
const joinBits = flags & 61440;
|
|
30008
30077
|
const ellipse = !rCtx.wholeDevicePixels && state.penWidth * Math.abs(matrix[0]) * 16 >= 1 && state.penWidth * Math.abs(matrix[3]) * 16 >= 1 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6 && Math.abs(Math.abs(matrix[0]) - Math.abs(matrix[3])) > 1e-6;
|
|
30009
|
-
const
|
|
30078
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
30079
|
+
const rotatedOrSheared = Math.abs(matrix[1]) >= 1e-6 || Math.abs(matrix[2]) >= 1e-6;
|
|
30080
|
+
const quarterTurn = Math.abs(matrix[0]) < 1e-9 && Math.abs(matrix[3]) < 1e-9;
|
|
30081
|
+
const general = !rCtx.wholeDevicePixels && rotatedOrSheared && !quarterTurn && Math.abs(det) > 1e-9 && state.penWidth * Math.sqrt(Math.abs(det)) * 16 >= 1;
|
|
30082
|
+
const dashes = state.penExtended ? ellipse || general ? geometricStyle(flags, state.penWidth, state.penUserStyle, 1) : geometricStyle(flags, widthPx, state.penUserStyle, widthPx / (state.penWidth || 1)) : null;
|
|
30010
30083
|
const dashMetric = ellipse && dashes ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : void 0;
|
|
30084
|
+
if (general) {
|
|
30085
|
+
return {
|
|
30086
|
+
width: Math.round(state.penWidth * 16),
|
|
30087
|
+
matrix: [matrix[0], matrix[1], matrix[2], matrix[3]],
|
|
30088
|
+
deviceNib: true,
|
|
30089
|
+
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30090
|
+
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30091
|
+
miterLimit: state.miterLimit ?? 10,
|
|
30092
|
+
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30093
|
+
shortenDashes: (flags & 15) !== 7
|
|
30094
|
+
};
|
|
30095
|
+
}
|
|
30011
30096
|
return {
|
|
30012
30097
|
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : widthPx) * 16),
|
|
30013
30098
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
package/dist/index.js
CHANGED
|
@@ -29239,11 +29239,42 @@ function penPolygon(width, height = width) {
|
|
|
29239
29239
|
penCache.set(key, pen);
|
|
29240
29240
|
return pen;
|
|
29241
29241
|
}
|
|
29242
|
-
|
|
29242
|
+
var matrixPenCache = /* @__PURE__ */ new Map();
|
|
29243
|
+
function penPolygonMatrix(width, m) {
|
|
29244
|
+
const key = `${width},${m.join(",")}`;
|
|
29245
|
+
const cached = matrixPenCache.get(key);
|
|
29246
|
+
if (cached) {
|
|
29247
|
+
return cached;
|
|
29248
|
+
}
|
|
29249
|
+
const r = Math.ceil(width / 2);
|
|
29250
|
+
const mirror2 = m[0] * m[3] - m[1] * m[2] < 0 ? -1 : 1;
|
|
29251
|
+
const bez = ellipseBeziers(-r, -r, r, r);
|
|
29252
|
+
const dev = [];
|
|
29253
|
+
for (let i = 0; i < 14; i += 2) {
|
|
29254
|
+
const x = bez[i];
|
|
29255
|
+
const y = bez[i + 1] * mirror2;
|
|
29256
|
+
dev.push(Math.round(m[0] * x + m[2] * y), Math.round(m[1] * x + m[3] * y));
|
|
29257
|
+
}
|
|
29258
|
+
const f = flattenBezierPath(dev);
|
|
29259
|
+
const half = [];
|
|
29260
|
+
for (let i = 0; i + 1 < f.length; i += 2) {
|
|
29261
|
+
half.push([f[i], f[i + 1]]);
|
|
29262
|
+
}
|
|
29263
|
+
half.pop();
|
|
29264
|
+
const pen = [...half, ...half.map((p) => [0 - p[0] || 0, 0 - p[1] || 0])];
|
|
29265
|
+
matrixPenCache.set(key, pen);
|
|
29266
|
+
return pen;
|
|
29267
|
+
}
|
|
29268
|
+
function drawVertices(pen, dx, dy, width = 1, height = width, matrix) {
|
|
29243
29269
|
const n = pen.length;
|
|
29244
29270
|
const axisVertex = pen.some((q) => q[1] === 0);
|
|
29245
|
-
|
|
29246
|
-
|
|
29271
|
+
let yMagnitude = Math.abs(dy) * (width === height ? 1 : width);
|
|
29272
|
+
let xMagnitude = Math.abs(dx) * (width === height ? 2 : height);
|
|
29273
|
+
if (matrix) {
|
|
29274
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29275
|
+
xMagnitude = Math.abs((matrix[3] * dx - matrix[2] * dy) / det);
|
|
29276
|
+
yMagnitude = Math.abs((-matrix[1] * dx + matrix[0] * dy) / det);
|
|
29277
|
+
}
|
|
29247
29278
|
const steep = yMagnitude > xMagnitude || yMagnitude === xMagnitude && axisVertex;
|
|
29248
29279
|
const s = (steep ? dy < 0 : dx < 0 || dx === 0 && dy < 0) ? -1 : 1;
|
|
29249
29280
|
let best = 0;
|
|
@@ -29263,7 +29294,7 @@ function drawVertices(pen, dx, dy, width = 1, height = width) {
|
|
|
29263
29294
|
function halfPixel(v) {
|
|
29264
29295
|
return Math.sign(v) * 8 * Math.floor((Math.abs(v) + 4) / 8);
|
|
29265
29296
|
}
|
|
29266
|
-
function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
29297
|
+
function perpendicularVectors(width, dx0, dy0, height = width, matrixPen) {
|
|
29267
29298
|
let dx = dx0;
|
|
29268
29299
|
let dy = dy0;
|
|
29269
29300
|
const flip = dx < 0 || dx === 0 && dy < 0;
|
|
@@ -29271,7 +29302,7 @@ function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
|
29271
29302
|
dx = -dx;
|
|
29272
29303
|
dy = -dy;
|
|
29273
29304
|
}
|
|
29274
|
-
const pen = penPolygon(width, height);
|
|
29305
|
+
const pen = matrixPen ?? penPolygon(width, height);
|
|
29275
29306
|
const n = pen.length;
|
|
29276
29307
|
const nx = -dy;
|
|
29277
29308
|
const ny = dx;
|
|
@@ -29310,7 +29341,15 @@ function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
|
29310
29341
|
const vx = rounded[0], vy = rounded[1];
|
|
29311
29342
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29312
29343
|
}
|
|
29313
|
-
function squareExtension(width, dx, dy, scale = 1, height = width) {
|
|
29344
|
+
function squareExtension(width, dx, dy, scale = 1, height = width, matrix) {
|
|
29345
|
+
if (matrix) {
|
|
29346
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29347
|
+
const lx = (matrix[3] * dx - matrix[2] * dy) / det;
|
|
29348
|
+
const ly = (-matrix[1] * dx + matrix[0] * dy) / det;
|
|
29349
|
+
const l = Math.hypot(lx, ly);
|
|
29350
|
+
const q = width / 2 * scale / l;
|
|
29351
|
+
return [Math.floor((matrix[0] * lx + matrix[2] * ly) * q + 0.5), Math.floor((matrix[1] * lx + matrix[3] * ly) * q + 0.5)];
|
|
29352
|
+
}
|
|
29314
29353
|
const len = width === height ? Math.hypot(dx, dy) : Math.hypot(dx, dy * width / height);
|
|
29315
29354
|
const r = width / 2 * scale;
|
|
29316
29355
|
return [Math.floor(dx / len * r + 0.5), Math.floor(dy / len * r + 0.5)];
|
|
@@ -29333,7 +29372,7 @@ var Outliner = class {
|
|
|
29333
29372
|
this.opts = opts;
|
|
29334
29373
|
this.out = out;
|
|
29335
29374
|
this.pts = [];
|
|
29336
|
-
this.pen = penPolygon(opts.width, opts.height);
|
|
29375
|
+
this.pen = opts.matrix && opts.deviceNib ? penPolygonMatrix(opts.width, opts.matrix) : penPolygon(opts.width, opts.height);
|
|
29337
29376
|
this.n = this.pen.length;
|
|
29338
29377
|
this.rr = opts.cap === "round" && opts.join === "round";
|
|
29339
29378
|
this.originalRoundJoinSides = opts.join === "round" && opts.cap !== "flat";
|
|
@@ -29348,10 +29387,11 @@ var Outliner = class {
|
|
|
29348
29387
|
const dx = dir ? dir[0] : b[0] - a[0];
|
|
29349
29388
|
const dy = dir ? dir[1] : b[1] - a[1];
|
|
29350
29389
|
const d = drawDir ?? [dx, dy];
|
|
29351
|
-
const
|
|
29390
|
+
const nibMatrix = this.opts.deviceNib ? this.opts.matrix : void 0;
|
|
29391
|
+
const [L, R] = drawVertices(this.pen, d[0], d[1], this.opts.width, this.opts.height, nibMatrix);
|
|
29352
29392
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29353
|
-
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height);
|
|
29354
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29393
|
+
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height, nibMatrix ? this.pen : void 0);
|
|
29394
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height, nibMatrix), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29355
29395
|
}
|
|
29356
29396
|
push(p, v) {
|
|
29357
29397
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29464,7 +29504,7 @@ var Outliner = class {
|
|
|
29464
29504
|
const sv = this.capSide(s, from);
|
|
29465
29505
|
const ev = this.capSide(s, to);
|
|
29466
29506
|
if (cap === "square") {
|
|
29467
|
-
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale, this.opts.height);
|
|
29507
|
+
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale, this.opts.height, this.opts.deviceNib ? this.opts.matrix : void 0);
|
|
29468
29508
|
const e = start ? [-e0[0], -e0[1]] : e0;
|
|
29469
29509
|
this.push(p, [sv[0] + e[0], sv[1] + e[1]]);
|
|
29470
29510
|
this.push(p, [ev[0] + e[0], ev[1] + e[1]]);
|
|
@@ -29644,7 +29684,7 @@ var Outliner = class {
|
|
|
29644
29684
|
this.flush();
|
|
29645
29685
|
}
|
|
29646
29686
|
};
|
|
29647
|
-
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric) {
|
|
29687
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric, matrix) {
|
|
29648
29688
|
const out = [];
|
|
29649
29689
|
const dashes = [];
|
|
29650
29690
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29664,8 +29704,9 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29664
29704
|
const [x0, y0] = P[i];
|
|
29665
29705
|
const [x1, y1] = P[i + 1];
|
|
29666
29706
|
const dir = [x1 - x0, y1 - y0];
|
|
29667
|
-
const
|
|
29668
|
-
const
|
|
29707
|
+
const det = matrix ? matrix[0] * matrix[3] - matrix[1] * matrix[2] : 1;
|
|
29708
|
+
const real = matrix ? Math.hypot((matrix[3] * dir[0] - matrix[2] * dir[1]) / det, (-matrix[1] * dir[0] + matrix[0] * dir[1]) / det) : metric ? Math.hypot(dir[0] / metric[0], dir[1] / metric[1]) : Math.hypot(dir[0], dir[1]);
|
|
29709
|
+
const len = metric || matrix ? real : wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29669
29710
|
if (len === 0) {
|
|
29670
29711
|
if (on && cur) {
|
|
29671
29712
|
cur.pts.push(P[i + 1]);
|
|
@@ -29709,7 +29750,35 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29709
29750
|
}
|
|
29710
29751
|
return out;
|
|
29711
29752
|
}
|
|
29753
|
+
function widenInLogicalSpace(path, opts, m) {
|
|
29754
|
+
const [a, b, c, d] = m;
|
|
29755
|
+
const det = a * d - b * c;
|
|
29756
|
+
const inverse = (x, y) => [(d * x - c * y) / det, (-b * x + a * y) / det];
|
|
29757
|
+
const logical = new GdiRasterPath();
|
|
29758
|
+
for (const fig of path.figures) {
|
|
29759
|
+
const pts = [];
|
|
29760
|
+
for (let i = 0; i + 1 < fig.pts.length; i += 2) {
|
|
29761
|
+
pts.push(...inverse(fig.pts[i], fig.pts[i + 1]));
|
|
29762
|
+
}
|
|
29763
|
+
const copy = { pts, closed: fig.closed, roundWiden: fig.roundWiden, curveSegs: fig.curveSegs };
|
|
29764
|
+
if (fig.tangents) {
|
|
29765
|
+
copy.tangents = new Map([...fig.tangents].map(([k, v]) => [k, inverse(v[0], v[1])]));
|
|
29766
|
+
}
|
|
29767
|
+
logical.figures.push(copy);
|
|
29768
|
+
}
|
|
29769
|
+
const outline = widenPath(logical, { ...opts, matrix: void 0, height: void 0 });
|
|
29770
|
+
return outline.map((poly) => {
|
|
29771
|
+
const out = [];
|
|
29772
|
+
for (let i = 0; i + 1 < poly.length; i += 2) {
|
|
29773
|
+
out.push(Math.round(a * poly[i] + c * poly[i + 1]), Math.round(b * poly[i] + d * poly[i + 1]));
|
|
29774
|
+
}
|
|
29775
|
+
return out;
|
|
29776
|
+
});
|
|
29777
|
+
}
|
|
29712
29778
|
function widenPath(path, opts) {
|
|
29779
|
+
if (opts.matrix && !(opts.deviceNib && opts.join === "round")) {
|
|
29780
|
+
return widenInLogicalSpace(path, opts, opts.matrix);
|
|
29781
|
+
}
|
|
29713
29782
|
const out = [];
|
|
29714
29783
|
const dashed = !!opts.dashes && opts.dashes.length > 0;
|
|
29715
29784
|
for (const fig of path.figures) {
|
|
@@ -29741,7 +29810,7 @@ function widenPath(path, opts) {
|
|
|
29741
29810
|
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.dashMetric ? opts.width / opts.dashMetric[0] : opts.width;
|
|
29742
29811
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29743
29812
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29744
|
-
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric)) {
|
|
29813
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric, opts.deviceNib ? opts.matrix : void 0)) {
|
|
29745
29814
|
const pts = [piece.pts[0]];
|
|
29746
29815
|
const pdirs = [];
|
|
29747
29816
|
const pdraws = [];
|
|
@@ -30009,8 +30078,24 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30009
30078
|
const capBits = flags & 3840;
|
|
30010
30079
|
const joinBits = flags & 61440;
|
|
30011
30080
|
const ellipse = !rCtx.wholeDevicePixels && state.penWidth * Math.abs(matrix[0]) * 16 >= 1 && state.penWidth * Math.abs(matrix[3]) * 16 >= 1 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6 && Math.abs(Math.abs(matrix[0]) - Math.abs(matrix[3])) > 1e-6;
|
|
30012
|
-
const
|
|
30081
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
30082
|
+
const rotatedOrSheared = Math.abs(matrix[1]) >= 1e-6 || Math.abs(matrix[2]) >= 1e-6;
|
|
30083
|
+
const quarterTurn = Math.abs(matrix[0]) < 1e-9 && Math.abs(matrix[3]) < 1e-9;
|
|
30084
|
+
const general = !rCtx.wholeDevicePixels && rotatedOrSheared && !quarterTurn && Math.abs(det) > 1e-9 && state.penWidth * Math.sqrt(Math.abs(det)) * 16 >= 1;
|
|
30085
|
+
const dashes = state.penExtended ? ellipse || general ? geometricStyle(flags, state.penWidth, state.penUserStyle, 1) : geometricStyle(flags, widthPx, state.penUserStyle, widthPx / (state.penWidth || 1)) : null;
|
|
30013
30086
|
const dashMetric = ellipse && dashes ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : void 0;
|
|
30087
|
+
if (general) {
|
|
30088
|
+
return {
|
|
30089
|
+
width: Math.round(state.penWidth * 16),
|
|
30090
|
+
matrix: [matrix[0], matrix[1], matrix[2], matrix[3]],
|
|
30091
|
+
deviceNib: true,
|
|
30092
|
+
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30093
|
+
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30094
|
+
miterLimit: state.miterLimit ?? 10,
|
|
30095
|
+
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30096
|
+
shortenDashes: (flags & 15) !== 7
|
|
30097
|
+
};
|
|
30098
|
+
}
|
|
30014
30099
|
return {
|
|
30015
30100
|
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : widthPx) * 16),
|
|
30016
30101
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
package/dist/index.mjs
CHANGED
|
@@ -29237,11 +29237,42 @@ function penPolygon(width, height = width) {
|
|
|
29237
29237
|
penCache.set(key, pen);
|
|
29238
29238
|
return pen;
|
|
29239
29239
|
}
|
|
29240
|
-
|
|
29240
|
+
var matrixPenCache = /* @__PURE__ */ new Map();
|
|
29241
|
+
function penPolygonMatrix(width, m) {
|
|
29242
|
+
const key = `${width},${m.join(",")}`;
|
|
29243
|
+
const cached = matrixPenCache.get(key);
|
|
29244
|
+
if (cached) {
|
|
29245
|
+
return cached;
|
|
29246
|
+
}
|
|
29247
|
+
const r = Math.ceil(width / 2);
|
|
29248
|
+
const mirror2 = m[0] * m[3] - m[1] * m[2] < 0 ? -1 : 1;
|
|
29249
|
+
const bez = ellipseBeziers(-r, -r, r, r);
|
|
29250
|
+
const dev = [];
|
|
29251
|
+
for (let i = 0; i < 14; i += 2) {
|
|
29252
|
+
const x = bez[i];
|
|
29253
|
+
const y = bez[i + 1] * mirror2;
|
|
29254
|
+
dev.push(Math.round(m[0] * x + m[2] * y), Math.round(m[1] * x + m[3] * y));
|
|
29255
|
+
}
|
|
29256
|
+
const f = flattenBezierPath(dev);
|
|
29257
|
+
const half = [];
|
|
29258
|
+
for (let i = 0; i + 1 < f.length; i += 2) {
|
|
29259
|
+
half.push([f[i], f[i + 1]]);
|
|
29260
|
+
}
|
|
29261
|
+
half.pop();
|
|
29262
|
+
const pen = [...half, ...half.map((p) => [0 - p[0] || 0, 0 - p[1] || 0])];
|
|
29263
|
+
matrixPenCache.set(key, pen);
|
|
29264
|
+
return pen;
|
|
29265
|
+
}
|
|
29266
|
+
function drawVertices(pen, dx, dy, width = 1, height = width, matrix) {
|
|
29241
29267
|
const n = pen.length;
|
|
29242
29268
|
const axisVertex = pen.some((q) => q[1] === 0);
|
|
29243
|
-
|
|
29244
|
-
|
|
29269
|
+
let yMagnitude = Math.abs(dy) * (width === height ? 1 : width);
|
|
29270
|
+
let xMagnitude = Math.abs(dx) * (width === height ? 2 : height);
|
|
29271
|
+
if (matrix) {
|
|
29272
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29273
|
+
xMagnitude = Math.abs((matrix[3] * dx - matrix[2] * dy) / det);
|
|
29274
|
+
yMagnitude = Math.abs((-matrix[1] * dx + matrix[0] * dy) / det);
|
|
29275
|
+
}
|
|
29245
29276
|
const steep = yMagnitude > xMagnitude || yMagnitude === xMagnitude && axisVertex;
|
|
29246
29277
|
const s = (steep ? dy < 0 : dx < 0 || dx === 0 && dy < 0) ? -1 : 1;
|
|
29247
29278
|
let best = 0;
|
|
@@ -29261,7 +29292,7 @@ function drawVertices(pen, dx, dy, width = 1, height = width) {
|
|
|
29261
29292
|
function halfPixel(v) {
|
|
29262
29293
|
return Math.sign(v) * 8 * Math.floor((Math.abs(v) + 4) / 8);
|
|
29263
29294
|
}
|
|
29264
|
-
function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
29295
|
+
function perpendicularVectors(width, dx0, dy0, height = width, matrixPen) {
|
|
29265
29296
|
let dx = dx0;
|
|
29266
29297
|
let dy = dy0;
|
|
29267
29298
|
const flip = dx < 0 || dx === 0 && dy < 0;
|
|
@@ -29269,7 +29300,7 @@ function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
|
29269
29300
|
dx = -dx;
|
|
29270
29301
|
dy = -dy;
|
|
29271
29302
|
}
|
|
29272
|
-
const pen = penPolygon(width, height);
|
|
29303
|
+
const pen = matrixPen ?? penPolygon(width, height);
|
|
29273
29304
|
const n = pen.length;
|
|
29274
29305
|
const nx = -dy;
|
|
29275
29306
|
const ny = dx;
|
|
@@ -29308,7 +29339,15 @@ function perpendicularVectors(width, dx0, dy0, height = width) {
|
|
|
29308
29339
|
const vx = rounded[0], vy = rounded[1];
|
|
29309
29340
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29310
29341
|
}
|
|
29311
|
-
function squareExtension(width, dx, dy, scale = 1, height = width) {
|
|
29342
|
+
function squareExtension(width, dx, dy, scale = 1, height = width, matrix) {
|
|
29343
|
+
if (matrix) {
|
|
29344
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29345
|
+
const lx = (matrix[3] * dx - matrix[2] * dy) / det;
|
|
29346
|
+
const ly = (-matrix[1] * dx + matrix[0] * dy) / det;
|
|
29347
|
+
const l = Math.hypot(lx, ly);
|
|
29348
|
+
const q = width / 2 * scale / l;
|
|
29349
|
+
return [Math.floor((matrix[0] * lx + matrix[2] * ly) * q + 0.5), Math.floor((matrix[1] * lx + matrix[3] * ly) * q + 0.5)];
|
|
29350
|
+
}
|
|
29312
29351
|
const len = width === height ? Math.hypot(dx, dy) : Math.hypot(dx, dy * width / height);
|
|
29313
29352
|
const r = width / 2 * scale;
|
|
29314
29353
|
return [Math.floor(dx / len * r + 0.5), Math.floor(dy / len * r + 0.5)];
|
|
@@ -29331,7 +29370,7 @@ var Outliner = class {
|
|
|
29331
29370
|
this.opts = opts;
|
|
29332
29371
|
this.out = out;
|
|
29333
29372
|
this.pts = [];
|
|
29334
|
-
this.pen = penPolygon(opts.width, opts.height);
|
|
29373
|
+
this.pen = opts.matrix && opts.deviceNib ? penPolygonMatrix(opts.width, opts.matrix) : penPolygon(opts.width, opts.height);
|
|
29335
29374
|
this.n = this.pen.length;
|
|
29336
29375
|
this.rr = opts.cap === "round" && opts.join === "round";
|
|
29337
29376
|
this.originalRoundJoinSides = opts.join === "round" && opts.cap !== "flat";
|
|
@@ -29346,10 +29385,11 @@ var Outliner = class {
|
|
|
29346
29385
|
const dx = dir ? dir[0] : b[0] - a[0];
|
|
29347
29386
|
const dy = dir ? dir[1] : b[1] - a[1];
|
|
29348
29387
|
const d = drawDir ?? [dx, dy];
|
|
29349
|
-
const
|
|
29388
|
+
const nibMatrix = this.opts.deviceNib ? this.opts.matrix : void 0;
|
|
29389
|
+
const [L, R] = drawVertices(this.pen, d[0], d[1], this.opts.width, this.opts.height, nibMatrix);
|
|
29350
29390
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29351
|
-
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height);
|
|
29352
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29391
|
+
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height, nibMatrix ? this.pen : void 0);
|
|
29392
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height, nibMatrix), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29353
29393
|
}
|
|
29354
29394
|
push(p, v) {
|
|
29355
29395
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29462,7 +29502,7 @@ var Outliner = class {
|
|
|
29462
29502
|
const sv = this.capSide(s, from);
|
|
29463
29503
|
const ev = this.capSide(s, to);
|
|
29464
29504
|
if (cap === "square") {
|
|
29465
|
-
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale, this.opts.height);
|
|
29505
|
+
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale, this.opts.height, this.opts.deviceNib ? this.opts.matrix : void 0);
|
|
29466
29506
|
const e = start ? [-e0[0], -e0[1]] : e0;
|
|
29467
29507
|
this.push(p, [sv[0] + e[0], sv[1] + e[1]]);
|
|
29468
29508
|
this.push(p, [ev[0] + e[0], ev[1] + e[1]]);
|
|
@@ -29642,7 +29682,7 @@ var Outliner = class {
|
|
|
29642
29682
|
this.flush();
|
|
29643
29683
|
}
|
|
29644
29684
|
};
|
|
29645
|
-
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric) {
|
|
29685
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric, matrix) {
|
|
29646
29686
|
const out = [];
|
|
29647
29687
|
const dashes = [];
|
|
29648
29688
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29662,8 +29702,9 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29662
29702
|
const [x0, y0] = P[i];
|
|
29663
29703
|
const [x1, y1] = P[i + 1];
|
|
29664
29704
|
const dir = [x1 - x0, y1 - y0];
|
|
29665
|
-
const
|
|
29666
|
-
const
|
|
29705
|
+
const det = matrix ? matrix[0] * matrix[3] - matrix[1] * matrix[2] : 1;
|
|
29706
|
+
const real = matrix ? Math.hypot((matrix[3] * dir[0] - matrix[2] * dir[1]) / det, (-matrix[1] * dir[0] + matrix[0] * dir[1]) / det) : metric ? Math.hypot(dir[0] / metric[0], dir[1] / metric[1]) : Math.hypot(dir[0], dir[1]);
|
|
29707
|
+
const len = metric || matrix ? real : wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29667
29708
|
if (len === 0) {
|
|
29668
29709
|
if (on && cur) {
|
|
29669
29710
|
cur.pts.push(P[i + 1]);
|
|
@@ -29707,7 +29748,35 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29707
29748
|
}
|
|
29708
29749
|
return out;
|
|
29709
29750
|
}
|
|
29751
|
+
function widenInLogicalSpace(path, opts, m) {
|
|
29752
|
+
const [a, b, c, d] = m;
|
|
29753
|
+
const det = a * d - b * c;
|
|
29754
|
+
const inverse = (x, y) => [(d * x - c * y) / det, (-b * x + a * y) / det];
|
|
29755
|
+
const logical = new GdiRasterPath();
|
|
29756
|
+
for (const fig of path.figures) {
|
|
29757
|
+
const pts = [];
|
|
29758
|
+
for (let i = 0; i + 1 < fig.pts.length; i += 2) {
|
|
29759
|
+
pts.push(...inverse(fig.pts[i], fig.pts[i + 1]));
|
|
29760
|
+
}
|
|
29761
|
+
const copy = { pts, closed: fig.closed, roundWiden: fig.roundWiden, curveSegs: fig.curveSegs };
|
|
29762
|
+
if (fig.tangents) {
|
|
29763
|
+
copy.tangents = new Map([...fig.tangents].map(([k, v]) => [k, inverse(v[0], v[1])]));
|
|
29764
|
+
}
|
|
29765
|
+
logical.figures.push(copy);
|
|
29766
|
+
}
|
|
29767
|
+
const outline = widenPath(logical, { ...opts, matrix: void 0, height: void 0 });
|
|
29768
|
+
return outline.map((poly) => {
|
|
29769
|
+
const out = [];
|
|
29770
|
+
for (let i = 0; i + 1 < poly.length; i += 2) {
|
|
29771
|
+
out.push(Math.round(a * poly[i] + c * poly[i + 1]), Math.round(b * poly[i] + d * poly[i + 1]));
|
|
29772
|
+
}
|
|
29773
|
+
return out;
|
|
29774
|
+
});
|
|
29775
|
+
}
|
|
29710
29776
|
function widenPath(path, opts) {
|
|
29777
|
+
if (opts.matrix && !(opts.deviceNib && opts.join === "round")) {
|
|
29778
|
+
return widenInLogicalSpace(path, opts, opts.matrix);
|
|
29779
|
+
}
|
|
29711
29780
|
const out = [];
|
|
29712
29781
|
const dashed = !!opts.dashes && opts.dashes.length > 0;
|
|
29713
29782
|
for (const fig of path.figures) {
|
|
@@ -29739,7 +29808,7 @@ function widenPath(path, opts) {
|
|
|
29739
29808
|
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.dashMetric ? opts.width / opts.dashMetric[0] : opts.width;
|
|
29740
29809
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29741
29810
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29742
|
-
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric)) {
|
|
29811
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric, opts.deviceNib ? opts.matrix : void 0)) {
|
|
29743
29812
|
const pts = [piece.pts[0]];
|
|
29744
29813
|
const pdirs = [];
|
|
29745
29814
|
const pdraws = [];
|
|
@@ -30007,8 +30076,24 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30007
30076
|
const capBits = flags & 3840;
|
|
30008
30077
|
const joinBits = flags & 61440;
|
|
30009
30078
|
const ellipse = !rCtx.wholeDevicePixels && state.penWidth * Math.abs(matrix[0]) * 16 >= 1 && state.penWidth * Math.abs(matrix[3]) * 16 >= 1 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6 && Math.abs(Math.abs(matrix[0]) - Math.abs(matrix[3])) > 1e-6;
|
|
30010
|
-
const
|
|
30079
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
30080
|
+
const rotatedOrSheared = Math.abs(matrix[1]) >= 1e-6 || Math.abs(matrix[2]) >= 1e-6;
|
|
30081
|
+
const quarterTurn = Math.abs(matrix[0]) < 1e-9 && Math.abs(matrix[3]) < 1e-9;
|
|
30082
|
+
const general = !rCtx.wholeDevicePixels && rotatedOrSheared && !quarterTurn && Math.abs(det) > 1e-9 && state.penWidth * Math.sqrt(Math.abs(det)) * 16 >= 1;
|
|
30083
|
+
const dashes = state.penExtended ? ellipse || general ? geometricStyle(flags, state.penWidth, state.penUserStyle, 1) : geometricStyle(flags, widthPx, state.penUserStyle, widthPx / (state.penWidth || 1)) : null;
|
|
30011
30084
|
const dashMetric = ellipse && dashes ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : void 0;
|
|
30085
|
+
if (general) {
|
|
30086
|
+
return {
|
|
30087
|
+
width: Math.round(state.penWidth * 16),
|
|
30088
|
+
matrix: [matrix[0], matrix[1], matrix[2], matrix[3]],
|
|
30089
|
+
deviceNib: true,
|
|
30090
|
+
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30091
|
+
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30092
|
+
miterLimit: state.miterLimit ?? 10,
|
|
30093
|
+
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30094
|
+
shortenDashes: (flags & 15) !== 7
|
|
30095
|
+
};
|
|
30096
|
+
}
|
|
30012
30097
|
return {
|
|
30013
30098
|
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : widthPx) * 16),
|
|
30014
30099
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|