emf-converter 4.8.1 → 4.8.2
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/README.md +1 -1
- package/dist/browser.js +40 -17
- package/dist/browser.mjs +40 -17
- package/dist/index.js +40 -17
- package/dist/index.mjs +40 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -217,7 +217,7 @@ Everything is measured against output painted by Windows itself; `src/gdi-parity
|
|
|
217
217
|
- **Colour adjustment and image effects**: all eleven EMF+ image effects are supported. Complete native tables cover every legal ColorCurve intensity. Deferred draws retain their effects. JPEG, GIF and TIFF have bundled decoders for environments without Canvas. HSL, tint, red-eye, blur, sharpen and GDI colour adjustment retain measured differences; see [the detailed limitations](docs/limitations.md) and the native fixture bounds.
|
|
218
218
|
- **Pen transforms**: EMF+ pen transforms (uniform, nonuniform and skewed) match GDI+ exactly on the 17 pen-transform fixtures, including dashes, which GDI+ lays out along the path in world space at the untransformed pen width. Native fixtures verify dashes under both uniform and non-uniform scales. GDI+ rejects singular pen transforms; the converter ignores such malformed transform data. Square, round, diamond and arrow anchor caps use their native shapes; the new centered-cap fixtures match every pixel with and without antialiasing.
|
|
219
219
|
- **Text**: ANSI, multi-string and small-text records now render; the Windows text fixtures retain a few glyph-edge differences and a `PolyTextOut` C1 control-glyph difference (under 0.1% of pixels; bounds in `src/emf-text-records.fixture.test.ts`). ANSI decoding uses the host's `TextDecoder` for common Windows code pages; Johab and OEM CP437 use bundled Windows mappings. Vertical `ETO_PDY` advances work with and without the `fonts` engine. Without `fonts`, SVG text measurements use deterministic estimates, so precise justification requires supplying the matching fonts.
|
|
220
|
-
- **Wide pens and paths**: flat-capped GDI pens 7 px and wider can differ by a few pixels at round joins, and dashed wide
|
|
220
|
+
- **Wide pens and paths**: flat-capped GDI pens 7 px and wider can differ by a few pixels at round joins, and dashed wide curves follow `WidenPath` (exact for round and flat caps at one logical unit per pixel; square caps differ slightly at path ends); at most 0.2% of pixels on the fixtures. `EMR_WIDENPATH` does not reproduce the extra inner join triangles GDI's own `WidenPath` emits (visible only when the widened outline is itself stroked). EMF+ 1-pixel antialiased lines can differ by one antialiasing sample at their ends, some closed widened outlines by one sample along an edge, and Inset or compound pens on closed figures are approximate.
|
|
221
221
|
- **GM_COMPATIBLE recordings**: EMF files do not record the graphics mode, and Windows plays RoundRect, Arc, Chord, Pie and null-pen Ellipse records back differently from how a GM_COMPATIBLE application drew them on screen; the converter follows Windows' playback.
|
|
222
222
|
- **Small EMF+ residuals**: rotated `HighQualityBicubic` `DrawImage` edge pixels (0.14%), one-level differences at exact half-level `Blend` knots, and a few pixels of a metafile nested in `DrawImage` under a scale.
|
|
223
223
|
- **WMF**: `PS_INSIDEFRAME` boxes can come out a pixel short at non-integer scales, right-to-left (`LAYOUT_RTL`) layouts differ by single pixels on mirrored diagonals, and metric map modes assume a 96 dpi reference device (Windows derives them from the physical display, so its own output varies per machine).
|
package/dist/browser.js
CHANGED
|
@@ -29228,9 +29228,9 @@ function perpendicularVectors(width, dx0, dy0) {
|
|
|
29228
29228
|
const vx = rounded[0], vy = rounded[1];
|
|
29229
29229
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29230
29230
|
}
|
|
29231
|
-
function squareExtension(width, dx, dy) {
|
|
29231
|
+
function squareExtension(width, dx, dy, scale = 1) {
|
|
29232
29232
|
const len = Math.hypot(dx, dy);
|
|
29233
|
-
const r = width / 2;
|
|
29233
|
+
const r = width / 2 * scale;
|
|
29234
29234
|
return [Math.floor(dx / len * r + 0.5), Math.floor(dy / len * r + 0.5)];
|
|
29235
29235
|
}
|
|
29236
29236
|
function turnSign(ax, ay, bx, by) {
|
|
@@ -29269,7 +29269,7 @@ var Outliner = class {
|
|
|
29269
29269
|
const [L, R] = drawVertices(this.pen, d[0], d[1]);
|
|
29270
29270
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29271
29271
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
|
|
29272
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29272
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29273
29273
|
}
|
|
29274
29274
|
push(p, v) {
|
|
29275
29275
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29364,7 +29364,7 @@ var Outliner = class {
|
|
|
29364
29364
|
return side === "R" ? s.v : [-s.v[0], -s.v[1]];
|
|
29365
29365
|
}
|
|
29366
29366
|
/** A cap at `p` from the `from` side of `s` round to the other side (`start`: around the back). */
|
|
29367
|
-
cap(p, s, start) {
|
|
29367
|
+
cap(p, s, start, scale = 1) {
|
|
29368
29368
|
const from = start ? "L" : "R";
|
|
29369
29369
|
const to = start ? "R" : "L";
|
|
29370
29370
|
const { cap } = this.opts;
|
|
@@ -29382,7 +29382,8 @@ var Outliner = class {
|
|
|
29382
29382
|
const sv = this.capSide(s, from);
|
|
29383
29383
|
const ev = this.capSide(s, to);
|
|
29384
29384
|
if (cap === "square") {
|
|
29385
|
-
const
|
|
29385
|
+
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale);
|
|
29386
|
+
const e = start ? [-e0[0], -e0[1]] : e0;
|
|
29386
29387
|
this.push(p, [sv[0] + e[0], sv[1] + e[1]]);
|
|
29387
29388
|
this.push(p, [ev[0] + e[0], ev[1] + e[1]]);
|
|
29388
29389
|
} else {
|
|
@@ -29478,7 +29479,7 @@ var Outliner = class {
|
|
|
29478
29479
|
* lets a single point stand for a zero-length dash along `dirs[0]`;
|
|
29479
29480
|
* `draws` (curve end tangents) picks draw vertices only.
|
|
29480
29481
|
*/
|
|
29481
|
-
open(P, dirs, draws, curves) {
|
|
29482
|
+
open(P, dirs, draws, curves, startScale = 1, endScale = 1) {
|
|
29482
29483
|
if (P.length < 2 && !dirs?.[0]) {
|
|
29483
29484
|
this.dot(P[0]);
|
|
29484
29485
|
return;
|
|
@@ -29489,12 +29490,12 @@ var Outliner = class {
|
|
|
29489
29490
|
}
|
|
29490
29491
|
if (segs2.length === 0) {
|
|
29491
29492
|
const s = this.seg(P[0], P[0], dirs?.[0], draws?.[0], curves?.[0]);
|
|
29492
|
-
this.cap(P[0], s, true);
|
|
29493
|
-
this.cap(P[0], s, false);
|
|
29493
|
+
this.cap(P[0], s, true, startScale);
|
|
29494
|
+
this.cap(P[0], s, false, endScale);
|
|
29494
29495
|
this.flush();
|
|
29495
29496
|
return;
|
|
29496
29497
|
}
|
|
29497
|
-
this.cap(P[0], segs2[0], true);
|
|
29498
|
+
this.cap(P[0], segs2[0], true, startScale);
|
|
29498
29499
|
for (let i = 0; i + 1 < segs2.length; i++) {
|
|
29499
29500
|
const s = segs2[i];
|
|
29500
29501
|
const t = segs2[i + 1];
|
|
@@ -29505,7 +29506,7 @@ var Outliner = class {
|
|
|
29505
29506
|
this.join(P[i + 1], s, t, "R", tr < 0);
|
|
29506
29507
|
}
|
|
29507
29508
|
}
|
|
29508
|
-
this.cap(P[P.length - 1], segs2[segs2.length - 1], false);
|
|
29509
|
+
this.cap(P[P.length - 1], segs2[segs2.length - 1], false, endScale);
|
|
29509
29510
|
for (let i = segs2.length - 1; i > 0; i--) {
|
|
29510
29511
|
const s = segs2[i];
|
|
29511
29512
|
const t = segs2[i - 1];
|
|
@@ -29561,7 +29562,7 @@ var Outliner = class {
|
|
|
29561
29562
|
this.flush();
|
|
29562
29563
|
}
|
|
29563
29564
|
};
|
|
29564
|
-
function dashPieces(P, tangents, pattern, shorten) {
|
|
29565
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors) {
|
|
29565
29566
|
const out = [];
|
|
29566
29567
|
const dashes = [];
|
|
29567
29568
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29576,12 +29577,22 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29576
29577
|
let idx = 0;
|
|
29577
29578
|
let left = dashes[0];
|
|
29578
29579
|
let on = true;
|
|
29579
|
-
let cur = { pts: [P[0]], dirs: [], draws: [] };
|
|
29580
|
+
let cur = { pts: [P[0]], dirs: [], draws: [], curves: [], startScale: 1, endScale: 1 };
|
|
29580
29581
|
for (let i = 0; i + 1 < P.length; i++) {
|
|
29581
29582
|
const [x0, y0] = P[i];
|
|
29582
29583
|
const [x1, y1] = P[i + 1];
|
|
29583
29584
|
const dir = [x1 - x0, y1 - y0];
|
|
29584
|
-
const
|
|
29585
|
+
const real = Math.hypot(dir[0], dir[1]);
|
|
29586
|
+
const len = wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29587
|
+
if (len === 0) {
|
|
29588
|
+
if (on && cur) {
|
|
29589
|
+
cur.pts.push(P[i + 1]);
|
|
29590
|
+
cur.dirs.push(dir);
|
|
29591
|
+
cur.draws.push(tangents[i]);
|
|
29592
|
+
cur.curves.push(curveFlags[i]);
|
|
29593
|
+
}
|
|
29594
|
+
continue;
|
|
29595
|
+
}
|
|
29585
29596
|
let t = 0;
|
|
29586
29597
|
while (len - t > left || left === 0 && on) {
|
|
29587
29598
|
t += left;
|
|
@@ -29590,10 +29601,12 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29590
29601
|
cur.pts.push(q);
|
|
29591
29602
|
cur.dirs.push(dir);
|
|
29592
29603
|
cur.draws.push(tangents[i]);
|
|
29604
|
+
cur.curves.push(curveFlags[i]);
|
|
29605
|
+
cur.endScale = cur.pts[0] === P[0] && q[0] === P[0][0] && q[1] === P[0][1] ? 1 : real / len;
|
|
29593
29606
|
out.push(cur);
|
|
29594
29607
|
cur = null;
|
|
29595
29608
|
} else {
|
|
29596
|
-
cur = { pts: [q], dirs: [], draws: [] };
|
|
29609
|
+
cur = { pts: [q], dirs: [], draws: [], curves: [], startScale: real / len, endScale: 1 };
|
|
29597
29610
|
}
|
|
29598
29611
|
on = !on;
|
|
29599
29612
|
idx = (idx + 1) % dashes.length;
|
|
@@ -29604,9 +29617,12 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29604
29617
|
cur.pts.push(P[i + 1]);
|
|
29605
29618
|
cur.dirs.push(dir);
|
|
29606
29619
|
cur.draws.push(tangents[i]);
|
|
29620
|
+
cur.curves.push(curveFlags[i]);
|
|
29621
|
+
cur.endScale = real / len;
|
|
29607
29622
|
}
|
|
29608
29623
|
}
|
|
29609
29624
|
if (on && cur && cur.dirs.length > 0) {
|
|
29625
|
+
cur.endScale = 1;
|
|
29610
29626
|
out.push(cur);
|
|
29611
29627
|
}
|
|
29612
29628
|
return out;
|
|
@@ -29641,10 +29657,13 @@ function widenPath(path, opts) {
|
|
|
29641
29657
|
if (dashed) {
|
|
29642
29658
|
const run = closed ? [...P, P[0]] : P;
|
|
29643
29659
|
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.width;
|
|
29644
|
-
|
|
29660
|
+
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29661
|
+
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29662
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors)) {
|
|
29645
29663
|
const pts = [piece.pts[0]];
|
|
29646
29664
|
const pdirs = [];
|
|
29647
29665
|
const pdraws = [];
|
|
29666
|
+
const pcurves = [];
|
|
29648
29667
|
for (let i = 1; i < piece.pts.length; i++) {
|
|
29649
29668
|
const q = piece.pts[i];
|
|
29650
29669
|
const last = pts[pts.length - 1];
|
|
@@ -29652,9 +29671,10 @@ function widenPath(path, opts) {
|
|
|
29652
29671
|
pts.push(q);
|
|
29653
29672
|
pdirs.push(piece.dirs[i - 1]);
|
|
29654
29673
|
pdraws.push(piece.draws[i - 1]);
|
|
29674
|
+
pcurves.push(piece.curves[i - 1]);
|
|
29655
29675
|
}
|
|
29656
29676
|
}
|
|
29657
|
-
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]],
|
|
29677
|
+
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);
|
|
29658
29678
|
}
|
|
29659
29679
|
} else if (closed && P.length >= 3) {
|
|
29660
29680
|
outliner.closed(P, dirs, curves);
|
|
@@ -29862,7 +29882,10 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
29862
29882
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
29863
29883
|
miterLimit: state.miterLimit ?? 10,
|
|
29864
29884
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
29865
|
-
shortenDashes: (flags & 15) !== 7
|
|
29885
|
+
shortenDashes: (flags & 15) !== 7,
|
|
29886
|
+
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
29887
|
+
// segments in whole pixels.
|
|
29888
|
+
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
|
|
29866
29889
|
};
|
|
29867
29890
|
}
|
|
29868
29891
|
function hatchBackgroundMask(hatch) {
|
package/dist/browser.mjs
CHANGED
|
@@ -29226,9 +29226,9 @@ function perpendicularVectors(width, dx0, dy0) {
|
|
|
29226
29226
|
const vx = rounded[0], vy = rounded[1];
|
|
29227
29227
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29228
29228
|
}
|
|
29229
|
-
function squareExtension(width, dx, dy) {
|
|
29229
|
+
function squareExtension(width, dx, dy, scale = 1) {
|
|
29230
29230
|
const len = Math.hypot(dx, dy);
|
|
29231
|
-
const r = width / 2;
|
|
29231
|
+
const r = width / 2 * scale;
|
|
29232
29232
|
return [Math.floor(dx / len * r + 0.5), Math.floor(dy / len * r + 0.5)];
|
|
29233
29233
|
}
|
|
29234
29234
|
function turnSign(ax, ay, bx, by) {
|
|
@@ -29267,7 +29267,7 @@ var Outliner = class {
|
|
|
29267
29267
|
const [L, R] = drawVertices(this.pen, d[0], d[1]);
|
|
29268
29268
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29269
29269
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
|
|
29270
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29270
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29271
29271
|
}
|
|
29272
29272
|
push(p, v) {
|
|
29273
29273
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29362,7 +29362,7 @@ var Outliner = class {
|
|
|
29362
29362
|
return side === "R" ? s.v : [-s.v[0], -s.v[1]];
|
|
29363
29363
|
}
|
|
29364
29364
|
/** A cap at `p` from the `from` side of `s` round to the other side (`start`: around the back). */
|
|
29365
|
-
cap(p, s, start) {
|
|
29365
|
+
cap(p, s, start, scale = 1) {
|
|
29366
29366
|
const from = start ? "L" : "R";
|
|
29367
29367
|
const to = start ? "R" : "L";
|
|
29368
29368
|
const { cap } = this.opts;
|
|
@@ -29380,7 +29380,8 @@ var Outliner = class {
|
|
|
29380
29380
|
const sv = this.capSide(s, from);
|
|
29381
29381
|
const ev = this.capSide(s, to);
|
|
29382
29382
|
if (cap === "square") {
|
|
29383
|
-
const
|
|
29383
|
+
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale);
|
|
29384
|
+
const e = start ? [-e0[0], -e0[1]] : e0;
|
|
29384
29385
|
this.push(p, [sv[0] + e[0], sv[1] + e[1]]);
|
|
29385
29386
|
this.push(p, [ev[0] + e[0], ev[1] + e[1]]);
|
|
29386
29387
|
} else {
|
|
@@ -29476,7 +29477,7 @@ var Outliner = class {
|
|
|
29476
29477
|
* lets a single point stand for a zero-length dash along `dirs[0]`;
|
|
29477
29478
|
* `draws` (curve end tangents) picks draw vertices only.
|
|
29478
29479
|
*/
|
|
29479
|
-
open(P, dirs, draws, curves) {
|
|
29480
|
+
open(P, dirs, draws, curves, startScale = 1, endScale = 1) {
|
|
29480
29481
|
if (P.length < 2 && !dirs?.[0]) {
|
|
29481
29482
|
this.dot(P[0]);
|
|
29482
29483
|
return;
|
|
@@ -29487,12 +29488,12 @@ var Outliner = class {
|
|
|
29487
29488
|
}
|
|
29488
29489
|
if (segs2.length === 0) {
|
|
29489
29490
|
const s = this.seg(P[0], P[0], dirs?.[0], draws?.[0], curves?.[0]);
|
|
29490
|
-
this.cap(P[0], s, true);
|
|
29491
|
-
this.cap(P[0], s, false);
|
|
29491
|
+
this.cap(P[0], s, true, startScale);
|
|
29492
|
+
this.cap(P[0], s, false, endScale);
|
|
29492
29493
|
this.flush();
|
|
29493
29494
|
return;
|
|
29494
29495
|
}
|
|
29495
|
-
this.cap(P[0], segs2[0], true);
|
|
29496
|
+
this.cap(P[0], segs2[0], true, startScale);
|
|
29496
29497
|
for (let i = 0; i + 1 < segs2.length; i++) {
|
|
29497
29498
|
const s = segs2[i];
|
|
29498
29499
|
const t = segs2[i + 1];
|
|
@@ -29503,7 +29504,7 @@ var Outliner = class {
|
|
|
29503
29504
|
this.join(P[i + 1], s, t, "R", tr < 0);
|
|
29504
29505
|
}
|
|
29505
29506
|
}
|
|
29506
|
-
this.cap(P[P.length - 1], segs2[segs2.length - 1], false);
|
|
29507
|
+
this.cap(P[P.length - 1], segs2[segs2.length - 1], false, endScale);
|
|
29507
29508
|
for (let i = segs2.length - 1; i > 0; i--) {
|
|
29508
29509
|
const s = segs2[i];
|
|
29509
29510
|
const t = segs2[i - 1];
|
|
@@ -29559,7 +29560,7 @@ var Outliner = class {
|
|
|
29559
29560
|
this.flush();
|
|
29560
29561
|
}
|
|
29561
29562
|
};
|
|
29562
|
-
function dashPieces(P, tangents, pattern, shorten) {
|
|
29563
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors) {
|
|
29563
29564
|
const out = [];
|
|
29564
29565
|
const dashes = [];
|
|
29565
29566
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29574,12 +29575,22 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29574
29575
|
let idx = 0;
|
|
29575
29576
|
let left = dashes[0];
|
|
29576
29577
|
let on = true;
|
|
29577
|
-
let cur = { pts: [P[0]], dirs: [], draws: [] };
|
|
29578
|
+
let cur = { pts: [P[0]], dirs: [], draws: [], curves: [], startScale: 1, endScale: 1 };
|
|
29578
29579
|
for (let i = 0; i + 1 < P.length; i++) {
|
|
29579
29580
|
const [x0, y0] = P[i];
|
|
29580
29581
|
const [x1, y1] = P[i + 1];
|
|
29581
29582
|
const dir = [x1 - x0, y1 - y0];
|
|
29582
|
-
const
|
|
29583
|
+
const real = Math.hypot(dir[0], dir[1]);
|
|
29584
|
+
const len = wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29585
|
+
if (len === 0) {
|
|
29586
|
+
if (on && cur) {
|
|
29587
|
+
cur.pts.push(P[i + 1]);
|
|
29588
|
+
cur.dirs.push(dir);
|
|
29589
|
+
cur.draws.push(tangents[i]);
|
|
29590
|
+
cur.curves.push(curveFlags[i]);
|
|
29591
|
+
}
|
|
29592
|
+
continue;
|
|
29593
|
+
}
|
|
29583
29594
|
let t = 0;
|
|
29584
29595
|
while (len - t > left || left === 0 && on) {
|
|
29585
29596
|
t += left;
|
|
@@ -29588,10 +29599,12 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29588
29599
|
cur.pts.push(q);
|
|
29589
29600
|
cur.dirs.push(dir);
|
|
29590
29601
|
cur.draws.push(tangents[i]);
|
|
29602
|
+
cur.curves.push(curveFlags[i]);
|
|
29603
|
+
cur.endScale = cur.pts[0] === P[0] && q[0] === P[0][0] && q[1] === P[0][1] ? 1 : real / len;
|
|
29591
29604
|
out.push(cur);
|
|
29592
29605
|
cur = null;
|
|
29593
29606
|
} else {
|
|
29594
|
-
cur = { pts: [q], dirs: [], draws: [] };
|
|
29607
|
+
cur = { pts: [q], dirs: [], draws: [], curves: [], startScale: real / len, endScale: 1 };
|
|
29595
29608
|
}
|
|
29596
29609
|
on = !on;
|
|
29597
29610
|
idx = (idx + 1) % dashes.length;
|
|
@@ -29602,9 +29615,12 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29602
29615
|
cur.pts.push(P[i + 1]);
|
|
29603
29616
|
cur.dirs.push(dir);
|
|
29604
29617
|
cur.draws.push(tangents[i]);
|
|
29618
|
+
cur.curves.push(curveFlags[i]);
|
|
29619
|
+
cur.endScale = real / len;
|
|
29605
29620
|
}
|
|
29606
29621
|
}
|
|
29607
29622
|
if (on && cur && cur.dirs.length > 0) {
|
|
29623
|
+
cur.endScale = 1;
|
|
29608
29624
|
out.push(cur);
|
|
29609
29625
|
}
|
|
29610
29626
|
return out;
|
|
@@ -29639,10 +29655,13 @@ function widenPath(path, opts) {
|
|
|
29639
29655
|
if (dashed) {
|
|
29640
29656
|
const run = closed ? [...P, P[0]] : P;
|
|
29641
29657
|
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.width;
|
|
29642
|
-
|
|
29658
|
+
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29659
|
+
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29660
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors)) {
|
|
29643
29661
|
const pts = [piece.pts[0]];
|
|
29644
29662
|
const pdirs = [];
|
|
29645
29663
|
const pdraws = [];
|
|
29664
|
+
const pcurves = [];
|
|
29646
29665
|
for (let i = 1; i < piece.pts.length; i++) {
|
|
29647
29666
|
const q = piece.pts[i];
|
|
29648
29667
|
const last = pts[pts.length - 1];
|
|
@@ -29650,9 +29669,10 @@ function widenPath(path, opts) {
|
|
|
29650
29669
|
pts.push(q);
|
|
29651
29670
|
pdirs.push(piece.dirs[i - 1]);
|
|
29652
29671
|
pdraws.push(piece.draws[i - 1]);
|
|
29672
|
+
pcurves.push(piece.curves[i - 1]);
|
|
29653
29673
|
}
|
|
29654
29674
|
}
|
|
29655
|
-
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]],
|
|
29675
|
+
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);
|
|
29656
29676
|
}
|
|
29657
29677
|
} else if (closed && P.length >= 3) {
|
|
29658
29678
|
outliner.closed(P, dirs, curves);
|
|
@@ -29860,7 +29880,10 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
29860
29880
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
29861
29881
|
miterLimit: state.miterLimit ?? 10,
|
|
29862
29882
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
29863
|
-
shortenDashes: (flags & 15) !== 7
|
|
29883
|
+
shortenDashes: (flags & 15) !== 7,
|
|
29884
|
+
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
29885
|
+
// segments in whole pixels.
|
|
29886
|
+
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
|
|
29864
29887
|
};
|
|
29865
29888
|
}
|
|
29866
29889
|
function hatchBackgroundMask(hatch) {
|
package/dist/index.js
CHANGED
|
@@ -29229,9 +29229,9 @@ function perpendicularVectors(width, dx0, dy0) {
|
|
|
29229
29229
|
const vx = rounded[0], vy = rounded[1];
|
|
29230
29230
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29231
29231
|
}
|
|
29232
|
-
function squareExtension(width, dx, dy) {
|
|
29232
|
+
function squareExtension(width, dx, dy, scale = 1) {
|
|
29233
29233
|
const len = Math.hypot(dx, dy);
|
|
29234
|
-
const r = width / 2;
|
|
29234
|
+
const r = width / 2 * scale;
|
|
29235
29235
|
return [Math.floor(dx / len * r + 0.5), Math.floor(dy / len * r + 0.5)];
|
|
29236
29236
|
}
|
|
29237
29237
|
function turnSign(ax, ay, bx, by) {
|
|
@@ -29270,7 +29270,7 @@ var Outliner = class {
|
|
|
29270
29270
|
const [L, R] = drawVertices(this.pen, d[0], d[1]);
|
|
29271
29271
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29272
29272
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
|
|
29273
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29273
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29274
29274
|
}
|
|
29275
29275
|
push(p, v) {
|
|
29276
29276
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29365,7 +29365,7 @@ var Outliner = class {
|
|
|
29365
29365
|
return side === "R" ? s.v : [-s.v[0], -s.v[1]];
|
|
29366
29366
|
}
|
|
29367
29367
|
/** A cap at `p` from the `from` side of `s` round to the other side (`start`: around the back). */
|
|
29368
|
-
cap(p, s, start) {
|
|
29368
|
+
cap(p, s, start, scale = 1) {
|
|
29369
29369
|
const from = start ? "L" : "R";
|
|
29370
29370
|
const to = start ? "R" : "L";
|
|
29371
29371
|
const { cap } = this.opts;
|
|
@@ -29383,7 +29383,8 @@ var Outliner = class {
|
|
|
29383
29383
|
const sv = this.capSide(s, from);
|
|
29384
29384
|
const ev = this.capSide(s, to);
|
|
29385
29385
|
if (cap === "square") {
|
|
29386
|
-
const
|
|
29386
|
+
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale);
|
|
29387
|
+
const e = start ? [-e0[0], -e0[1]] : e0;
|
|
29387
29388
|
this.push(p, [sv[0] + e[0], sv[1] + e[1]]);
|
|
29388
29389
|
this.push(p, [ev[0] + e[0], ev[1] + e[1]]);
|
|
29389
29390
|
} else {
|
|
@@ -29479,7 +29480,7 @@ var Outliner = class {
|
|
|
29479
29480
|
* lets a single point stand for a zero-length dash along `dirs[0]`;
|
|
29480
29481
|
* `draws` (curve end tangents) picks draw vertices only.
|
|
29481
29482
|
*/
|
|
29482
|
-
open(P, dirs, draws, curves) {
|
|
29483
|
+
open(P, dirs, draws, curves, startScale = 1, endScale = 1) {
|
|
29483
29484
|
if (P.length < 2 && !dirs?.[0]) {
|
|
29484
29485
|
this.dot(P[0]);
|
|
29485
29486
|
return;
|
|
@@ -29490,12 +29491,12 @@ var Outliner = class {
|
|
|
29490
29491
|
}
|
|
29491
29492
|
if (segs2.length === 0) {
|
|
29492
29493
|
const s = this.seg(P[0], P[0], dirs?.[0], draws?.[0], curves?.[0]);
|
|
29493
|
-
this.cap(P[0], s, true);
|
|
29494
|
-
this.cap(P[0], s, false);
|
|
29494
|
+
this.cap(P[0], s, true, startScale);
|
|
29495
|
+
this.cap(P[0], s, false, endScale);
|
|
29495
29496
|
this.flush();
|
|
29496
29497
|
return;
|
|
29497
29498
|
}
|
|
29498
|
-
this.cap(P[0], segs2[0], true);
|
|
29499
|
+
this.cap(P[0], segs2[0], true, startScale);
|
|
29499
29500
|
for (let i = 0; i + 1 < segs2.length; i++) {
|
|
29500
29501
|
const s = segs2[i];
|
|
29501
29502
|
const t = segs2[i + 1];
|
|
@@ -29506,7 +29507,7 @@ var Outliner = class {
|
|
|
29506
29507
|
this.join(P[i + 1], s, t, "R", tr < 0);
|
|
29507
29508
|
}
|
|
29508
29509
|
}
|
|
29509
|
-
this.cap(P[P.length - 1], segs2[segs2.length - 1], false);
|
|
29510
|
+
this.cap(P[P.length - 1], segs2[segs2.length - 1], false, endScale);
|
|
29510
29511
|
for (let i = segs2.length - 1; i > 0; i--) {
|
|
29511
29512
|
const s = segs2[i];
|
|
29512
29513
|
const t = segs2[i - 1];
|
|
@@ -29562,7 +29563,7 @@ var Outliner = class {
|
|
|
29562
29563
|
this.flush();
|
|
29563
29564
|
}
|
|
29564
29565
|
};
|
|
29565
|
-
function dashPieces(P, tangents, pattern, shorten) {
|
|
29566
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors) {
|
|
29566
29567
|
const out = [];
|
|
29567
29568
|
const dashes = [];
|
|
29568
29569
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29577,12 +29578,22 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29577
29578
|
let idx = 0;
|
|
29578
29579
|
let left = dashes[0];
|
|
29579
29580
|
let on = true;
|
|
29580
|
-
let cur = { pts: [P[0]], dirs: [], draws: [] };
|
|
29581
|
+
let cur = { pts: [P[0]], dirs: [], draws: [], curves: [], startScale: 1, endScale: 1 };
|
|
29581
29582
|
for (let i = 0; i + 1 < P.length; i++) {
|
|
29582
29583
|
const [x0, y0] = P[i];
|
|
29583
29584
|
const [x1, y1] = P[i + 1];
|
|
29584
29585
|
const dir = [x1 - x0, y1 - y0];
|
|
29585
|
-
const
|
|
29586
|
+
const real = Math.hypot(dir[0], dir[1]);
|
|
29587
|
+
const len = wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29588
|
+
if (len === 0) {
|
|
29589
|
+
if (on && cur) {
|
|
29590
|
+
cur.pts.push(P[i + 1]);
|
|
29591
|
+
cur.dirs.push(dir);
|
|
29592
|
+
cur.draws.push(tangents[i]);
|
|
29593
|
+
cur.curves.push(curveFlags[i]);
|
|
29594
|
+
}
|
|
29595
|
+
continue;
|
|
29596
|
+
}
|
|
29586
29597
|
let t = 0;
|
|
29587
29598
|
while (len - t > left || left === 0 && on) {
|
|
29588
29599
|
t += left;
|
|
@@ -29591,10 +29602,12 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29591
29602
|
cur.pts.push(q);
|
|
29592
29603
|
cur.dirs.push(dir);
|
|
29593
29604
|
cur.draws.push(tangents[i]);
|
|
29605
|
+
cur.curves.push(curveFlags[i]);
|
|
29606
|
+
cur.endScale = cur.pts[0] === P[0] && q[0] === P[0][0] && q[1] === P[0][1] ? 1 : real / len;
|
|
29594
29607
|
out.push(cur);
|
|
29595
29608
|
cur = null;
|
|
29596
29609
|
} else {
|
|
29597
|
-
cur = { pts: [q], dirs: [], draws: [] };
|
|
29610
|
+
cur = { pts: [q], dirs: [], draws: [], curves: [], startScale: real / len, endScale: 1 };
|
|
29598
29611
|
}
|
|
29599
29612
|
on = !on;
|
|
29600
29613
|
idx = (idx + 1) % dashes.length;
|
|
@@ -29605,9 +29618,12 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29605
29618
|
cur.pts.push(P[i + 1]);
|
|
29606
29619
|
cur.dirs.push(dir);
|
|
29607
29620
|
cur.draws.push(tangents[i]);
|
|
29621
|
+
cur.curves.push(curveFlags[i]);
|
|
29622
|
+
cur.endScale = real / len;
|
|
29608
29623
|
}
|
|
29609
29624
|
}
|
|
29610
29625
|
if (on && cur && cur.dirs.length > 0) {
|
|
29626
|
+
cur.endScale = 1;
|
|
29611
29627
|
out.push(cur);
|
|
29612
29628
|
}
|
|
29613
29629
|
return out;
|
|
@@ -29642,10 +29658,13 @@ function widenPath(path, opts) {
|
|
|
29642
29658
|
if (dashed) {
|
|
29643
29659
|
const run = closed ? [...P, P[0]] : P;
|
|
29644
29660
|
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.width;
|
|
29645
|
-
|
|
29661
|
+
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29662
|
+
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29663
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors)) {
|
|
29646
29664
|
const pts = [piece.pts[0]];
|
|
29647
29665
|
const pdirs = [];
|
|
29648
29666
|
const pdraws = [];
|
|
29667
|
+
const pcurves = [];
|
|
29649
29668
|
for (let i = 1; i < piece.pts.length; i++) {
|
|
29650
29669
|
const q = piece.pts[i];
|
|
29651
29670
|
const last = pts[pts.length - 1];
|
|
@@ -29653,9 +29672,10 @@ function widenPath(path, opts) {
|
|
|
29653
29672
|
pts.push(q);
|
|
29654
29673
|
pdirs.push(piece.dirs[i - 1]);
|
|
29655
29674
|
pdraws.push(piece.draws[i - 1]);
|
|
29675
|
+
pcurves.push(piece.curves[i - 1]);
|
|
29656
29676
|
}
|
|
29657
29677
|
}
|
|
29658
|
-
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]],
|
|
29678
|
+
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);
|
|
29659
29679
|
}
|
|
29660
29680
|
} else if (closed && P.length >= 3) {
|
|
29661
29681
|
outliner.closed(P, dirs, curves);
|
|
@@ -29863,7 +29883,10 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
29863
29883
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
29864
29884
|
miterLimit: state.miterLimit ?? 10,
|
|
29865
29885
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
29866
|
-
shortenDashes: (flags & 15) !== 7
|
|
29886
|
+
shortenDashes: (flags & 15) !== 7,
|
|
29887
|
+
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
29888
|
+
// segments in whole pixels.
|
|
29889
|
+
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
|
|
29867
29890
|
};
|
|
29868
29891
|
}
|
|
29869
29892
|
function hatchBackgroundMask(hatch) {
|
package/dist/index.mjs
CHANGED
|
@@ -29227,9 +29227,9 @@ function perpendicularVectors(width, dx0, dy0) {
|
|
|
29227
29227
|
const vx = rounded[0], vy = rounded[1];
|
|
29228
29228
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29229
29229
|
}
|
|
29230
|
-
function squareExtension(width, dx, dy) {
|
|
29230
|
+
function squareExtension(width, dx, dy, scale = 1) {
|
|
29231
29231
|
const len = Math.hypot(dx, dy);
|
|
29232
|
-
const r = width / 2;
|
|
29232
|
+
const r = width / 2 * scale;
|
|
29233
29233
|
return [Math.floor(dx / len * r + 0.5), Math.floor(dy / len * r + 0.5)];
|
|
29234
29234
|
}
|
|
29235
29235
|
function turnSign(ax, ay, bx, by) {
|
|
@@ -29268,7 +29268,7 @@ var Outliner = class {
|
|
|
29268
29268
|
const [L, R] = drawVertices(this.pen, d[0], d[1]);
|
|
29269
29269
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29270
29270
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
|
|
29271
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29271
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29272
29272
|
}
|
|
29273
29273
|
push(p, v) {
|
|
29274
29274
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29363,7 +29363,7 @@ var Outliner = class {
|
|
|
29363
29363
|
return side === "R" ? s.v : [-s.v[0], -s.v[1]];
|
|
29364
29364
|
}
|
|
29365
29365
|
/** A cap at `p` from the `from` side of `s` round to the other side (`start`: around the back). */
|
|
29366
|
-
cap(p, s, start) {
|
|
29366
|
+
cap(p, s, start, scale = 1) {
|
|
29367
29367
|
const from = start ? "L" : "R";
|
|
29368
29368
|
const to = start ? "R" : "L";
|
|
29369
29369
|
const { cap } = this.opts;
|
|
@@ -29381,7 +29381,8 @@ var Outliner = class {
|
|
|
29381
29381
|
const sv = this.capSide(s, from);
|
|
29382
29382
|
const ev = this.capSide(s, to);
|
|
29383
29383
|
if (cap === "square") {
|
|
29384
|
-
const
|
|
29384
|
+
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale);
|
|
29385
|
+
const e = start ? [-e0[0], -e0[1]] : e0;
|
|
29385
29386
|
this.push(p, [sv[0] + e[0], sv[1] + e[1]]);
|
|
29386
29387
|
this.push(p, [ev[0] + e[0], ev[1] + e[1]]);
|
|
29387
29388
|
} else {
|
|
@@ -29477,7 +29478,7 @@ var Outliner = class {
|
|
|
29477
29478
|
* lets a single point stand for a zero-length dash along `dirs[0]`;
|
|
29478
29479
|
* `draws` (curve end tangents) picks draw vertices only.
|
|
29479
29480
|
*/
|
|
29480
|
-
open(P, dirs, draws, curves) {
|
|
29481
|
+
open(P, dirs, draws, curves, startScale = 1, endScale = 1) {
|
|
29481
29482
|
if (P.length < 2 && !dirs?.[0]) {
|
|
29482
29483
|
this.dot(P[0]);
|
|
29483
29484
|
return;
|
|
@@ -29488,12 +29489,12 @@ var Outliner = class {
|
|
|
29488
29489
|
}
|
|
29489
29490
|
if (segs2.length === 0) {
|
|
29490
29491
|
const s = this.seg(P[0], P[0], dirs?.[0], draws?.[0], curves?.[0]);
|
|
29491
|
-
this.cap(P[0], s, true);
|
|
29492
|
-
this.cap(P[0], s, false);
|
|
29492
|
+
this.cap(P[0], s, true, startScale);
|
|
29493
|
+
this.cap(P[0], s, false, endScale);
|
|
29493
29494
|
this.flush();
|
|
29494
29495
|
return;
|
|
29495
29496
|
}
|
|
29496
|
-
this.cap(P[0], segs2[0], true);
|
|
29497
|
+
this.cap(P[0], segs2[0], true, startScale);
|
|
29497
29498
|
for (let i = 0; i + 1 < segs2.length; i++) {
|
|
29498
29499
|
const s = segs2[i];
|
|
29499
29500
|
const t = segs2[i + 1];
|
|
@@ -29504,7 +29505,7 @@ var Outliner = class {
|
|
|
29504
29505
|
this.join(P[i + 1], s, t, "R", tr < 0);
|
|
29505
29506
|
}
|
|
29506
29507
|
}
|
|
29507
|
-
this.cap(P[P.length - 1], segs2[segs2.length - 1], false);
|
|
29508
|
+
this.cap(P[P.length - 1], segs2[segs2.length - 1], false, endScale);
|
|
29508
29509
|
for (let i = segs2.length - 1; i > 0; i--) {
|
|
29509
29510
|
const s = segs2[i];
|
|
29510
29511
|
const t = segs2[i - 1];
|
|
@@ -29560,7 +29561,7 @@ var Outliner = class {
|
|
|
29560
29561
|
this.flush();
|
|
29561
29562
|
}
|
|
29562
29563
|
};
|
|
29563
|
-
function dashPieces(P, tangents, pattern, shorten) {
|
|
29564
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors) {
|
|
29564
29565
|
const out = [];
|
|
29565
29566
|
const dashes = [];
|
|
29566
29567
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29575,12 +29576,22 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29575
29576
|
let idx = 0;
|
|
29576
29577
|
let left = dashes[0];
|
|
29577
29578
|
let on = true;
|
|
29578
|
-
let cur = { pts: [P[0]], dirs: [], draws: [] };
|
|
29579
|
+
let cur = { pts: [P[0]], dirs: [], draws: [], curves: [], startScale: 1, endScale: 1 };
|
|
29579
29580
|
for (let i = 0; i + 1 < P.length; i++) {
|
|
29580
29581
|
const [x0, y0] = P[i];
|
|
29581
29582
|
const [x1, y1] = P[i + 1];
|
|
29582
29583
|
const dir = [x1 - x0, y1 - y0];
|
|
29583
|
-
const
|
|
29584
|
+
const real = Math.hypot(dir[0], dir[1]);
|
|
29585
|
+
const len = wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29586
|
+
if (len === 0) {
|
|
29587
|
+
if (on && cur) {
|
|
29588
|
+
cur.pts.push(P[i + 1]);
|
|
29589
|
+
cur.dirs.push(dir);
|
|
29590
|
+
cur.draws.push(tangents[i]);
|
|
29591
|
+
cur.curves.push(curveFlags[i]);
|
|
29592
|
+
}
|
|
29593
|
+
continue;
|
|
29594
|
+
}
|
|
29584
29595
|
let t = 0;
|
|
29585
29596
|
while (len - t > left || left === 0 && on) {
|
|
29586
29597
|
t += left;
|
|
@@ -29589,10 +29600,12 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29589
29600
|
cur.pts.push(q);
|
|
29590
29601
|
cur.dirs.push(dir);
|
|
29591
29602
|
cur.draws.push(tangents[i]);
|
|
29603
|
+
cur.curves.push(curveFlags[i]);
|
|
29604
|
+
cur.endScale = cur.pts[0] === P[0] && q[0] === P[0][0] && q[1] === P[0][1] ? 1 : real / len;
|
|
29592
29605
|
out.push(cur);
|
|
29593
29606
|
cur = null;
|
|
29594
29607
|
} else {
|
|
29595
|
-
cur = { pts: [q], dirs: [], draws: [] };
|
|
29608
|
+
cur = { pts: [q], dirs: [], draws: [], curves: [], startScale: real / len, endScale: 1 };
|
|
29596
29609
|
}
|
|
29597
29610
|
on = !on;
|
|
29598
29611
|
idx = (idx + 1) % dashes.length;
|
|
@@ -29603,9 +29616,12 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29603
29616
|
cur.pts.push(P[i + 1]);
|
|
29604
29617
|
cur.dirs.push(dir);
|
|
29605
29618
|
cur.draws.push(tangents[i]);
|
|
29619
|
+
cur.curves.push(curveFlags[i]);
|
|
29620
|
+
cur.endScale = real / len;
|
|
29606
29621
|
}
|
|
29607
29622
|
}
|
|
29608
29623
|
if (on && cur && cur.dirs.length > 0) {
|
|
29624
|
+
cur.endScale = 1;
|
|
29609
29625
|
out.push(cur);
|
|
29610
29626
|
}
|
|
29611
29627
|
return out;
|
|
@@ -29640,10 +29656,13 @@ function widenPath(path, opts) {
|
|
|
29640
29656
|
if (dashed) {
|
|
29641
29657
|
const run = closed ? [...P, P[0]] : P;
|
|
29642
29658
|
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.width;
|
|
29643
|
-
|
|
29659
|
+
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29660
|
+
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29661
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors)) {
|
|
29644
29662
|
const pts = [piece.pts[0]];
|
|
29645
29663
|
const pdirs = [];
|
|
29646
29664
|
const pdraws = [];
|
|
29665
|
+
const pcurves = [];
|
|
29647
29666
|
for (let i = 1; i < piece.pts.length; i++) {
|
|
29648
29667
|
const q = piece.pts[i];
|
|
29649
29668
|
const last = pts[pts.length - 1];
|
|
@@ -29651,9 +29670,10 @@ function widenPath(path, opts) {
|
|
|
29651
29670
|
pts.push(q);
|
|
29652
29671
|
pdirs.push(piece.dirs[i - 1]);
|
|
29653
29672
|
pdraws.push(piece.draws[i - 1]);
|
|
29673
|
+
pcurves.push(piece.curves[i - 1]);
|
|
29654
29674
|
}
|
|
29655
29675
|
}
|
|
29656
|
-
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]],
|
|
29676
|
+
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);
|
|
29657
29677
|
}
|
|
29658
29678
|
} else if (closed && P.length >= 3) {
|
|
29659
29679
|
outliner.closed(P, dirs, curves);
|
|
@@ -29861,7 +29881,10 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
29861
29881
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
29862
29882
|
miterLimit: state.miterLimit ?? 10,
|
|
29863
29883
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
29864
|
-
shortenDashes: (flags & 15) !== 7
|
|
29884
|
+
shortenDashes: (flags & 15) !== 7,
|
|
29885
|
+
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
29886
|
+
// segments in whole pixels.
|
|
29887
|
+
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
|
|
29865
29888
|
};
|
|
29866
29889
|
}
|
|
29867
29890
|
function hatchBackgroundMask(hatch) {
|