emf-converter 4.13.0 → 4.15.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 +123 -37
- package/dist/browser.mjs +123 -37
- package/dist/index.js +123 -37
- package/dist/index.mjs +123 -37
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -16513,6 +16513,45 @@ function lerpUniformPathArgb(a, b, t) {
|
|
|
16513
16513
|
};
|
|
16514
16514
|
return (alpha << 24 | ch(16) << 16 | ch(8) << 8 | ch(0)) >>> 0;
|
|
16515
16515
|
}
|
|
16516
|
+
function pathGradientQuantum(boundary, matrix = IDENTITY) {
|
|
16517
|
+
let x0 = Infinity;
|
|
16518
|
+
let y0 = Infinity;
|
|
16519
|
+
let x1 = -Infinity;
|
|
16520
|
+
let y1 = -Infinity;
|
|
16521
|
+
for (const p of boundary) {
|
|
16522
|
+
const x = matrix[0] * p.x + matrix[2] * p.y + matrix[4];
|
|
16523
|
+
const y = matrix[1] * p.x + matrix[3] * p.y + matrix[5];
|
|
16524
|
+
x0 = Math.min(x0, x);
|
|
16525
|
+
y0 = Math.min(y0, y);
|
|
16526
|
+
x1 = Math.max(x1, x);
|
|
16527
|
+
y1 = Math.max(y1, y);
|
|
16528
|
+
}
|
|
16529
|
+
const steps = Math.ceil(2 * Math.hypot(x1 - x0, y1 - y0));
|
|
16530
|
+
return Number.isFinite(steps) && steps > 0 ? steps : 0;
|
|
16531
|
+
}
|
|
16532
|
+
var TIE_EPSILON = 1e-7;
|
|
16533
|
+
function quantisedPathArgb(surround, centre, t, quantum) {
|
|
16534
|
+
const scaled2 = t * quantum;
|
|
16535
|
+
const tie = Math.abs(scaled2 - Math.floor(scaled2) - 0.5) < TIE_EPSILON;
|
|
16536
|
+
const k = tie ? scaled2 : Math.floor(scaled2 + 0.5);
|
|
16537
|
+
const fromBoundary = t < 0.5;
|
|
16538
|
+
const w = (fromBoundary ? k : quantum - k) / quantum;
|
|
16539
|
+
const aS = surround >>> 24 & 255;
|
|
16540
|
+
const aC = centre >>> 24 & 255;
|
|
16541
|
+
const mix2 = (s, c) => fromBoundary ? s + (c - s) * w : c + (s - c) * w;
|
|
16542
|
+
const alpha = Math.floor(mix2(aS, aC) + 0.5);
|
|
16543
|
+
if (alpha <= 0) return 0;
|
|
16544
|
+
const ch = (shift) => {
|
|
16545
|
+
const p = Math.floor(mix2((surround >>> shift & 255) * aS / 255, (centre >>> shift & 255) * aC / 255) + 0.5);
|
|
16546
|
+
return Math.min(255, Math.max(0, Math.round(p * 255 / alpha)));
|
|
16547
|
+
};
|
|
16548
|
+
return (alpha << 24 | ch(16) << 16 | ch(8) << 8 | ch(0)) >>> 0;
|
|
16549
|
+
}
|
|
16550
|
+
function quantisedPosition(pos, quantum) {
|
|
16551
|
+
const scaled2 = pos * quantum;
|
|
16552
|
+
const tie = Math.abs(scaled2 - Math.floor(scaled2) - 0.5) < TIE_EPSILON;
|
|
16553
|
+
return (tie ? scaled2 : Math.floor(scaled2 + 0.5)) / quantum;
|
|
16554
|
+
}
|
|
16516
16555
|
function piecewise2(xs, ys, x) {
|
|
16517
16556
|
const n = Math.min(xs.length, ys.length);
|
|
16518
16557
|
if (n === 0) {
|
|
@@ -16547,11 +16586,13 @@ function stopColorAt(stops, t) {
|
|
|
16547
16586
|
}
|
|
16548
16587
|
return stops[stops.length - 1].argb;
|
|
16549
16588
|
}
|
|
16550
|
-
function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
16589
|
+
function pathGradientColorAt(shape, x, y, focusPoint, quantum) {
|
|
16551
16590
|
const { center, boundary, boundaryArgb } = shape;
|
|
16552
16591
|
const n = boundary.length;
|
|
16553
16592
|
const px = x - center.x;
|
|
16554
16593
|
const py = y - center.y;
|
|
16594
|
+
const ux = (focusPoint?.x ?? x) - center.x;
|
|
16595
|
+
const uy = (focusPoint?.y ?? y) - center.y;
|
|
16555
16596
|
let found = -1;
|
|
16556
16597
|
let bestS = 0;
|
|
16557
16598
|
let bestU = 0;
|
|
@@ -16573,8 +16614,10 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16573
16614
|
continue;
|
|
16574
16615
|
}
|
|
16575
16616
|
found = i;
|
|
16576
|
-
|
|
16577
|
-
|
|
16617
|
+
const alphaU = quantum ? (ux * ey - uy * ex) / det : alpha;
|
|
16618
|
+
const betaU = quantum ? (ax * uy - ay * ux) / det : beta;
|
|
16619
|
+
bestS = Math.max(0, alphaU);
|
|
16620
|
+
bestU = alphaU > 0 ? Math.min(1, Math.max(0, betaU / alphaU)) : 0;
|
|
16578
16621
|
}
|
|
16579
16622
|
let s = found < 0 ? Infinity : bestS;
|
|
16580
16623
|
if (shape.focus) {
|
|
@@ -16649,7 +16692,8 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16649
16692
|
}
|
|
16650
16693
|
}
|
|
16651
16694
|
if (found < 0 || !Number.isFinite(s)) return null;
|
|
16652
|
-
const
|
|
16695
|
+
const exactPos = 1 - s;
|
|
16696
|
+
const pos = quantum && quantum > 0 ? quantisedPosition(exactPos, quantum) : exactPos;
|
|
16653
16697
|
if (shape.preset && shape.preset.positions.length > 0) {
|
|
16654
16698
|
const { positions, argb } = shape.preset;
|
|
16655
16699
|
if (pos <= positions[0]) {
|
|
@@ -16668,6 +16712,9 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16668
16712
|
const surround = lerpArgb(c0, c1, bestU);
|
|
16669
16713
|
const factor = shape.blend ? piecewise2(shape.blend.positions, shape.blend.factors, pos) : pos;
|
|
16670
16714
|
const t = Math.min(1, Math.max(0, factor));
|
|
16715
|
+
if (quantum && quantum > 0 && !shape.blend && boundaryArgb.every((color) => color === boundaryArgb[0])) {
|
|
16716
|
+
return quantisedPathArgb(surround, shape.centerArgb, Math.min(1, Math.max(0, exactPos)), quantum);
|
|
16717
|
+
}
|
|
16671
16718
|
return surround >>> 24 !== shape.centerArgb >>> 24 && boundaryArgb.every((color) => color === boundaryArgb[0]) ? lerpUniformPathArgb(surround, shape.centerArgb, t) : lerpArgb(surround, shape.centerArgb, t);
|
|
16672
16719
|
}
|
|
16673
16720
|
var MAX_TILE = 2048;
|
|
@@ -29941,23 +29988,35 @@ function perpendicularVectors(width, dx0, dy0, height = width, matrixPen) {
|
|
|
29941
29988
|
const vx = rounded[0], vy = rounded[1];
|
|
29942
29989
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29943
29990
|
}
|
|
29944
|
-
function
|
|
29991
|
+
function norm(x, y) {
|
|
29992
|
+
return Math.sqrt(x * x + y * y);
|
|
29993
|
+
}
|
|
29994
|
+
function squareExtension(width, dx, dy, scale = 1, height = width, matrix, wholePixelNorm = false, symmetric = wholePixelNorm, logicalScale = 1) {
|
|
29995
|
+
const slack = 8;
|
|
29945
29996
|
if (matrix) {
|
|
29946
29997
|
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29947
29998
|
const lx = (matrix[3] * dx - matrix[2] * dy) / det;
|
|
29948
29999
|
const ly = (-matrix[1] * dx + matrix[0] * dy) / det;
|
|
29949
|
-
|
|
30000
|
+
let l = Math.hypot(lx, ly);
|
|
30001
|
+
if (wholePixelNorm) {
|
|
30002
|
+
l = norm(Math.floor((lx + slack) / 16) * 16, Math.floor((ly + slack) / 16) * 16);
|
|
30003
|
+
if (l === 0) return [0, 0];
|
|
30004
|
+
}
|
|
29950
30005
|
const q = width / 2 * scale / l;
|
|
29951
30006
|
return [Math.floor((matrix[0] * lx + matrix[2] * ly) * q + 0.5), Math.floor((matrix[1] * lx + matrix[3] * ly) * q + 0.5)];
|
|
29952
30007
|
}
|
|
29953
|
-
|
|
29954
|
-
if (wholePixelNorm && width === height) {
|
|
29955
|
-
const whole = Math.hypot(Math.floor(dx / 16), Math.floor(dy / 16)) * 16;
|
|
29956
|
-
if (whole === 0) return [0, 0];
|
|
29957
|
-
len = whole;
|
|
29958
|
-
}
|
|
30008
|
+
const [ax, ay] = typeof logicalScale === "number" ? [logicalScale, logicalScale] : logicalScale;
|
|
29959
30009
|
const r = width / 2 * scale;
|
|
29960
30010
|
const round = symmetric ? (v) => Math.sign(v) * Math.floor(Math.abs(v) + 0.5) : (v) => Math.floor(v + 0.5);
|
|
30011
|
+
if (wholePixelNorm && (width === height || ax !== ay)) {
|
|
30012
|
+
const lx = dx / ax;
|
|
30013
|
+
const ly = dy / ay;
|
|
30014
|
+
const cut = ax === 1 && ay === 1 ? 0 : slack;
|
|
30015
|
+
const whole = norm(Math.floor((lx + cut) / 16) * 16, Math.floor((ly + cut) / 16) * 16);
|
|
30016
|
+
if (whole === 0) return [0, 0];
|
|
30017
|
+
return [round(lx / whole * r), round(ly * ay / ax / whole * r)];
|
|
30018
|
+
}
|
|
30019
|
+
const len = width === height ? norm(dx, dy) : norm(dx, dy * width / height);
|
|
29961
30020
|
return [round(dx / len * r), round(dy / len * r)];
|
|
29962
30021
|
}
|
|
29963
30022
|
function turnSign(ax, ay, bx, by) {
|
|
@@ -29997,7 +30056,7 @@ var Outliner = class {
|
|
|
29997
30056
|
const [L, R] = drawVertices(this.pen, d[0], d[1], this.opts.width, this.opts.height, nibMatrix);
|
|
29998
30057
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29999
30058
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height, nibMatrix ? this.pen : void 0);
|
|
30000
|
-
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, !!this.opts.wholePixelDashVectors), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, role: drawDir?.[2] ?? 3, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
30059
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.capWidth ?? this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height ?? this.opts.capWidth, nibMatrix, !!(this.opts.wholePixelDashVectors || this.opts.cutToLogicalUnits), void 0, this.opts.logicalScale), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, role: drawDir?.[2] ?? 3, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
30001
30060
|
}
|
|
30002
30061
|
push(p, v) {
|
|
30003
30062
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -30315,8 +30374,8 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
30315
30374
|
const [x1, y1] = P[i + 1];
|
|
30316
30375
|
const dir = [x1 - x0, y1 - y0];
|
|
30317
30376
|
const det = matrix ? matrix[0] * matrix[3] - matrix[1] * matrix[2] : 1;
|
|
30318
|
-
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]) :
|
|
30319
|
-
const len = metric || matrix ? real : wholePixelVectors ?
|
|
30377
|
+
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]) : norm(dir[0], dir[1]);
|
|
30378
|
+
const len = metric || matrix ? real : wholePixelVectors ? norm(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : norm(dir[0], dir[1]);
|
|
30320
30379
|
if (len === 0) {
|
|
30321
30380
|
if (on && cur) {
|
|
30322
30381
|
cur.pts.push(P[i + 1]);
|
|
@@ -30424,26 +30483,16 @@ function widenPath(path, opts) {
|
|
|
30424
30483
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
30425
30484
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
30426
30485
|
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric, opts.deviceNib ? opts.matrix : void 0)) {
|
|
30427
|
-
const pts =
|
|
30428
|
-
const pdirs =
|
|
30429
|
-
const pdraws =
|
|
30430
|
-
const pcurves =
|
|
30431
|
-
for (let i = 1; i < piece.pts.length; i++) {
|
|
30432
|
-
const q = piece.pts[i];
|
|
30433
|
-
const last = pts[pts.length - 1];
|
|
30434
|
-
if (q[0] !== last[0] || q[1] !== last[1]) {
|
|
30435
|
-
pts.push(q);
|
|
30436
|
-
pdirs.push(piece.dirs[i - 1]);
|
|
30437
|
-
pdraws.push(piece.draws[i - 1]);
|
|
30438
|
-
pcurves.push(piece.curves[i - 1]);
|
|
30439
|
-
}
|
|
30440
|
-
}
|
|
30486
|
+
const pts = piece.pts;
|
|
30487
|
+
const pdirs = piece.dirs;
|
|
30488
|
+
const pdraws = piece.draws;
|
|
30489
|
+
const pcurves = piece.curves;
|
|
30441
30490
|
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]], pdirs.length > 0 ? pcurves : [piece.curves[0]], piece.startScale, piece.endScale);
|
|
30442
30491
|
}
|
|
30443
30492
|
} else if (closed && P.length >= 3) {
|
|
30444
30493
|
outliner.closed(P, dirs, curves);
|
|
30445
30494
|
} else if (closed && P.length === 2) {
|
|
30446
|
-
outliner.
|
|
30495
|
+
outliner.closed(P, dirs, curves);
|
|
30447
30496
|
} else {
|
|
30448
30497
|
outliner.open(P, void 0, dirs, curves);
|
|
30449
30498
|
}
|
|
@@ -30706,11 +30755,17 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30706
30755
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30707
30756
|
miterLimit: state.miterLimit ?? 10,
|
|
30708
30757
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30709
|
-
shortenDashes: (flags & 15) !== 7
|
|
30758
|
+
shortenDashes: (flags & 15) !== 7,
|
|
30759
|
+
// Under a rotation the device vector is converted back to logical units for a square cap's extension.
|
|
30760
|
+
cutToLogicalUnits: !dashes
|
|
30710
30761
|
};
|
|
30711
30762
|
}
|
|
30763
|
+
const unrotated = Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6;
|
|
30764
|
+
const scaled2 = !rCtx.wholeDevicePixels && unrotated && (Math.abs(Math.abs(matrix[0]) - 1) > 1e-6 || Math.abs(Math.abs(matrix[3]) - 1) > 1e-6);
|
|
30765
|
+
const uniform = scaled2 && !ellipse && state.penExtended && (flags & 15) !== 6;
|
|
30766
|
+
const nibWidth = uniform ? Math.max(1, Math.floor(widthPx + 0.5)) : widthPx;
|
|
30712
30767
|
return {
|
|
30713
|
-
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) :
|
|
30768
|
+
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : nibWidth) * 16),
|
|
30714
30769
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
|
30715
30770
|
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30716
30771
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
@@ -30720,7 +30775,13 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30720
30775
|
shortenDashes: (flags & 15) !== 7,
|
|
30721
30776
|
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
30722
30777
|
// segments in whole pixels.
|
|
30723
|
-
wholePixelDashVectors: Math.abs(matrix[0] - 1) < 1e-6 && Math.abs(matrix[3] - 1) < 1e-6 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6
|
|
30778
|
+
wholePixelDashVectors: Math.abs(matrix[0] - 1) < 1e-6 && Math.abs(matrix[3] - 1) < 1e-6 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6,
|
|
30779
|
+
...scaled2 && !dashes ? {
|
|
30780
|
+
cutToLogicalUnits: true,
|
|
30781
|
+
logicalScale: ellipse ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : Math.abs(matrix[0]),
|
|
30782
|
+
// The pen rounds to whole pixels, but a square cap extends by half the unrounded width.
|
|
30783
|
+
...uniform ? { capWidth: state.penWidth * Math.abs(matrix[0]) * 16 } : {}
|
|
30784
|
+
} : {}
|
|
30724
30785
|
};
|
|
30725
30786
|
}
|
|
30726
30787
|
function hatchBackgroundMask(hatch) {
|
|
@@ -31211,6 +31272,21 @@ function foldIntoTile(v, origin, size, mirror2, lag) {
|
|
|
31211
31272
|
}
|
|
31212
31273
|
return origin + local;
|
|
31213
31274
|
}
|
|
31275
|
+
function pixelAligned(boundary, m) {
|
|
31276
|
+
let x0 = Infinity;
|
|
31277
|
+
let y0 = Infinity;
|
|
31278
|
+
let x1 = -Infinity;
|
|
31279
|
+
let y1 = -Infinity;
|
|
31280
|
+
for (const p of boundary) {
|
|
31281
|
+
const x = m[0] * p.x + m[2] * p.y + m[4];
|
|
31282
|
+
const y = m[1] * p.x + m[3] * p.y + m[5];
|
|
31283
|
+
x0 = Math.min(x0, x);
|
|
31284
|
+
y0 = Math.min(y0, y);
|
|
31285
|
+
x1 = Math.max(x1, x);
|
|
31286
|
+
y1 = Math.max(y1, y);
|
|
31287
|
+
}
|
|
31288
|
+
return [x0, y0, x1, y1].every((v) => Math.abs(v - Math.round(v)) < 1e-6);
|
|
31289
|
+
}
|
|
31214
31290
|
function pathGradientSampler(shape, wrap, device) {
|
|
31215
31291
|
const box = boundaryBox2(shape.boundary);
|
|
31216
31292
|
const full = mulMatrix(device, shape.transform ?? IDENTITY4);
|
|
@@ -31218,6 +31294,10 @@ function pathGradientSampler(shape, wrap, device) {
|
|
|
31218
31294
|
if (!box || !inv2) {
|
|
31219
31295
|
return null;
|
|
31220
31296
|
}
|
|
31297
|
+
const anisotropicFocus = !!shape.focus && Math.abs(shape.focus.x - shape.focus.y) > 1e-9;
|
|
31298
|
+
const uniformSurround = shape.boundaryArgb.every((color) => color === shape.boundaryArgb[0]);
|
|
31299
|
+
const smooth = !uniformSurround && !shape.preset || anisotropicFocus || wrap !== "clamp" && !pixelAligned(shape.boundary, full);
|
|
31300
|
+
const quantum = smooth ? 0 : pathGradientQuantum(shape.boundary, full);
|
|
31221
31301
|
const pxX = Math.hypot(full[0], full[1]);
|
|
31222
31302
|
const pxY = Math.hypot(full[2], full[3]);
|
|
31223
31303
|
const lagX = pxX > 0 ? 1 / pxX : 0;
|
|
@@ -31237,8 +31317,8 @@ function pathGradientSampler(shape, wrap, device) {
|
|
|
31237
31317
|
by = foldIntoTile(by, box.y, box.h, mirrorY, lagY);
|
|
31238
31318
|
}
|
|
31239
31319
|
if (wrap === "clamp" && by >= box.y + box.h) continue;
|
|
31240
|
-
const focusPoint = bias
|
|
31241
|
-
const c = pathGradientColorAt(shape, bx, by, focusPoint);
|
|
31320
|
+
const focusPoint = bias ? { x: bx - inv2[0] * bias, y: by - inv2[1] * bias } : void 0;
|
|
31321
|
+
const c = pathGradientColorAt(shape, bx, by, focusPoint, quantum);
|
|
31242
31322
|
if (c === null) {
|
|
31243
31323
|
continue;
|
|
31244
31324
|
}
|
|
@@ -32012,8 +32092,14 @@ function handleRoundRect(rCtx, dataOff, recSize) {
|
|
|
32012
32092
|
const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
|
|
32013
32093
|
const cornerFixH = inset ? Math.abs(cornerH * devM[3]) * 16 : fixExtent(rCtx, cornerH, 1);
|
|
32014
32094
|
const cornerOnFrame = (fix, size, framedSize) => inset && size !== 0 ? Math.floor(Math.min(fix, size) * framedSize / size) : fix;
|
|
32015
|
-
|
|
32016
|
-
|
|
32095
|
+
let cw = cornerOnFrame(cornerFixW, Math.abs((r - l) * devM[0]) * 16, Math.abs(framed.exx));
|
|
32096
|
+
let ch = cornerOnFrame(cornerFixH, Math.abs((b - t) * devM[3]) * 16, Math.abs(framed.eyy));
|
|
32097
|
+
if (!inset && rCtx.state.penStyle !== 6 && cornerW !== 0 && cornerH !== 0 && Math.abs(devM[1]) < 1e-9 && Math.abs(devM[2]) < 1e-9 && rCtx.state.penStyle !== 5 && !penIsCosmetic(rCtx) && rCtx.state.worldTransform.every((v, i) => v === [1, 0, 0, 1, 0, 0][i])) {
|
|
32098
|
+
const fullW = (Math.abs(r - l) + 1) * Math.abs(devM[0]) * 16;
|
|
32099
|
+
const fullH = (Math.abs(b - t) + 1) * Math.abs(devM[3]) * 16;
|
|
32100
|
+
cw = Math.floor(Math.min(cornerFixW, fullW) * Math.abs(framed.exx) / fullW);
|
|
32101
|
+
ch = Math.floor(Math.min(cornerFixH, fullH) * Math.abs(framed.eyy) / fullH);
|
|
32102
|
+
}
|
|
32017
32103
|
const drawRoundRect = inset ? (c) => appendRoundRectPath(
|
|
32018
32104
|
c,
|
|
32019
32105
|
Math.min(framed.ax, framed.ax + framed.exx) / 16,
|
package/dist/browser.mjs
CHANGED
|
@@ -16511,6 +16511,45 @@ function lerpUniformPathArgb(a, b, t) {
|
|
|
16511
16511
|
};
|
|
16512
16512
|
return (alpha << 24 | ch(16) << 16 | ch(8) << 8 | ch(0)) >>> 0;
|
|
16513
16513
|
}
|
|
16514
|
+
function pathGradientQuantum(boundary, matrix = IDENTITY) {
|
|
16515
|
+
let x0 = Infinity;
|
|
16516
|
+
let y0 = Infinity;
|
|
16517
|
+
let x1 = -Infinity;
|
|
16518
|
+
let y1 = -Infinity;
|
|
16519
|
+
for (const p of boundary) {
|
|
16520
|
+
const x = matrix[0] * p.x + matrix[2] * p.y + matrix[4];
|
|
16521
|
+
const y = matrix[1] * p.x + matrix[3] * p.y + matrix[5];
|
|
16522
|
+
x0 = Math.min(x0, x);
|
|
16523
|
+
y0 = Math.min(y0, y);
|
|
16524
|
+
x1 = Math.max(x1, x);
|
|
16525
|
+
y1 = Math.max(y1, y);
|
|
16526
|
+
}
|
|
16527
|
+
const steps = Math.ceil(2 * Math.hypot(x1 - x0, y1 - y0));
|
|
16528
|
+
return Number.isFinite(steps) && steps > 0 ? steps : 0;
|
|
16529
|
+
}
|
|
16530
|
+
var TIE_EPSILON = 1e-7;
|
|
16531
|
+
function quantisedPathArgb(surround, centre, t, quantum) {
|
|
16532
|
+
const scaled2 = t * quantum;
|
|
16533
|
+
const tie = Math.abs(scaled2 - Math.floor(scaled2) - 0.5) < TIE_EPSILON;
|
|
16534
|
+
const k = tie ? scaled2 : Math.floor(scaled2 + 0.5);
|
|
16535
|
+
const fromBoundary = t < 0.5;
|
|
16536
|
+
const w = (fromBoundary ? k : quantum - k) / quantum;
|
|
16537
|
+
const aS = surround >>> 24 & 255;
|
|
16538
|
+
const aC = centre >>> 24 & 255;
|
|
16539
|
+
const mix2 = (s, c) => fromBoundary ? s + (c - s) * w : c + (s - c) * w;
|
|
16540
|
+
const alpha = Math.floor(mix2(aS, aC) + 0.5);
|
|
16541
|
+
if (alpha <= 0) return 0;
|
|
16542
|
+
const ch = (shift) => {
|
|
16543
|
+
const p = Math.floor(mix2((surround >>> shift & 255) * aS / 255, (centre >>> shift & 255) * aC / 255) + 0.5);
|
|
16544
|
+
return Math.min(255, Math.max(0, Math.round(p * 255 / alpha)));
|
|
16545
|
+
};
|
|
16546
|
+
return (alpha << 24 | ch(16) << 16 | ch(8) << 8 | ch(0)) >>> 0;
|
|
16547
|
+
}
|
|
16548
|
+
function quantisedPosition(pos, quantum) {
|
|
16549
|
+
const scaled2 = pos * quantum;
|
|
16550
|
+
const tie = Math.abs(scaled2 - Math.floor(scaled2) - 0.5) < TIE_EPSILON;
|
|
16551
|
+
return (tie ? scaled2 : Math.floor(scaled2 + 0.5)) / quantum;
|
|
16552
|
+
}
|
|
16514
16553
|
function piecewise2(xs, ys, x) {
|
|
16515
16554
|
const n = Math.min(xs.length, ys.length);
|
|
16516
16555
|
if (n === 0) {
|
|
@@ -16545,11 +16584,13 @@ function stopColorAt(stops, t) {
|
|
|
16545
16584
|
}
|
|
16546
16585
|
return stops[stops.length - 1].argb;
|
|
16547
16586
|
}
|
|
16548
|
-
function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
16587
|
+
function pathGradientColorAt(shape, x, y, focusPoint, quantum) {
|
|
16549
16588
|
const { center, boundary, boundaryArgb } = shape;
|
|
16550
16589
|
const n = boundary.length;
|
|
16551
16590
|
const px = x - center.x;
|
|
16552
16591
|
const py = y - center.y;
|
|
16592
|
+
const ux = (focusPoint?.x ?? x) - center.x;
|
|
16593
|
+
const uy = (focusPoint?.y ?? y) - center.y;
|
|
16553
16594
|
let found = -1;
|
|
16554
16595
|
let bestS = 0;
|
|
16555
16596
|
let bestU = 0;
|
|
@@ -16571,8 +16612,10 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16571
16612
|
continue;
|
|
16572
16613
|
}
|
|
16573
16614
|
found = i;
|
|
16574
|
-
|
|
16575
|
-
|
|
16615
|
+
const alphaU = quantum ? (ux * ey - uy * ex) / det : alpha;
|
|
16616
|
+
const betaU = quantum ? (ax * uy - ay * ux) / det : beta;
|
|
16617
|
+
bestS = Math.max(0, alphaU);
|
|
16618
|
+
bestU = alphaU > 0 ? Math.min(1, Math.max(0, betaU / alphaU)) : 0;
|
|
16576
16619
|
}
|
|
16577
16620
|
let s = found < 0 ? Infinity : bestS;
|
|
16578
16621
|
if (shape.focus) {
|
|
@@ -16647,7 +16690,8 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16647
16690
|
}
|
|
16648
16691
|
}
|
|
16649
16692
|
if (found < 0 || !Number.isFinite(s)) return null;
|
|
16650
|
-
const
|
|
16693
|
+
const exactPos = 1 - s;
|
|
16694
|
+
const pos = quantum && quantum > 0 ? quantisedPosition(exactPos, quantum) : exactPos;
|
|
16651
16695
|
if (shape.preset && shape.preset.positions.length > 0) {
|
|
16652
16696
|
const { positions, argb } = shape.preset;
|
|
16653
16697
|
if (pos <= positions[0]) {
|
|
@@ -16666,6 +16710,9 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16666
16710
|
const surround = lerpArgb(c0, c1, bestU);
|
|
16667
16711
|
const factor = shape.blend ? piecewise2(shape.blend.positions, shape.blend.factors, pos) : pos;
|
|
16668
16712
|
const t = Math.min(1, Math.max(0, factor));
|
|
16713
|
+
if (quantum && quantum > 0 && !shape.blend && boundaryArgb.every((color) => color === boundaryArgb[0])) {
|
|
16714
|
+
return quantisedPathArgb(surround, shape.centerArgb, Math.min(1, Math.max(0, exactPos)), quantum);
|
|
16715
|
+
}
|
|
16669
16716
|
return surround >>> 24 !== shape.centerArgb >>> 24 && boundaryArgb.every((color) => color === boundaryArgb[0]) ? lerpUniformPathArgb(surround, shape.centerArgb, t) : lerpArgb(surround, shape.centerArgb, t);
|
|
16670
16717
|
}
|
|
16671
16718
|
var MAX_TILE = 2048;
|
|
@@ -29939,23 +29986,35 @@ function perpendicularVectors(width, dx0, dy0, height = width, matrixPen) {
|
|
|
29939
29986
|
const vx = rounded[0], vy = rounded[1];
|
|
29940
29987
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29941
29988
|
}
|
|
29942
|
-
function
|
|
29989
|
+
function norm(x, y) {
|
|
29990
|
+
return Math.sqrt(x * x + y * y);
|
|
29991
|
+
}
|
|
29992
|
+
function squareExtension(width, dx, dy, scale = 1, height = width, matrix, wholePixelNorm = false, symmetric = wholePixelNorm, logicalScale = 1) {
|
|
29993
|
+
const slack = 8;
|
|
29943
29994
|
if (matrix) {
|
|
29944
29995
|
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29945
29996
|
const lx = (matrix[3] * dx - matrix[2] * dy) / det;
|
|
29946
29997
|
const ly = (-matrix[1] * dx + matrix[0] * dy) / det;
|
|
29947
|
-
|
|
29998
|
+
let l = Math.hypot(lx, ly);
|
|
29999
|
+
if (wholePixelNorm) {
|
|
30000
|
+
l = norm(Math.floor((lx + slack) / 16) * 16, Math.floor((ly + slack) / 16) * 16);
|
|
30001
|
+
if (l === 0) return [0, 0];
|
|
30002
|
+
}
|
|
29948
30003
|
const q = width / 2 * scale / l;
|
|
29949
30004
|
return [Math.floor((matrix[0] * lx + matrix[2] * ly) * q + 0.5), Math.floor((matrix[1] * lx + matrix[3] * ly) * q + 0.5)];
|
|
29950
30005
|
}
|
|
29951
|
-
|
|
29952
|
-
if (wholePixelNorm && width === height) {
|
|
29953
|
-
const whole = Math.hypot(Math.floor(dx / 16), Math.floor(dy / 16)) * 16;
|
|
29954
|
-
if (whole === 0) return [0, 0];
|
|
29955
|
-
len = whole;
|
|
29956
|
-
}
|
|
30006
|
+
const [ax, ay] = typeof logicalScale === "number" ? [logicalScale, logicalScale] : logicalScale;
|
|
29957
30007
|
const r = width / 2 * scale;
|
|
29958
30008
|
const round = symmetric ? (v) => Math.sign(v) * Math.floor(Math.abs(v) + 0.5) : (v) => Math.floor(v + 0.5);
|
|
30009
|
+
if (wholePixelNorm && (width === height || ax !== ay)) {
|
|
30010
|
+
const lx = dx / ax;
|
|
30011
|
+
const ly = dy / ay;
|
|
30012
|
+
const cut = ax === 1 && ay === 1 ? 0 : slack;
|
|
30013
|
+
const whole = norm(Math.floor((lx + cut) / 16) * 16, Math.floor((ly + cut) / 16) * 16);
|
|
30014
|
+
if (whole === 0) return [0, 0];
|
|
30015
|
+
return [round(lx / whole * r), round(ly * ay / ax / whole * r)];
|
|
30016
|
+
}
|
|
30017
|
+
const len = width === height ? norm(dx, dy) : norm(dx, dy * width / height);
|
|
29959
30018
|
return [round(dx / len * r), round(dy / len * r)];
|
|
29960
30019
|
}
|
|
29961
30020
|
function turnSign(ax, ay, bx, by) {
|
|
@@ -29995,7 +30054,7 @@ var Outliner = class {
|
|
|
29995
30054
|
const [L, R] = drawVertices(this.pen, d[0], d[1], this.opts.width, this.opts.height, nibMatrix);
|
|
29996
30055
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29997
30056
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height, nibMatrix ? this.pen : void 0);
|
|
29998
|
-
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, !!this.opts.wholePixelDashVectors), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, role: drawDir?.[2] ?? 3, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
30057
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.capWidth ?? this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height ?? this.opts.capWidth, nibMatrix, !!(this.opts.wholePixelDashVectors || this.opts.cutToLogicalUnits), void 0, this.opts.logicalScale), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, role: drawDir?.[2] ?? 3, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29999
30058
|
}
|
|
30000
30059
|
push(p, v) {
|
|
30001
30060
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -30313,8 +30372,8 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
30313
30372
|
const [x1, y1] = P[i + 1];
|
|
30314
30373
|
const dir = [x1 - x0, y1 - y0];
|
|
30315
30374
|
const det = matrix ? matrix[0] * matrix[3] - matrix[1] * matrix[2] : 1;
|
|
30316
|
-
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]) :
|
|
30317
|
-
const len = metric || matrix ? real : wholePixelVectors ?
|
|
30375
|
+
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]) : norm(dir[0], dir[1]);
|
|
30376
|
+
const len = metric || matrix ? real : wholePixelVectors ? norm(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : norm(dir[0], dir[1]);
|
|
30318
30377
|
if (len === 0) {
|
|
30319
30378
|
if (on && cur) {
|
|
30320
30379
|
cur.pts.push(P[i + 1]);
|
|
@@ -30422,26 +30481,16 @@ function widenPath(path, opts) {
|
|
|
30422
30481
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
30423
30482
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
30424
30483
|
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric, opts.deviceNib ? opts.matrix : void 0)) {
|
|
30425
|
-
const pts =
|
|
30426
|
-
const pdirs =
|
|
30427
|
-
const pdraws =
|
|
30428
|
-
const pcurves =
|
|
30429
|
-
for (let i = 1; i < piece.pts.length; i++) {
|
|
30430
|
-
const q = piece.pts[i];
|
|
30431
|
-
const last = pts[pts.length - 1];
|
|
30432
|
-
if (q[0] !== last[0] || q[1] !== last[1]) {
|
|
30433
|
-
pts.push(q);
|
|
30434
|
-
pdirs.push(piece.dirs[i - 1]);
|
|
30435
|
-
pdraws.push(piece.draws[i - 1]);
|
|
30436
|
-
pcurves.push(piece.curves[i - 1]);
|
|
30437
|
-
}
|
|
30438
|
-
}
|
|
30484
|
+
const pts = piece.pts;
|
|
30485
|
+
const pdirs = piece.dirs;
|
|
30486
|
+
const pdraws = piece.draws;
|
|
30487
|
+
const pcurves = piece.curves;
|
|
30439
30488
|
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]], pdirs.length > 0 ? pcurves : [piece.curves[0]], piece.startScale, piece.endScale);
|
|
30440
30489
|
}
|
|
30441
30490
|
} else if (closed && P.length >= 3) {
|
|
30442
30491
|
outliner.closed(P, dirs, curves);
|
|
30443
30492
|
} else if (closed && P.length === 2) {
|
|
30444
|
-
outliner.
|
|
30493
|
+
outliner.closed(P, dirs, curves);
|
|
30445
30494
|
} else {
|
|
30446
30495
|
outliner.open(P, void 0, dirs, curves);
|
|
30447
30496
|
}
|
|
@@ -30704,11 +30753,17 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30704
30753
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30705
30754
|
miterLimit: state.miterLimit ?? 10,
|
|
30706
30755
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30707
|
-
shortenDashes: (flags & 15) !== 7
|
|
30756
|
+
shortenDashes: (flags & 15) !== 7,
|
|
30757
|
+
// Under a rotation the device vector is converted back to logical units for a square cap's extension.
|
|
30758
|
+
cutToLogicalUnits: !dashes
|
|
30708
30759
|
};
|
|
30709
30760
|
}
|
|
30761
|
+
const unrotated = Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6;
|
|
30762
|
+
const scaled2 = !rCtx.wholeDevicePixels && unrotated && (Math.abs(Math.abs(matrix[0]) - 1) > 1e-6 || Math.abs(Math.abs(matrix[3]) - 1) > 1e-6);
|
|
30763
|
+
const uniform = scaled2 && !ellipse && state.penExtended && (flags & 15) !== 6;
|
|
30764
|
+
const nibWidth = uniform ? Math.max(1, Math.floor(widthPx + 0.5)) : widthPx;
|
|
30710
30765
|
return {
|
|
30711
|
-
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) :
|
|
30766
|
+
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : nibWidth) * 16),
|
|
30712
30767
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
|
30713
30768
|
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30714
30769
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
@@ -30718,7 +30773,13 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30718
30773
|
shortenDashes: (flags & 15) !== 7,
|
|
30719
30774
|
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
30720
30775
|
// segments in whole pixels.
|
|
30721
|
-
wholePixelDashVectors: Math.abs(matrix[0] - 1) < 1e-6 && Math.abs(matrix[3] - 1) < 1e-6 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6
|
|
30776
|
+
wholePixelDashVectors: Math.abs(matrix[0] - 1) < 1e-6 && Math.abs(matrix[3] - 1) < 1e-6 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6,
|
|
30777
|
+
...scaled2 && !dashes ? {
|
|
30778
|
+
cutToLogicalUnits: true,
|
|
30779
|
+
logicalScale: ellipse ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : Math.abs(matrix[0]),
|
|
30780
|
+
// The pen rounds to whole pixels, but a square cap extends by half the unrounded width.
|
|
30781
|
+
...uniform ? { capWidth: state.penWidth * Math.abs(matrix[0]) * 16 } : {}
|
|
30782
|
+
} : {}
|
|
30722
30783
|
};
|
|
30723
30784
|
}
|
|
30724
30785
|
function hatchBackgroundMask(hatch) {
|
|
@@ -31209,6 +31270,21 @@ function foldIntoTile(v, origin, size, mirror2, lag) {
|
|
|
31209
31270
|
}
|
|
31210
31271
|
return origin + local;
|
|
31211
31272
|
}
|
|
31273
|
+
function pixelAligned(boundary, m) {
|
|
31274
|
+
let x0 = Infinity;
|
|
31275
|
+
let y0 = Infinity;
|
|
31276
|
+
let x1 = -Infinity;
|
|
31277
|
+
let y1 = -Infinity;
|
|
31278
|
+
for (const p of boundary) {
|
|
31279
|
+
const x = m[0] * p.x + m[2] * p.y + m[4];
|
|
31280
|
+
const y = m[1] * p.x + m[3] * p.y + m[5];
|
|
31281
|
+
x0 = Math.min(x0, x);
|
|
31282
|
+
y0 = Math.min(y0, y);
|
|
31283
|
+
x1 = Math.max(x1, x);
|
|
31284
|
+
y1 = Math.max(y1, y);
|
|
31285
|
+
}
|
|
31286
|
+
return [x0, y0, x1, y1].every((v) => Math.abs(v - Math.round(v)) < 1e-6);
|
|
31287
|
+
}
|
|
31212
31288
|
function pathGradientSampler(shape, wrap, device) {
|
|
31213
31289
|
const box = boundaryBox2(shape.boundary);
|
|
31214
31290
|
const full = mulMatrix(device, shape.transform ?? IDENTITY4);
|
|
@@ -31216,6 +31292,10 @@ function pathGradientSampler(shape, wrap, device) {
|
|
|
31216
31292
|
if (!box || !inv2) {
|
|
31217
31293
|
return null;
|
|
31218
31294
|
}
|
|
31295
|
+
const anisotropicFocus = !!shape.focus && Math.abs(shape.focus.x - shape.focus.y) > 1e-9;
|
|
31296
|
+
const uniformSurround = shape.boundaryArgb.every((color) => color === shape.boundaryArgb[0]);
|
|
31297
|
+
const smooth = !uniformSurround && !shape.preset || anisotropicFocus || wrap !== "clamp" && !pixelAligned(shape.boundary, full);
|
|
31298
|
+
const quantum = smooth ? 0 : pathGradientQuantum(shape.boundary, full);
|
|
31219
31299
|
const pxX = Math.hypot(full[0], full[1]);
|
|
31220
31300
|
const pxY = Math.hypot(full[2], full[3]);
|
|
31221
31301
|
const lagX = pxX > 0 ? 1 / pxX : 0;
|
|
@@ -31235,8 +31315,8 @@ function pathGradientSampler(shape, wrap, device) {
|
|
|
31235
31315
|
by = foldIntoTile(by, box.y, box.h, mirrorY, lagY);
|
|
31236
31316
|
}
|
|
31237
31317
|
if (wrap === "clamp" && by >= box.y + box.h) continue;
|
|
31238
|
-
const focusPoint = bias
|
|
31239
|
-
const c = pathGradientColorAt(shape, bx, by, focusPoint);
|
|
31318
|
+
const focusPoint = bias ? { x: bx - inv2[0] * bias, y: by - inv2[1] * bias } : void 0;
|
|
31319
|
+
const c = pathGradientColorAt(shape, bx, by, focusPoint, quantum);
|
|
31240
31320
|
if (c === null) {
|
|
31241
31321
|
continue;
|
|
31242
31322
|
}
|
|
@@ -32010,8 +32090,14 @@ function handleRoundRect(rCtx, dataOff, recSize) {
|
|
|
32010
32090
|
const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
|
|
32011
32091
|
const cornerFixH = inset ? Math.abs(cornerH * devM[3]) * 16 : fixExtent(rCtx, cornerH, 1);
|
|
32012
32092
|
const cornerOnFrame = (fix, size, framedSize) => inset && size !== 0 ? Math.floor(Math.min(fix, size) * framedSize / size) : fix;
|
|
32013
|
-
|
|
32014
|
-
|
|
32093
|
+
let cw = cornerOnFrame(cornerFixW, Math.abs((r - l) * devM[0]) * 16, Math.abs(framed.exx));
|
|
32094
|
+
let ch = cornerOnFrame(cornerFixH, Math.abs((b - t) * devM[3]) * 16, Math.abs(framed.eyy));
|
|
32095
|
+
if (!inset && rCtx.state.penStyle !== 6 && cornerW !== 0 && cornerH !== 0 && Math.abs(devM[1]) < 1e-9 && Math.abs(devM[2]) < 1e-9 && rCtx.state.penStyle !== 5 && !penIsCosmetic(rCtx) && rCtx.state.worldTransform.every((v, i) => v === [1, 0, 0, 1, 0, 0][i])) {
|
|
32096
|
+
const fullW = (Math.abs(r - l) + 1) * Math.abs(devM[0]) * 16;
|
|
32097
|
+
const fullH = (Math.abs(b - t) + 1) * Math.abs(devM[3]) * 16;
|
|
32098
|
+
cw = Math.floor(Math.min(cornerFixW, fullW) * Math.abs(framed.exx) / fullW);
|
|
32099
|
+
ch = Math.floor(Math.min(cornerFixH, fullH) * Math.abs(framed.eyy) / fullH);
|
|
32100
|
+
}
|
|
32015
32101
|
const drawRoundRect = inset ? (c) => appendRoundRectPath(
|
|
32016
32102
|
c,
|
|
32017
32103
|
Math.min(framed.ax, framed.ax + framed.exx) / 16,
|
package/dist/index.js
CHANGED
|
@@ -16514,6 +16514,45 @@ function lerpUniformPathArgb(a, b, t) {
|
|
|
16514
16514
|
};
|
|
16515
16515
|
return (alpha << 24 | ch(16) << 16 | ch(8) << 8 | ch(0)) >>> 0;
|
|
16516
16516
|
}
|
|
16517
|
+
function pathGradientQuantum(boundary, matrix = IDENTITY) {
|
|
16518
|
+
let x0 = Infinity;
|
|
16519
|
+
let y0 = Infinity;
|
|
16520
|
+
let x1 = -Infinity;
|
|
16521
|
+
let y1 = -Infinity;
|
|
16522
|
+
for (const p of boundary) {
|
|
16523
|
+
const x = matrix[0] * p.x + matrix[2] * p.y + matrix[4];
|
|
16524
|
+
const y = matrix[1] * p.x + matrix[3] * p.y + matrix[5];
|
|
16525
|
+
x0 = Math.min(x0, x);
|
|
16526
|
+
y0 = Math.min(y0, y);
|
|
16527
|
+
x1 = Math.max(x1, x);
|
|
16528
|
+
y1 = Math.max(y1, y);
|
|
16529
|
+
}
|
|
16530
|
+
const steps = Math.ceil(2 * Math.hypot(x1 - x0, y1 - y0));
|
|
16531
|
+
return Number.isFinite(steps) && steps > 0 ? steps : 0;
|
|
16532
|
+
}
|
|
16533
|
+
var TIE_EPSILON = 1e-7;
|
|
16534
|
+
function quantisedPathArgb(surround, centre, t, quantum) {
|
|
16535
|
+
const scaled2 = t * quantum;
|
|
16536
|
+
const tie = Math.abs(scaled2 - Math.floor(scaled2) - 0.5) < TIE_EPSILON;
|
|
16537
|
+
const k = tie ? scaled2 : Math.floor(scaled2 + 0.5);
|
|
16538
|
+
const fromBoundary = t < 0.5;
|
|
16539
|
+
const w = (fromBoundary ? k : quantum - k) / quantum;
|
|
16540
|
+
const aS = surround >>> 24 & 255;
|
|
16541
|
+
const aC = centre >>> 24 & 255;
|
|
16542
|
+
const mix2 = (s, c) => fromBoundary ? s + (c - s) * w : c + (s - c) * w;
|
|
16543
|
+
const alpha = Math.floor(mix2(aS, aC) + 0.5);
|
|
16544
|
+
if (alpha <= 0) return 0;
|
|
16545
|
+
const ch = (shift) => {
|
|
16546
|
+
const p = Math.floor(mix2((surround >>> shift & 255) * aS / 255, (centre >>> shift & 255) * aC / 255) + 0.5);
|
|
16547
|
+
return Math.min(255, Math.max(0, Math.round(p * 255 / alpha)));
|
|
16548
|
+
};
|
|
16549
|
+
return (alpha << 24 | ch(16) << 16 | ch(8) << 8 | ch(0)) >>> 0;
|
|
16550
|
+
}
|
|
16551
|
+
function quantisedPosition(pos, quantum) {
|
|
16552
|
+
const scaled2 = pos * quantum;
|
|
16553
|
+
const tie = Math.abs(scaled2 - Math.floor(scaled2) - 0.5) < TIE_EPSILON;
|
|
16554
|
+
return (tie ? scaled2 : Math.floor(scaled2 + 0.5)) / quantum;
|
|
16555
|
+
}
|
|
16517
16556
|
function piecewise2(xs, ys, x) {
|
|
16518
16557
|
const n = Math.min(xs.length, ys.length);
|
|
16519
16558
|
if (n === 0) {
|
|
@@ -16548,11 +16587,13 @@ function stopColorAt(stops, t) {
|
|
|
16548
16587
|
}
|
|
16549
16588
|
return stops[stops.length - 1].argb;
|
|
16550
16589
|
}
|
|
16551
|
-
function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
16590
|
+
function pathGradientColorAt(shape, x, y, focusPoint, quantum) {
|
|
16552
16591
|
const { center, boundary, boundaryArgb } = shape;
|
|
16553
16592
|
const n = boundary.length;
|
|
16554
16593
|
const px = x - center.x;
|
|
16555
16594
|
const py = y - center.y;
|
|
16595
|
+
const ux = (focusPoint?.x ?? x) - center.x;
|
|
16596
|
+
const uy = (focusPoint?.y ?? y) - center.y;
|
|
16556
16597
|
let found = -1;
|
|
16557
16598
|
let bestS = 0;
|
|
16558
16599
|
let bestU = 0;
|
|
@@ -16574,8 +16615,10 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16574
16615
|
continue;
|
|
16575
16616
|
}
|
|
16576
16617
|
found = i;
|
|
16577
|
-
|
|
16578
|
-
|
|
16618
|
+
const alphaU = quantum ? (ux * ey - uy * ex) / det : alpha;
|
|
16619
|
+
const betaU = quantum ? (ax * uy - ay * ux) / det : beta;
|
|
16620
|
+
bestS = Math.max(0, alphaU);
|
|
16621
|
+
bestU = alphaU > 0 ? Math.min(1, Math.max(0, betaU / alphaU)) : 0;
|
|
16579
16622
|
}
|
|
16580
16623
|
let s = found < 0 ? Infinity : bestS;
|
|
16581
16624
|
if (shape.focus) {
|
|
@@ -16650,7 +16693,8 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16650
16693
|
}
|
|
16651
16694
|
}
|
|
16652
16695
|
if (found < 0 || !Number.isFinite(s)) return null;
|
|
16653
|
-
const
|
|
16696
|
+
const exactPos = 1 - s;
|
|
16697
|
+
const pos = quantum && quantum > 0 ? quantisedPosition(exactPos, quantum) : exactPos;
|
|
16654
16698
|
if (shape.preset && shape.preset.positions.length > 0) {
|
|
16655
16699
|
const { positions, argb } = shape.preset;
|
|
16656
16700
|
if (pos <= positions[0]) {
|
|
@@ -16669,6 +16713,9 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16669
16713
|
const surround = lerpArgb(c0, c1, bestU);
|
|
16670
16714
|
const factor = shape.blend ? piecewise2(shape.blend.positions, shape.blend.factors, pos) : pos;
|
|
16671
16715
|
const t = Math.min(1, Math.max(0, factor));
|
|
16716
|
+
if (quantum && quantum > 0 && !shape.blend && boundaryArgb.every((color) => color === boundaryArgb[0])) {
|
|
16717
|
+
return quantisedPathArgb(surround, shape.centerArgb, Math.min(1, Math.max(0, exactPos)), quantum);
|
|
16718
|
+
}
|
|
16672
16719
|
return surround >>> 24 !== shape.centerArgb >>> 24 && boundaryArgb.every((color) => color === boundaryArgb[0]) ? lerpUniformPathArgb(surround, shape.centerArgb, t) : lerpArgb(surround, shape.centerArgb, t);
|
|
16673
16720
|
}
|
|
16674
16721
|
var MAX_TILE = 2048;
|
|
@@ -29942,23 +29989,35 @@ function perpendicularVectors(width, dx0, dy0, height = width, matrixPen) {
|
|
|
29942
29989
|
const vx = rounded[0], vy = rounded[1];
|
|
29943
29990
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29944
29991
|
}
|
|
29945
|
-
function
|
|
29992
|
+
function norm(x, y) {
|
|
29993
|
+
return Math.sqrt(x * x + y * y);
|
|
29994
|
+
}
|
|
29995
|
+
function squareExtension(width, dx, dy, scale = 1, height = width, matrix, wholePixelNorm = false, symmetric = wholePixelNorm, logicalScale = 1) {
|
|
29996
|
+
const slack = 8;
|
|
29946
29997
|
if (matrix) {
|
|
29947
29998
|
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29948
29999
|
const lx = (matrix[3] * dx - matrix[2] * dy) / det;
|
|
29949
30000
|
const ly = (-matrix[1] * dx + matrix[0] * dy) / det;
|
|
29950
|
-
|
|
30001
|
+
let l = Math.hypot(lx, ly);
|
|
30002
|
+
if (wholePixelNorm) {
|
|
30003
|
+
l = norm(Math.floor((lx + slack) / 16) * 16, Math.floor((ly + slack) / 16) * 16);
|
|
30004
|
+
if (l === 0) return [0, 0];
|
|
30005
|
+
}
|
|
29951
30006
|
const q = width / 2 * scale / l;
|
|
29952
30007
|
return [Math.floor((matrix[0] * lx + matrix[2] * ly) * q + 0.5), Math.floor((matrix[1] * lx + matrix[3] * ly) * q + 0.5)];
|
|
29953
30008
|
}
|
|
29954
|
-
|
|
29955
|
-
if (wholePixelNorm && width === height) {
|
|
29956
|
-
const whole = Math.hypot(Math.floor(dx / 16), Math.floor(dy / 16)) * 16;
|
|
29957
|
-
if (whole === 0) return [0, 0];
|
|
29958
|
-
len = whole;
|
|
29959
|
-
}
|
|
30009
|
+
const [ax, ay] = typeof logicalScale === "number" ? [logicalScale, logicalScale] : logicalScale;
|
|
29960
30010
|
const r = width / 2 * scale;
|
|
29961
30011
|
const round = symmetric ? (v) => Math.sign(v) * Math.floor(Math.abs(v) + 0.5) : (v) => Math.floor(v + 0.5);
|
|
30012
|
+
if (wholePixelNorm && (width === height || ax !== ay)) {
|
|
30013
|
+
const lx = dx / ax;
|
|
30014
|
+
const ly = dy / ay;
|
|
30015
|
+
const cut = ax === 1 && ay === 1 ? 0 : slack;
|
|
30016
|
+
const whole = norm(Math.floor((lx + cut) / 16) * 16, Math.floor((ly + cut) / 16) * 16);
|
|
30017
|
+
if (whole === 0) return [0, 0];
|
|
30018
|
+
return [round(lx / whole * r), round(ly * ay / ax / whole * r)];
|
|
30019
|
+
}
|
|
30020
|
+
const len = width === height ? norm(dx, dy) : norm(dx, dy * width / height);
|
|
29962
30021
|
return [round(dx / len * r), round(dy / len * r)];
|
|
29963
30022
|
}
|
|
29964
30023
|
function turnSign(ax, ay, bx, by) {
|
|
@@ -29998,7 +30057,7 @@ var Outliner = class {
|
|
|
29998
30057
|
const [L, R] = drawVertices(this.pen, d[0], d[1], this.opts.width, this.opts.height, nibMatrix);
|
|
29999
30058
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
30000
30059
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height, nibMatrix ? this.pen : void 0);
|
|
30001
|
-
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, !!this.opts.wholePixelDashVectors), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, role: drawDir?.[2] ?? 3, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
30060
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.capWidth ?? this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height ?? this.opts.capWidth, nibMatrix, !!(this.opts.wholePixelDashVectors || this.opts.cutToLogicalUnits), void 0, this.opts.logicalScale), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, role: drawDir?.[2] ?? 3, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
30002
30061
|
}
|
|
30003
30062
|
push(p, v) {
|
|
30004
30063
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -30316,8 +30375,8 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
30316
30375
|
const [x1, y1] = P[i + 1];
|
|
30317
30376
|
const dir = [x1 - x0, y1 - y0];
|
|
30318
30377
|
const det = matrix ? matrix[0] * matrix[3] - matrix[1] * matrix[2] : 1;
|
|
30319
|
-
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]) :
|
|
30320
|
-
const len = metric || matrix ? real : wholePixelVectors ?
|
|
30378
|
+
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]) : norm(dir[0], dir[1]);
|
|
30379
|
+
const len = metric || matrix ? real : wholePixelVectors ? norm(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : norm(dir[0], dir[1]);
|
|
30321
30380
|
if (len === 0) {
|
|
30322
30381
|
if (on && cur) {
|
|
30323
30382
|
cur.pts.push(P[i + 1]);
|
|
@@ -30425,26 +30484,16 @@ function widenPath(path, opts) {
|
|
|
30425
30484
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
30426
30485
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
30427
30486
|
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric, opts.deviceNib ? opts.matrix : void 0)) {
|
|
30428
|
-
const pts =
|
|
30429
|
-
const pdirs =
|
|
30430
|
-
const pdraws =
|
|
30431
|
-
const pcurves =
|
|
30432
|
-
for (let i = 1; i < piece.pts.length; i++) {
|
|
30433
|
-
const q = piece.pts[i];
|
|
30434
|
-
const last = pts[pts.length - 1];
|
|
30435
|
-
if (q[0] !== last[0] || q[1] !== last[1]) {
|
|
30436
|
-
pts.push(q);
|
|
30437
|
-
pdirs.push(piece.dirs[i - 1]);
|
|
30438
|
-
pdraws.push(piece.draws[i - 1]);
|
|
30439
|
-
pcurves.push(piece.curves[i - 1]);
|
|
30440
|
-
}
|
|
30441
|
-
}
|
|
30487
|
+
const pts = piece.pts;
|
|
30488
|
+
const pdirs = piece.dirs;
|
|
30489
|
+
const pdraws = piece.draws;
|
|
30490
|
+
const pcurves = piece.curves;
|
|
30442
30491
|
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]], pdirs.length > 0 ? pcurves : [piece.curves[0]], piece.startScale, piece.endScale);
|
|
30443
30492
|
}
|
|
30444
30493
|
} else if (closed && P.length >= 3) {
|
|
30445
30494
|
outliner.closed(P, dirs, curves);
|
|
30446
30495
|
} else if (closed && P.length === 2) {
|
|
30447
|
-
outliner.
|
|
30496
|
+
outliner.closed(P, dirs, curves);
|
|
30448
30497
|
} else {
|
|
30449
30498
|
outliner.open(P, void 0, dirs, curves);
|
|
30450
30499
|
}
|
|
@@ -30707,11 +30756,17 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30707
30756
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30708
30757
|
miterLimit: state.miterLimit ?? 10,
|
|
30709
30758
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30710
|
-
shortenDashes: (flags & 15) !== 7
|
|
30759
|
+
shortenDashes: (flags & 15) !== 7,
|
|
30760
|
+
// Under a rotation the device vector is converted back to logical units for a square cap's extension.
|
|
30761
|
+
cutToLogicalUnits: !dashes
|
|
30711
30762
|
};
|
|
30712
30763
|
}
|
|
30764
|
+
const unrotated = Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6;
|
|
30765
|
+
const scaled2 = !rCtx.wholeDevicePixels && unrotated && (Math.abs(Math.abs(matrix[0]) - 1) > 1e-6 || Math.abs(Math.abs(matrix[3]) - 1) > 1e-6);
|
|
30766
|
+
const uniform = scaled2 && !ellipse && state.penExtended && (flags & 15) !== 6;
|
|
30767
|
+
const nibWidth = uniform ? Math.max(1, Math.floor(widthPx + 0.5)) : widthPx;
|
|
30713
30768
|
return {
|
|
30714
|
-
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) :
|
|
30769
|
+
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : nibWidth) * 16),
|
|
30715
30770
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
|
30716
30771
|
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30717
30772
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
@@ -30721,7 +30776,13 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30721
30776
|
shortenDashes: (flags & 15) !== 7,
|
|
30722
30777
|
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
30723
30778
|
// segments in whole pixels.
|
|
30724
|
-
wholePixelDashVectors: Math.abs(matrix[0] - 1) < 1e-6 && Math.abs(matrix[3] - 1) < 1e-6 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6
|
|
30779
|
+
wholePixelDashVectors: Math.abs(matrix[0] - 1) < 1e-6 && Math.abs(matrix[3] - 1) < 1e-6 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6,
|
|
30780
|
+
...scaled2 && !dashes ? {
|
|
30781
|
+
cutToLogicalUnits: true,
|
|
30782
|
+
logicalScale: ellipse ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : Math.abs(matrix[0]),
|
|
30783
|
+
// The pen rounds to whole pixels, but a square cap extends by half the unrounded width.
|
|
30784
|
+
...uniform ? { capWidth: state.penWidth * Math.abs(matrix[0]) * 16 } : {}
|
|
30785
|
+
} : {}
|
|
30725
30786
|
};
|
|
30726
30787
|
}
|
|
30727
30788
|
function hatchBackgroundMask(hatch) {
|
|
@@ -31212,6 +31273,21 @@ function foldIntoTile(v, origin, size, mirror2, lag) {
|
|
|
31212
31273
|
}
|
|
31213
31274
|
return origin + local;
|
|
31214
31275
|
}
|
|
31276
|
+
function pixelAligned(boundary, m) {
|
|
31277
|
+
let x0 = Infinity;
|
|
31278
|
+
let y0 = Infinity;
|
|
31279
|
+
let x1 = -Infinity;
|
|
31280
|
+
let y1 = -Infinity;
|
|
31281
|
+
for (const p of boundary) {
|
|
31282
|
+
const x = m[0] * p.x + m[2] * p.y + m[4];
|
|
31283
|
+
const y = m[1] * p.x + m[3] * p.y + m[5];
|
|
31284
|
+
x0 = Math.min(x0, x);
|
|
31285
|
+
y0 = Math.min(y0, y);
|
|
31286
|
+
x1 = Math.max(x1, x);
|
|
31287
|
+
y1 = Math.max(y1, y);
|
|
31288
|
+
}
|
|
31289
|
+
return [x0, y0, x1, y1].every((v) => Math.abs(v - Math.round(v)) < 1e-6);
|
|
31290
|
+
}
|
|
31215
31291
|
function pathGradientSampler(shape, wrap, device) {
|
|
31216
31292
|
const box = boundaryBox2(shape.boundary);
|
|
31217
31293
|
const full = mulMatrix(device, shape.transform ?? IDENTITY4);
|
|
@@ -31219,6 +31295,10 @@ function pathGradientSampler(shape, wrap, device) {
|
|
|
31219
31295
|
if (!box || !inv2) {
|
|
31220
31296
|
return null;
|
|
31221
31297
|
}
|
|
31298
|
+
const anisotropicFocus = !!shape.focus && Math.abs(shape.focus.x - shape.focus.y) > 1e-9;
|
|
31299
|
+
const uniformSurround = shape.boundaryArgb.every((color) => color === shape.boundaryArgb[0]);
|
|
31300
|
+
const smooth = !uniformSurround && !shape.preset || anisotropicFocus || wrap !== "clamp" && !pixelAligned(shape.boundary, full);
|
|
31301
|
+
const quantum = smooth ? 0 : pathGradientQuantum(shape.boundary, full);
|
|
31222
31302
|
const pxX = Math.hypot(full[0], full[1]);
|
|
31223
31303
|
const pxY = Math.hypot(full[2], full[3]);
|
|
31224
31304
|
const lagX = pxX > 0 ? 1 / pxX : 0;
|
|
@@ -31238,8 +31318,8 @@ function pathGradientSampler(shape, wrap, device) {
|
|
|
31238
31318
|
by = foldIntoTile(by, box.y, box.h, mirrorY, lagY);
|
|
31239
31319
|
}
|
|
31240
31320
|
if (wrap === "clamp" && by >= box.y + box.h) continue;
|
|
31241
|
-
const focusPoint = bias
|
|
31242
|
-
const c = pathGradientColorAt(shape, bx, by, focusPoint);
|
|
31321
|
+
const focusPoint = bias ? { x: bx - inv2[0] * bias, y: by - inv2[1] * bias } : void 0;
|
|
31322
|
+
const c = pathGradientColorAt(shape, bx, by, focusPoint, quantum);
|
|
31243
31323
|
if (c === null) {
|
|
31244
31324
|
continue;
|
|
31245
31325
|
}
|
|
@@ -32013,8 +32093,14 @@ function handleRoundRect(rCtx, dataOff, recSize) {
|
|
|
32013
32093
|
const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
|
|
32014
32094
|
const cornerFixH = inset ? Math.abs(cornerH * devM[3]) * 16 : fixExtent(rCtx, cornerH, 1);
|
|
32015
32095
|
const cornerOnFrame = (fix, size, framedSize) => inset && size !== 0 ? Math.floor(Math.min(fix, size) * framedSize / size) : fix;
|
|
32016
|
-
|
|
32017
|
-
|
|
32096
|
+
let cw = cornerOnFrame(cornerFixW, Math.abs((r - l) * devM[0]) * 16, Math.abs(framed.exx));
|
|
32097
|
+
let ch = cornerOnFrame(cornerFixH, Math.abs((b - t) * devM[3]) * 16, Math.abs(framed.eyy));
|
|
32098
|
+
if (!inset && rCtx.state.penStyle !== 6 && cornerW !== 0 && cornerH !== 0 && Math.abs(devM[1]) < 1e-9 && Math.abs(devM[2]) < 1e-9 && rCtx.state.penStyle !== 5 && !penIsCosmetic(rCtx) && rCtx.state.worldTransform.every((v, i) => v === [1, 0, 0, 1, 0, 0][i])) {
|
|
32099
|
+
const fullW = (Math.abs(r - l) + 1) * Math.abs(devM[0]) * 16;
|
|
32100
|
+
const fullH = (Math.abs(b - t) + 1) * Math.abs(devM[3]) * 16;
|
|
32101
|
+
cw = Math.floor(Math.min(cornerFixW, fullW) * Math.abs(framed.exx) / fullW);
|
|
32102
|
+
ch = Math.floor(Math.min(cornerFixH, fullH) * Math.abs(framed.eyy) / fullH);
|
|
32103
|
+
}
|
|
32018
32104
|
const drawRoundRect = inset ? (c) => appendRoundRectPath(
|
|
32019
32105
|
c,
|
|
32020
32106
|
Math.min(framed.ax, framed.ax + framed.exx) / 16,
|
package/dist/index.mjs
CHANGED
|
@@ -16512,6 +16512,45 @@ function lerpUniformPathArgb(a, b, t) {
|
|
|
16512
16512
|
};
|
|
16513
16513
|
return (alpha << 24 | ch(16) << 16 | ch(8) << 8 | ch(0)) >>> 0;
|
|
16514
16514
|
}
|
|
16515
|
+
function pathGradientQuantum(boundary, matrix = IDENTITY) {
|
|
16516
|
+
let x0 = Infinity;
|
|
16517
|
+
let y0 = Infinity;
|
|
16518
|
+
let x1 = -Infinity;
|
|
16519
|
+
let y1 = -Infinity;
|
|
16520
|
+
for (const p of boundary) {
|
|
16521
|
+
const x = matrix[0] * p.x + matrix[2] * p.y + matrix[4];
|
|
16522
|
+
const y = matrix[1] * p.x + matrix[3] * p.y + matrix[5];
|
|
16523
|
+
x0 = Math.min(x0, x);
|
|
16524
|
+
y0 = Math.min(y0, y);
|
|
16525
|
+
x1 = Math.max(x1, x);
|
|
16526
|
+
y1 = Math.max(y1, y);
|
|
16527
|
+
}
|
|
16528
|
+
const steps = Math.ceil(2 * Math.hypot(x1 - x0, y1 - y0));
|
|
16529
|
+
return Number.isFinite(steps) && steps > 0 ? steps : 0;
|
|
16530
|
+
}
|
|
16531
|
+
var TIE_EPSILON = 1e-7;
|
|
16532
|
+
function quantisedPathArgb(surround, centre, t, quantum) {
|
|
16533
|
+
const scaled2 = t * quantum;
|
|
16534
|
+
const tie = Math.abs(scaled2 - Math.floor(scaled2) - 0.5) < TIE_EPSILON;
|
|
16535
|
+
const k = tie ? scaled2 : Math.floor(scaled2 + 0.5);
|
|
16536
|
+
const fromBoundary = t < 0.5;
|
|
16537
|
+
const w = (fromBoundary ? k : quantum - k) / quantum;
|
|
16538
|
+
const aS = surround >>> 24 & 255;
|
|
16539
|
+
const aC = centre >>> 24 & 255;
|
|
16540
|
+
const mix2 = (s, c) => fromBoundary ? s + (c - s) * w : c + (s - c) * w;
|
|
16541
|
+
const alpha = Math.floor(mix2(aS, aC) + 0.5);
|
|
16542
|
+
if (alpha <= 0) return 0;
|
|
16543
|
+
const ch = (shift) => {
|
|
16544
|
+
const p = Math.floor(mix2((surround >>> shift & 255) * aS / 255, (centre >>> shift & 255) * aC / 255) + 0.5);
|
|
16545
|
+
return Math.min(255, Math.max(0, Math.round(p * 255 / alpha)));
|
|
16546
|
+
};
|
|
16547
|
+
return (alpha << 24 | ch(16) << 16 | ch(8) << 8 | ch(0)) >>> 0;
|
|
16548
|
+
}
|
|
16549
|
+
function quantisedPosition(pos, quantum) {
|
|
16550
|
+
const scaled2 = pos * quantum;
|
|
16551
|
+
const tie = Math.abs(scaled2 - Math.floor(scaled2) - 0.5) < TIE_EPSILON;
|
|
16552
|
+
return (tie ? scaled2 : Math.floor(scaled2 + 0.5)) / quantum;
|
|
16553
|
+
}
|
|
16515
16554
|
function piecewise2(xs, ys, x) {
|
|
16516
16555
|
const n = Math.min(xs.length, ys.length);
|
|
16517
16556
|
if (n === 0) {
|
|
@@ -16546,11 +16585,13 @@ function stopColorAt(stops, t) {
|
|
|
16546
16585
|
}
|
|
16547
16586
|
return stops[stops.length - 1].argb;
|
|
16548
16587
|
}
|
|
16549
|
-
function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
16588
|
+
function pathGradientColorAt(shape, x, y, focusPoint, quantum) {
|
|
16550
16589
|
const { center, boundary, boundaryArgb } = shape;
|
|
16551
16590
|
const n = boundary.length;
|
|
16552
16591
|
const px = x - center.x;
|
|
16553
16592
|
const py = y - center.y;
|
|
16593
|
+
const ux = (focusPoint?.x ?? x) - center.x;
|
|
16594
|
+
const uy = (focusPoint?.y ?? y) - center.y;
|
|
16554
16595
|
let found = -1;
|
|
16555
16596
|
let bestS = 0;
|
|
16556
16597
|
let bestU = 0;
|
|
@@ -16572,8 +16613,10 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16572
16613
|
continue;
|
|
16573
16614
|
}
|
|
16574
16615
|
found = i;
|
|
16575
|
-
|
|
16576
|
-
|
|
16616
|
+
const alphaU = quantum ? (ux * ey - uy * ex) / det : alpha;
|
|
16617
|
+
const betaU = quantum ? (ax * uy - ay * ux) / det : beta;
|
|
16618
|
+
bestS = Math.max(0, alphaU);
|
|
16619
|
+
bestU = alphaU > 0 ? Math.min(1, Math.max(0, betaU / alphaU)) : 0;
|
|
16577
16620
|
}
|
|
16578
16621
|
let s = found < 0 ? Infinity : bestS;
|
|
16579
16622
|
if (shape.focus) {
|
|
@@ -16648,7 +16691,8 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16648
16691
|
}
|
|
16649
16692
|
}
|
|
16650
16693
|
if (found < 0 || !Number.isFinite(s)) return null;
|
|
16651
|
-
const
|
|
16694
|
+
const exactPos = 1 - s;
|
|
16695
|
+
const pos = quantum && quantum > 0 ? quantisedPosition(exactPos, quantum) : exactPos;
|
|
16652
16696
|
if (shape.preset && shape.preset.positions.length > 0) {
|
|
16653
16697
|
const { positions, argb } = shape.preset;
|
|
16654
16698
|
if (pos <= positions[0]) {
|
|
@@ -16667,6 +16711,9 @@ function pathGradientColorAt(shape, x, y, focusPoint) {
|
|
|
16667
16711
|
const surround = lerpArgb(c0, c1, bestU);
|
|
16668
16712
|
const factor = shape.blend ? piecewise2(shape.blend.positions, shape.blend.factors, pos) : pos;
|
|
16669
16713
|
const t = Math.min(1, Math.max(0, factor));
|
|
16714
|
+
if (quantum && quantum > 0 && !shape.blend && boundaryArgb.every((color) => color === boundaryArgb[0])) {
|
|
16715
|
+
return quantisedPathArgb(surround, shape.centerArgb, Math.min(1, Math.max(0, exactPos)), quantum);
|
|
16716
|
+
}
|
|
16670
16717
|
return surround >>> 24 !== shape.centerArgb >>> 24 && boundaryArgb.every((color) => color === boundaryArgb[0]) ? lerpUniformPathArgb(surround, shape.centerArgb, t) : lerpArgb(surround, shape.centerArgb, t);
|
|
16671
16718
|
}
|
|
16672
16719
|
var MAX_TILE = 2048;
|
|
@@ -29940,23 +29987,35 @@ function perpendicularVectors(width, dx0, dy0, height = width, matrixPen) {
|
|
|
29940
29987
|
const vx = rounded[0], vy = rounded[1];
|
|
29941
29988
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29942
29989
|
}
|
|
29943
|
-
function
|
|
29990
|
+
function norm(x, y) {
|
|
29991
|
+
return Math.sqrt(x * x + y * y);
|
|
29992
|
+
}
|
|
29993
|
+
function squareExtension(width, dx, dy, scale = 1, height = width, matrix, wholePixelNorm = false, symmetric = wholePixelNorm, logicalScale = 1) {
|
|
29994
|
+
const slack = 8;
|
|
29944
29995
|
if (matrix) {
|
|
29945
29996
|
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
29946
29997
|
const lx = (matrix[3] * dx - matrix[2] * dy) / det;
|
|
29947
29998
|
const ly = (-matrix[1] * dx + matrix[0] * dy) / det;
|
|
29948
|
-
|
|
29999
|
+
let l = Math.hypot(lx, ly);
|
|
30000
|
+
if (wholePixelNorm) {
|
|
30001
|
+
l = norm(Math.floor((lx + slack) / 16) * 16, Math.floor((ly + slack) / 16) * 16);
|
|
30002
|
+
if (l === 0) return [0, 0];
|
|
30003
|
+
}
|
|
29949
30004
|
const q = width / 2 * scale / l;
|
|
29950
30005
|
return [Math.floor((matrix[0] * lx + matrix[2] * ly) * q + 0.5), Math.floor((matrix[1] * lx + matrix[3] * ly) * q + 0.5)];
|
|
29951
30006
|
}
|
|
29952
|
-
|
|
29953
|
-
if (wholePixelNorm && width === height) {
|
|
29954
|
-
const whole = Math.hypot(Math.floor(dx / 16), Math.floor(dy / 16)) * 16;
|
|
29955
|
-
if (whole === 0) return [0, 0];
|
|
29956
|
-
len = whole;
|
|
29957
|
-
}
|
|
30007
|
+
const [ax, ay] = typeof logicalScale === "number" ? [logicalScale, logicalScale] : logicalScale;
|
|
29958
30008
|
const r = width / 2 * scale;
|
|
29959
30009
|
const round = symmetric ? (v) => Math.sign(v) * Math.floor(Math.abs(v) + 0.5) : (v) => Math.floor(v + 0.5);
|
|
30010
|
+
if (wholePixelNorm && (width === height || ax !== ay)) {
|
|
30011
|
+
const lx = dx / ax;
|
|
30012
|
+
const ly = dy / ay;
|
|
30013
|
+
const cut = ax === 1 && ay === 1 ? 0 : slack;
|
|
30014
|
+
const whole = norm(Math.floor((lx + cut) / 16) * 16, Math.floor((ly + cut) / 16) * 16);
|
|
30015
|
+
if (whole === 0) return [0, 0];
|
|
30016
|
+
return [round(lx / whole * r), round(ly * ay / ax / whole * r)];
|
|
30017
|
+
}
|
|
30018
|
+
const len = width === height ? norm(dx, dy) : norm(dx, dy * width / height);
|
|
29960
30019
|
return [round(dx / len * r), round(dy / len * r)];
|
|
29961
30020
|
}
|
|
29962
30021
|
function turnSign(ax, ay, bx, by) {
|
|
@@ -29996,7 +30055,7 @@ var Outliner = class {
|
|
|
29996
30055
|
const [L, R] = drawVertices(this.pen, d[0], d[1], this.opts.width, this.opts.height, nibMatrix);
|
|
29997
30056
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29998
30057
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height, nibMatrix ? this.pen : void 0);
|
|
29999
|
-
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, !!this.opts.wholePixelDashVectors), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, role: drawDir?.[2] ?? 3, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
30058
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.capWidth ?? this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height ?? this.opts.capWidth, nibMatrix, !!(this.opts.wholePixelDashVectors || this.opts.cutToLogicalUnits), void 0, this.opts.logicalScale), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, role: drawDir?.[2] ?? 3, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
30000
30059
|
}
|
|
30001
30060
|
push(p, v) {
|
|
30002
30061
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -30314,8 +30373,8 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
30314
30373
|
const [x1, y1] = P[i + 1];
|
|
30315
30374
|
const dir = [x1 - x0, y1 - y0];
|
|
30316
30375
|
const det = matrix ? matrix[0] * matrix[3] - matrix[1] * matrix[2] : 1;
|
|
30317
|
-
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]) :
|
|
30318
|
-
const len = metric || matrix ? real : wholePixelVectors ?
|
|
30376
|
+
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]) : norm(dir[0], dir[1]);
|
|
30377
|
+
const len = metric || matrix ? real : wholePixelVectors ? norm(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : norm(dir[0], dir[1]);
|
|
30319
30378
|
if (len === 0) {
|
|
30320
30379
|
if (on && cur) {
|
|
30321
30380
|
cur.pts.push(P[i + 1]);
|
|
@@ -30423,26 +30482,16 @@ function widenPath(path, opts) {
|
|
|
30423
30482
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
30424
30483
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
30425
30484
|
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric, opts.deviceNib ? opts.matrix : void 0)) {
|
|
30426
|
-
const pts =
|
|
30427
|
-
const pdirs =
|
|
30428
|
-
const pdraws =
|
|
30429
|
-
const pcurves =
|
|
30430
|
-
for (let i = 1; i < piece.pts.length; i++) {
|
|
30431
|
-
const q = piece.pts[i];
|
|
30432
|
-
const last = pts[pts.length - 1];
|
|
30433
|
-
if (q[0] !== last[0] || q[1] !== last[1]) {
|
|
30434
|
-
pts.push(q);
|
|
30435
|
-
pdirs.push(piece.dirs[i - 1]);
|
|
30436
|
-
pdraws.push(piece.draws[i - 1]);
|
|
30437
|
-
pcurves.push(piece.curves[i - 1]);
|
|
30438
|
-
}
|
|
30439
|
-
}
|
|
30485
|
+
const pts = piece.pts;
|
|
30486
|
+
const pdirs = piece.dirs;
|
|
30487
|
+
const pdraws = piece.draws;
|
|
30488
|
+
const pcurves = piece.curves;
|
|
30440
30489
|
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]], pdirs.length > 0 ? pcurves : [piece.curves[0]], piece.startScale, piece.endScale);
|
|
30441
30490
|
}
|
|
30442
30491
|
} else if (closed && P.length >= 3) {
|
|
30443
30492
|
outliner.closed(P, dirs, curves);
|
|
30444
30493
|
} else if (closed && P.length === 2) {
|
|
30445
|
-
outliner.
|
|
30494
|
+
outliner.closed(P, dirs, curves);
|
|
30446
30495
|
} else {
|
|
30447
30496
|
outliner.open(P, void 0, dirs, curves);
|
|
30448
30497
|
}
|
|
@@ -30705,11 +30754,17 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30705
30754
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30706
30755
|
miterLimit: state.miterLimit ?? 10,
|
|
30707
30756
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30708
|
-
shortenDashes: (flags & 15) !== 7
|
|
30757
|
+
shortenDashes: (flags & 15) !== 7,
|
|
30758
|
+
// Under a rotation the device vector is converted back to logical units for a square cap's extension.
|
|
30759
|
+
cutToLogicalUnits: !dashes
|
|
30709
30760
|
};
|
|
30710
30761
|
}
|
|
30762
|
+
const unrotated = Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6;
|
|
30763
|
+
const scaled2 = !rCtx.wholeDevicePixels && unrotated && (Math.abs(Math.abs(matrix[0]) - 1) > 1e-6 || Math.abs(Math.abs(matrix[3]) - 1) > 1e-6);
|
|
30764
|
+
const uniform = scaled2 && !ellipse && state.penExtended && (flags & 15) !== 6;
|
|
30765
|
+
const nibWidth = uniform ? Math.max(1, Math.floor(widthPx + 0.5)) : widthPx;
|
|
30711
30766
|
return {
|
|
30712
|
-
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) :
|
|
30767
|
+
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : nibWidth) * 16),
|
|
30713
30768
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
|
30714
30769
|
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30715
30770
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
@@ -30719,7 +30774,13 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30719
30774
|
shortenDashes: (flags & 15) !== 7,
|
|
30720
30775
|
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
30721
30776
|
// segments in whole pixels.
|
|
30722
|
-
wholePixelDashVectors: Math.abs(matrix[0] - 1) < 1e-6 && Math.abs(matrix[3] - 1) < 1e-6 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6
|
|
30777
|
+
wholePixelDashVectors: Math.abs(matrix[0] - 1) < 1e-6 && Math.abs(matrix[3] - 1) < 1e-6 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6,
|
|
30778
|
+
...scaled2 && !dashes ? {
|
|
30779
|
+
cutToLogicalUnits: true,
|
|
30780
|
+
logicalScale: ellipse ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : Math.abs(matrix[0]),
|
|
30781
|
+
// The pen rounds to whole pixels, but a square cap extends by half the unrounded width.
|
|
30782
|
+
...uniform ? { capWidth: state.penWidth * Math.abs(matrix[0]) * 16 } : {}
|
|
30783
|
+
} : {}
|
|
30723
30784
|
};
|
|
30724
30785
|
}
|
|
30725
30786
|
function hatchBackgroundMask(hatch) {
|
|
@@ -31210,6 +31271,21 @@ function foldIntoTile(v, origin, size, mirror2, lag) {
|
|
|
31210
31271
|
}
|
|
31211
31272
|
return origin + local;
|
|
31212
31273
|
}
|
|
31274
|
+
function pixelAligned(boundary, m) {
|
|
31275
|
+
let x0 = Infinity;
|
|
31276
|
+
let y0 = Infinity;
|
|
31277
|
+
let x1 = -Infinity;
|
|
31278
|
+
let y1 = -Infinity;
|
|
31279
|
+
for (const p of boundary) {
|
|
31280
|
+
const x = m[0] * p.x + m[2] * p.y + m[4];
|
|
31281
|
+
const y = m[1] * p.x + m[3] * p.y + m[5];
|
|
31282
|
+
x0 = Math.min(x0, x);
|
|
31283
|
+
y0 = Math.min(y0, y);
|
|
31284
|
+
x1 = Math.max(x1, x);
|
|
31285
|
+
y1 = Math.max(y1, y);
|
|
31286
|
+
}
|
|
31287
|
+
return [x0, y0, x1, y1].every((v) => Math.abs(v - Math.round(v)) < 1e-6);
|
|
31288
|
+
}
|
|
31213
31289
|
function pathGradientSampler(shape, wrap, device) {
|
|
31214
31290
|
const box = boundaryBox2(shape.boundary);
|
|
31215
31291
|
const full = mulMatrix(device, shape.transform ?? IDENTITY4);
|
|
@@ -31217,6 +31293,10 @@ function pathGradientSampler(shape, wrap, device) {
|
|
|
31217
31293
|
if (!box || !inv2) {
|
|
31218
31294
|
return null;
|
|
31219
31295
|
}
|
|
31296
|
+
const anisotropicFocus = !!shape.focus && Math.abs(shape.focus.x - shape.focus.y) > 1e-9;
|
|
31297
|
+
const uniformSurround = shape.boundaryArgb.every((color) => color === shape.boundaryArgb[0]);
|
|
31298
|
+
const smooth = !uniformSurround && !shape.preset || anisotropicFocus || wrap !== "clamp" && !pixelAligned(shape.boundary, full);
|
|
31299
|
+
const quantum = smooth ? 0 : pathGradientQuantum(shape.boundary, full);
|
|
31220
31300
|
const pxX = Math.hypot(full[0], full[1]);
|
|
31221
31301
|
const pxY = Math.hypot(full[2], full[3]);
|
|
31222
31302
|
const lagX = pxX > 0 ? 1 / pxX : 0;
|
|
@@ -31236,8 +31316,8 @@ function pathGradientSampler(shape, wrap, device) {
|
|
|
31236
31316
|
by = foldIntoTile(by, box.y, box.h, mirrorY, lagY);
|
|
31237
31317
|
}
|
|
31238
31318
|
if (wrap === "clamp" && by >= box.y + box.h) continue;
|
|
31239
|
-
const focusPoint = bias
|
|
31240
|
-
const c = pathGradientColorAt(shape, bx, by, focusPoint);
|
|
31319
|
+
const focusPoint = bias ? { x: bx - inv2[0] * bias, y: by - inv2[1] * bias } : void 0;
|
|
31320
|
+
const c = pathGradientColorAt(shape, bx, by, focusPoint, quantum);
|
|
31241
31321
|
if (c === null) {
|
|
31242
31322
|
continue;
|
|
31243
31323
|
}
|
|
@@ -32011,8 +32091,14 @@ function handleRoundRect(rCtx, dataOff, recSize) {
|
|
|
32011
32091
|
const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
|
|
32012
32092
|
const cornerFixH = inset ? Math.abs(cornerH * devM[3]) * 16 : fixExtent(rCtx, cornerH, 1);
|
|
32013
32093
|
const cornerOnFrame = (fix, size, framedSize) => inset && size !== 0 ? Math.floor(Math.min(fix, size) * framedSize / size) : fix;
|
|
32014
|
-
|
|
32015
|
-
|
|
32094
|
+
let cw = cornerOnFrame(cornerFixW, Math.abs((r - l) * devM[0]) * 16, Math.abs(framed.exx));
|
|
32095
|
+
let ch = cornerOnFrame(cornerFixH, Math.abs((b - t) * devM[3]) * 16, Math.abs(framed.eyy));
|
|
32096
|
+
if (!inset && rCtx.state.penStyle !== 6 && cornerW !== 0 && cornerH !== 0 && Math.abs(devM[1]) < 1e-9 && Math.abs(devM[2]) < 1e-9 && rCtx.state.penStyle !== 5 && !penIsCosmetic(rCtx) && rCtx.state.worldTransform.every((v, i) => v === [1, 0, 0, 1, 0, 0][i])) {
|
|
32097
|
+
const fullW = (Math.abs(r - l) + 1) * Math.abs(devM[0]) * 16;
|
|
32098
|
+
const fullH = (Math.abs(b - t) + 1) * Math.abs(devM[3]) * 16;
|
|
32099
|
+
cw = Math.floor(Math.min(cornerFixW, fullW) * Math.abs(framed.exx) / fullW);
|
|
32100
|
+
ch = Math.floor(Math.min(cornerFixH, fullH) * Math.abs(framed.eyy) / fullH);
|
|
32101
|
+
}
|
|
32016
32102
|
const drawRoundRect = inset ? (c) => appendRoundRectPath(
|
|
32017
32103
|
c,
|
|
32018
32104
|
Math.min(framed.ax, framed.ax + framed.exx) / 16,
|