emf-converter 4.8.21 → 4.10.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 +52 -7
- package/dist/browser.mjs +52 -7
- package/dist/index.js +52 -7
- package/dist/index.mjs +52 -7
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -29643,7 +29643,7 @@ var Outliner = class {
|
|
|
29643
29643
|
this.flush();
|
|
29644
29644
|
}
|
|
29645
29645
|
};
|
|
29646
|
-
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors) {
|
|
29646
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric) {
|
|
29647
29647
|
const out = [];
|
|
29648
29648
|
const dashes = [];
|
|
29649
29649
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29663,8 +29663,8 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29663
29663
|
const [x0, y0] = P[i];
|
|
29664
29664
|
const [x1, y1] = P[i + 1];
|
|
29665
29665
|
const dir = [x1 - x0, y1 - y0];
|
|
29666
|
-
const real = Math.hypot(dir[0], dir[1]);
|
|
29667
|
-
const len = wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29666
|
+
const real = metric ? Math.hypot(dir[0] / metric[0], dir[1] / metric[1]) : Math.hypot(dir[0], dir[1]);
|
|
29667
|
+
const len = metric ? real : wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29668
29668
|
if (len === 0) {
|
|
29669
29669
|
if (on && cur) {
|
|
29670
29670
|
cur.pts.push(P[i + 1]);
|
|
@@ -29708,7 +29708,35 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29708
29708
|
}
|
|
29709
29709
|
return out;
|
|
29710
29710
|
}
|
|
29711
|
+
function widenInLogicalSpace(path, opts, m) {
|
|
29712
|
+
const [a, b, c, d] = m;
|
|
29713
|
+
const det = a * d - b * c;
|
|
29714
|
+
const inverse = (x, y) => [(d * x - c * y) / det, (-b * x + a * y) / det];
|
|
29715
|
+
const logical = new GdiRasterPath();
|
|
29716
|
+
for (const fig of path.figures) {
|
|
29717
|
+
const pts = [];
|
|
29718
|
+
for (let i = 0; i + 1 < fig.pts.length; i += 2) {
|
|
29719
|
+
pts.push(...inverse(fig.pts[i], fig.pts[i + 1]));
|
|
29720
|
+
}
|
|
29721
|
+
const copy = { pts, closed: fig.closed, roundWiden: fig.roundWiden, curveSegs: fig.curveSegs };
|
|
29722
|
+
if (fig.tangents) {
|
|
29723
|
+
copy.tangents = new Map([...fig.tangents].map(([k, v]) => [k, inverse(v[0], v[1])]));
|
|
29724
|
+
}
|
|
29725
|
+
logical.figures.push(copy);
|
|
29726
|
+
}
|
|
29727
|
+
const outline = widenPath(logical, { ...opts, matrix: void 0, height: void 0 });
|
|
29728
|
+
return outline.map((poly) => {
|
|
29729
|
+
const out = [];
|
|
29730
|
+
for (let i = 0; i + 1 < poly.length; i += 2) {
|
|
29731
|
+
out.push(Math.round(a * poly[i] + c * poly[i + 1]), Math.round(b * poly[i] + d * poly[i + 1]));
|
|
29732
|
+
}
|
|
29733
|
+
return out;
|
|
29734
|
+
});
|
|
29735
|
+
}
|
|
29711
29736
|
function widenPath(path, opts) {
|
|
29737
|
+
if (opts.matrix) {
|
|
29738
|
+
return widenInLogicalSpace(path, opts, opts.matrix);
|
|
29739
|
+
}
|
|
29712
29740
|
const out = [];
|
|
29713
29741
|
const dashed = !!opts.dashes && opts.dashes.length > 0;
|
|
29714
29742
|
for (const fig of path.figures) {
|
|
@@ -29737,10 +29765,10 @@ function widenPath(path, opts) {
|
|
|
29737
29765
|
}
|
|
29738
29766
|
if (dashed) {
|
|
29739
29767
|
const run = closed ? [...P, P[0]] : P;
|
|
29740
|
-
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.width;
|
|
29768
|
+
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.dashMetric ? opts.width / opts.dashMetric[0] : opts.width;
|
|
29741
29769
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29742
29770
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29743
|
-
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors)) {
|
|
29771
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric)) {
|
|
29744
29772
|
const pts = [piece.pts[0]];
|
|
29745
29773
|
const pdirs = [];
|
|
29746
29774
|
const pdraws = [];
|
|
@@ -30007,8 +30035,24 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30007
30035
|
const widthPx = rCtx.wholeDevicePixels && (flags & 15) === 6 ? state.penWidth * Math.sqrt(Math.abs(matrix[0] * matrix[3] - matrix[1] * matrix[2])) : penDeviceWidth(rCtx);
|
|
30008
30036
|
const capBits = flags & 3840;
|
|
30009
30037
|
const joinBits = flags & 61440;
|
|
30010
|
-
const
|
|
30011
|
-
const
|
|
30038
|
+
const ellipse = !rCtx.wholeDevicePixels && state.penWidth * Math.abs(matrix[0]) * 16 >= 1 && state.penWidth * Math.abs(matrix[3]) * 16 >= 1 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6 && Math.abs(Math.abs(matrix[0]) - Math.abs(matrix[3])) > 1e-6;
|
|
30039
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
30040
|
+
const rotatedOrSheared = Math.abs(matrix[1]) >= 1e-6 || Math.abs(matrix[2]) >= 1e-6;
|
|
30041
|
+
const similar = Math.abs(matrix[0] - matrix[3]) < 1e-6 && Math.abs(matrix[1] + matrix[2]) < 1e-6 || Math.abs(matrix[0] + matrix[3]) < 1e-6 && Math.abs(matrix[1] - matrix[2]) < 1e-6;
|
|
30042
|
+
const general = !rCtx.wholeDevicePixels && rotatedOrSheared && !similar && Math.abs(det) > 1e-9 && state.penWidth * Math.sqrt(Math.abs(det)) * 16 >= 1;
|
|
30043
|
+
const dashes = state.penExtended ? ellipse || general ? geometricStyle(flags, state.penWidth, state.penUserStyle, 1) : geometricStyle(flags, widthPx, state.penUserStyle, widthPx / (state.penWidth || 1)) : null;
|
|
30044
|
+
const dashMetric = ellipse && dashes ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : void 0;
|
|
30045
|
+
if (general) {
|
|
30046
|
+
return {
|
|
30047
|
+
width: Math.round(state.penWidth * 16),
|
|
30048
|
+
matrix: [matrix[0], matrix[1], matrix[2], matrix[3]],
|
|
30049
|
+
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30050
|
+
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30051
|
+
miterLimit: state.miterLimit ?? 10,
|
|
30052
|
+
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30053
|
+
shortenDashes: (flags & 15) !== 7
|
|
30054
|
+
};
|
|
30055
|
+
}
|
|
30012
30056
|
return {
|
|
30013
30057
|
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : widthPx) * 16),
|
|
30014
30058
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
|
@@ -30016,6 +30060,7 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30016
30060
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30017
30061
|
miterLimit: state.miterLimit ?? 10,
|
|
30018
30062
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30063
|
+
...dashMetric ? { dashMetric } : {},
|
|
30019
30064
|
shortenDashes: (flags & 15) !== 7,
|
|
30020
30065
|
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
30021
30066
|
// segments in whole pixels.
|
package/dist/browser.mjs
CHANGED
|
@@ -29641,7 +29641,7 @@ var Outliner = class {
|
|
|
29641
29641
|
this.flush();
|
|
29642
29642
|
}
|
|
29643
29643
|
};
|
|
29644
|
-
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors) {
|
|
29644
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric) {
|
|
29645
29645
|
const out = [];
|
|
29646
29646
|
const dashes = [];
|
|
29647
29647
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29661,8 +29661,8 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29661
29661
|
const [x0, y0] = P[i];
|
|
29662
29662
|
const [x1, y1] = P[i + 1];
|
|
29663
29663
|
const dir = [x1 - x0, y1 - y0];
|
|
29664
|
-
const real = Math.hypot(dir[0], dir[1]);
|
|
29665
|
-
const len = wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29664
|
+
const real = metric ? Math.hypot(dir[0] / metric[0], dir[1] / metric[1]) : Math.hypot(dir[0], dir[1]);
|
|
29665
|
+
const len = metric ? real : wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29666
29666
|
if (len === 0) {
|
|
29667
29667
|
if (on && cur) {
|
|
29668
29668
|
cur.pts.push(P[i + 1]);
|
|
@@ -29706,7 +29706,35 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29706
29706
|
}
|
|
29707
29707
|
return out;
|
|
29708
29708
|
}
|
|
29709
|
+
function widenInLogicalSpace(path, opts, m) {
|
|
29710
|
+
const [a, b, c, d] = m;
|
|
29711
|
+
const det = a * d - b * c;
|
|
29712
|
+
const inverse = (x, y) => [(d * x - c * y) / det, (-b * x + a * y) / det];
|
|
29713
|
+
const logical = new GdiRasterPath();
|
|
29714
|
+
for (const fig of path.figures) {
|
|
29715
|
+
const pts = [];
|
|
29716
|
+
for (let i = 0; i + 1 < fig.pts.length; i += 2) {
|
|
29717
|
+
pts.push(...inverse(fig.pts[i], fig.pts[i + 1]));
|
|
29718
|
+
}
|
|
29719
|
+
const copy = { pts, closed: fig.closed, roundWiden: fig.roundWiden, curveSegs: fig.curveSegs };
|
|
29720
|
+
if (fig.tangents) {
|
|
29721
|
+
copy.tangents = new Map([...fig.tangents].map(([k, v]) => [k, inverse(v[0], v[1])]));
|
|
29722
|
+
}
|
|
29723
|
+
logical.figures.push(copy);
|
|
29724
|
+
}
|
|
29725
|
+
const outline = widenPath(logical, { ...opts, matrix: void 0, height: void 0 });
|
|
29726
|
+
return outline.map((poly) => {
|
|
29727
|
+
const out = [];
|
|
29728
|
+
for (let i = 0; i + 1 < poly.length; i += 2) {
|
|
29729
|
+
out.push(Math.round(a * poly[i] + c * poly[i + 1]), Math.round(b * poly[i] + d * poly[i + 1]));
|
|
29730
|
+
}
|
|
29731
|
+
return out;
|
|
29732
|
+
});
|
|
29733
|
+
}
|
|
29709
29734
|
function widenPath(path, opts) {
|
|
29735
|
+
if (opts.matrix) {
|
|
29736
|
+
return widenInLogicalSpace(path, opts, opts.matrix);
|
|
29737
|
+
}
|
|
29710
29738
|
const out = [];
|
|
29711
29739
|
const dashed = !!opts.dashes && opts.dashes.length > 0;
|
|
29712
29740
|
for (const fig of path.figures) {
|
|
@@ -29735,10 +29763,10 @@ function widenPath(path, opts) {
|
|
|
29735
29763
|
}
|
|
29736
29764
|
if (dashed) {
|
|
29737
29765
|
const run = closed ? [...P, P[0]] : P;
|
|
29738
|
-
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.width;
|
|
29766
|
+
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.dashMetric ? opts.width / opts.dashMetric[0] : opts.width;
|
|
29739
29767
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29740
29768
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29741
|
-
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors)) {
|
|
29769
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric)) {
|
|
29742
29770
|
const pts = [piece.pts[0]];
|
|
29743
29771
|
const pdirs = [];
|
|
29744
29772
|
const pdraws = [];
|
|
@@ -30005,8 +30033,24 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30005
30033
|
const widthPx = rCtx.wholeDevicePixels && (flags & 15) === 6 ? state.penWidth * Math.sqrt(Math.abs(matrix[0] * matrix[3] - matrix[1] * matrix[2])) : penDeviceWidth(rCtx);
|
|
30006
30034
|
const capBits = flags & 3840;
|
|
30007
30035
|
const joinBits = flags & 61440;
|
|
30008
|
-
const
|
|
30009
|
-
const
|
|
30036
|
+
const ellipse = !rCtx.wholeDevicePixels && state.penWidth * Math.abs(matrix[0]) * 16 >= 1 && state.penWidth * Math.abs(matrix[3]) * 16 >= 1 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6 && Math.abs(Math.abs(matrix[0]) - Math.abs(matrix[3])) > 1e-6;
|
|
30037
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
30038
|
+
const rotatedOrSheared = Math.abs(matrix[1]) >= 1e-6 || Math.abs(matrix[2]) >= 1e-6;
|
|
30039
|
+
const similar = Math.abs(matrix[0] - matrix[3]) < 1e-6 && Math.abs(matrix[1] + matrix[2]) < 1e-6 || Math.abs(matrix[0] + matrix[3]) < 1e-6 && Math.abs(matrix[1] - matrix[2]) < 1e-6;
|
|
30040
|
+
const general = !rCtx.wholeDevicePixels && rotatedOrSheared && !similar && Math.abs(det) > 1e-9 && state.penWidth * Math.sqrt(Math.abs(det)) * 16 >= 1;
|
|
30041
|
+
const dashes = state.penExtended ? ellipse || general ? geometricStyle(flags, state.penWidth, state.penUserStyle, 1) : geometricStyle(flags, widthPx, state.penUserStyle, widthPx / (state.penWidth || 1)) : null;
|
|
30042
|
+
const dashMetric = ellipse && dashes ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : void 0;
|
|
30043
|
+
if (general) {
|
|
30044
|
+
return {
|
|
30045
|
+
width: Math.round(state.penWidth * 16),
|
|
30046
|
+
matrix: [matrix[0], matrix[1], matrix[2], matrix[3]],
|
|
30047
|
+
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30048
|
+
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30049
|
+
miterLimit: state.miterLimit ?? 10,
|
|
30050
|
+
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30051
|
+
shortenDashes: (flags & 15) !== 7
|
|
30052
|
+
};
|
|
30053
|
+
}
|
|
30010
30054
|
return {
|
|
30011
30055
|
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : widthPx) * 16),
|
|
30012
30056
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
|
@@ -30014,6 +30058,7 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30014
30058
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30015
30059
|
miterLimit: state.miterLimit ?? 10,
|
|
30016
30060
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30061
|
+
...dashMetric ? { dashMetric } : {},
|
|
30017
30062
|
shortenDashes: (flags & 15) !== 7,
|
|
30018
30063
|
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
30019
30064
|
// segments in whole pixels.
|
package/dist/index.js
CHANGED
|
@@ -29644,7 +29644,7 @@ var Outliner = class {
|
|
|
29644
29644
|
this.flush();
|
|
29645
29645
|
}
|
|
29646
29646
|
};
|
|
29647
|
-
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors) {
|
|
29647
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric) {
|
|
29648
29648
|
const out = [];
|
|
29649
29649
|
const dashes = [];
|
|
29650
29650
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29664,8 +29664,8 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29664
29664
|
const [x0, y0] = P[i];
|
|
29665
29665
|
const [x1, y1] = P[i + 1];
|
|
29666
29666
|
const dir = [x1 - x0, y1 - y0];
|
|
29667
|
-
const real = Math.hypot(dir[0], dir[1]);
|
|
29668
|
-
const len = wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29667
|
+
const real = metric ? Math.hypot(dir[0] / metric[0], dir[1] / metric[1]) : Math.hypot(dir[0], dir[1]);
|
|
29668
|
+
const len = metric ? real : wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29669
29669
|
if (len === 0) {
|
|
29670
29670
|
if (on && cur) {
|
|
29671
29671
|
cur.pts.push(P[i + 1]);
|
|
@@ -29709,7 +29709,35 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29709
29709
|
}
|
|
29710
29710
|
return out;
|
|
29711
29711
|
}
|
|
29712
|
+
function widenInLogicalSpace(path, opts, m) {
|
|
29713
|
+
const [a, b, c, d] = m;
|
|
29714
|
+
const det = a * d - b * c;
|
|
29715
|
+
const inverse = (x, y) => [(d * x - c * y) / det, (-b * x + a * y) / det];
|
|
29716
|
+
const logical = new GdiRasterPath();
|
|
29717
|
+
for (const fig of path.figures) {
|
|
29718
|
+
const pts = [];
|
|
29719
|
+
for (let i = 0; i + 1 < fig.pts.length; i += 2) {
|
|
29720
|
+
pts.push(...inverse(fig.pts[i], fig.pts[i + 1]));
|
|
29721
|
+
}
|
|
29722
|
+
const copy = { pts, closed: fig.closed, roundWiden: fig.roundWiden, curveSegs: fig.curveSegs };
|
|
29723
|
+
if (fig.tangents) {
|
|
29724
|
+
copy.tangents = new Map([...fig.tangents].map(([k, v]) => [k, inverse(v[0], v[1])]));
|
|
29725
|
+
}
|
|
29726
|
+
logical.figures.push(copy);
|
|
29727
|
+
}
|
|
29728
|
+
const outline = widenPath(logical, { ...opts, matrix: void 0, height: void 0 });
|
|
29729
|
+
return outline.map((poly) => {
|
|
29730
|
+
const out = [];
|
|
29731
|
+
for (let i = 0; i + 1 < poly.length; i += 2) {
|
|
29732
|
+
out.push(Math.round(a * poly[i] + c * poly[i + 1]), Math.round(b * poly[i] + d * poly[i + 1]));
|
|
29733
|
+
}
|
|
29734
|
+
return out;
|
|
29735
|
+
});
|
|
29736
|
+
}
|
|
29712
29737
|
function widenPath(path, opts) {
|
|
29738
|
+
if (opts.matrix) {
|
|
29739
|
+
return widenInLogicalSpace(path, opts, opts.matrix);
|
|
29740
|
+
}
|
|
29713
29741
|
const out = [];
|
|
29714
29742
|
const dashed = !!opts.dashes && opts.dashes.length > 0;
|
|
29715
29743
|
for (const fig of path.figures) {
|
|
@@ -29738,10 +29766,10 @@ function widenPath(path, opts) {
|
|
|
29738
29766
|
}
|
|
29739
29767
|
if (dashed) {
|
|
29740
29768
|
const run = closed ? [...P, P[0]] : P;
|
|
29741
|
-
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.width;
|
|
29769
|
+
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.dashMetric ? opts.width / opts.dashMetric[0] : opts.width;
|
|
29742
29770
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29743
29771
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29744
|
-
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors)) {
|
|
29772
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric)) {
|
|
29745
29773
|
const pts = [piece.pts[0]];
|
|
29746
29774
|
const pdirs = [];
|
|
29747
29775
|
const pdraws = [];
|
|
@@ -30008,8 +30036,24 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30008
30036
|
const widthPx = rCtx.wholeDevicePixels && (flags & 15) === 6 ? state.penWidth * Math.sqrt(Math.abs(matrix[0] * matrix[3] - matrix[1] * matrix[2])) : penDeviceWidth(rCtx);
|
|
30009
30037
|
const capBits = flags & 3840;
|
|
30010
30038
|
const joinBits = flags & 61440;
|
|
30011
|
-
const
|
|
30012
|
-
const
|
|
30039
|
+
const ellipse = !rCtx.wholeDevicePixels && state.penWidth * Math.abs(matrix[0]) * 16 >= 1 && state.penWidth * Math.abs(matrix[3]) * 16 >= 1 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6 && Math.abs(Math.abs(matrix[0]) - Math.abs(matrix[3])) > 1e-6;
|
|
30040
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
30041
|
+
const rotatedOrSheared = Math.abs(matrix[1]) >= 1e-6 || Math.abs(matrix[2]) >= 1e-6;
|
|
30042
|
+
const similar = Math.abs(matrix[0] - matrix[3]) < 1e-6 && Math.abs(matrix[1] + matrix[2]) < 1e-6 || Math.abs(matrix[0] + matrix[3]) < 1e-6 && Math.abs(matrix[1] - matrix[2]) < 1e-6;
|
|
30043
|
+
const general = !rCtx.wholeDevicePixels && rotatedOrSheared && !similar && Math.abs(det) > 1e-9 && state.penWidth * Math.sqrt(Math.abs(det)) * 16 >= 1;
|
|
30044
|
+
const dashes = state.penExtended ? ellipse || general ? geometricStyle(flags, state.penWidth, state.penUserStyle, 1) : geometricStyle(flags, widthPx, state.penUserStyle, widthPx / (state.penWidth || 1)) : null;
|
|
30045
|
+
const dashMetric = ellipse && dashes ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : void 0;
|
|
30046
|
+
if (general) {
|
|
30047
|
+
return {
|
|
30048
|
+
width: Math.round(state.penWidth * 16),
|
|
30049
|
+
matrix: [matrix[0], matrix[1], matrix[2], matrix[3]],
|
|
30050
|
+
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30051
|
+
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30052
|
+
miterLimit: state.miterLimit ?? 10,
|
|
30053
|
+
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30054
|
+
shortenDashes: (flags & 15) !== 7
|
|
30055
|
+
};
|
|
30056
|
+
}
|
|
30013
30057
|
return {
|
|
30014
30058
|
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : widthPx) * 16),
|
|
30015
30059
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
|
@@ -30017,6 +30061,7 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30017
30061
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30018
30062
|
miterLimit: state.miterLimit ?? 10,
|
|
30019
30063
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30064
|
+
...dashMetric ? { dashMetric } : {},
|
|
30020
30065
|
shortenDashes: (flags & 15) !== 7,
|
|
30021
30066
|
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
30022
30067
|
// segments in whole pixels.
|
package/dist/index.mjs
CHANGED
|
@@ -29642,7 +29642,7 @@ var Outliner = class {
|
|
|
29642
29642
|
this.flush();
|
|
29643
29643
|
}
|
|
29644
29644
|
};
|
|
29645
|
-
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors) {
|
|
29645
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric) {
|
|
29646
29646
|
const out = [];
|
|
29647
29647
|
const dashes = [];
|
|
29648
29648
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29662,8 +29662,8 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29662
29662
|
const [x0, y0] = P[i];
|
|
29663
29663
|
const [x1, y1] = P[i + 1];
|
|
29664
29664
|
const dir = [x1 - x0, y1 - y0];
|
|
29665
|
-
const real = Math.hypot(dir[0], dir[1]);
|
|
29666
|
-
const len = wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29665
|
+
const real = metric ? Math.hypot(dir[0] / metric[0], dir[1] / metric[1]) : Math.hypot(dir[0], dir[1]);
|
|
29666
|
+
const len = metric ? real : wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29667
29667
|
if (len === 0) {
|
|
29668
29668
|
if (on && cur) {
|
|
29669
29669
|
cur.pts.push(P[i + 1]);
|
|
@@ -29707,7 +29707,35 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29707
29707
|
}
|
|
29708
29708
|
return out;
|
|
29709
29709
|
}
|
|
29710
|
+
function widenInLogicalSpace(path, opts, m) {
|
|
29711
|
+
const [a, b, c, d] = m;
|
|
29712
|
+
const det = a * d - b * c;
|
|
29713
|
+
const inverse = (x, y) => [(d * x - c * y) / det, (-b * x + a * y) / det];
|
|
29714
|
+
const logical = new GdiRasterPath();
|
|
29715
|
+
for (const fig of path.figures) {
|
|
29716
|
+
const pts = [];
|
|
29717
|
+
for (let i = 0; i + 1 < fig.pts.length; i += 2) {
|
|
29718
|
+
pts.push(...inverse(fig.pts[i], fig.pts[i + 1]));
|
|
29719
|
+
}
|
|
29720
|
+
const copy = { pts, closed: fig.closed, roundWiden: fig.roundWiden, curveSegs: fig.curveSegs };
|
|
29721
|
+
if (fig.tangents) {
|
|
29722
|
+
copy.tangents = new Map([...fig.tangents].map(([k, v]) => [k, inverse(v[0], v[1])]));
|
|
29723
|
+
}
|
|
29724
|
+
logical.figures.push(copy);
|
|
29725
|
+
}
|
|
29726
|
+
const outline = widenPath(logical, { ...opts, matrix: void 0, height: void 0 });
|
|
29727
|
+
return outline.map((poly) => {
|
|
29728
|
+
const out = [];
|
|
29729
|
+
for (let i = 0; i + 1 < poly.length; i += 2) {
|
|
29730
|
+
out.push(Math.round(a * poly[i] + c * poly[i + 1]), Math.round(b * poly[i] + d * poly[i + 1]));
|
|
29731
|
+
}
|
|
29732
|
+
return out;
|
|
29733
|
+
});
|
|
29734
|
+
}
|
|
29710
29735
|
function widenPath(path, opts) {
|
|
29736
|
+
if (opts.matrix) {
|
|
29737
|
+
return widenInLogicalSpace(path, opts, opts.matrix);
|
|
29738
|
+
}
|
|
29711
29739
|
const out = [];
|
|
29712
29740
|
const dashed = !!opts.dashes && opts.dashes.length > 0;
|
|
29713
29741
|
for (const fig of path.figures) {
|
|
@@ -29736,10 +29764,10 @@ function widenPath(path, opts) {
|
|
|
29736
29764
|
}
|
|
29737
29765
|
if (dashed) {
|
|
29738
29766
|
const run = closed ? [...P, P[0]] : P;
|
|
29739
|
-
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.width;
|
|
29767
|
+
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.dashMetric ? opts.width / opts.dashMetric[0] : opts.width;
|
|
29740
29768
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29741
29769
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29742
|
-
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors)) {
|
|
29770
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric)) {
|
|
29743
29771
|
const pts = [piece.pts[0]];
|
|
29744
29772
|
const pdirs = [];
|
|
29745
29773
|
const pdraws = [];
|
|
@@ -30006,8 +30034,24 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30006
30034
|
const widthPx = rCtx.wholeDevicePixels && (flags & 15) === 6 ? state.penWidth * Math.sqrt(Math.abs(matrix[0] * matrix[3] - matrix[1] * matrix[2])) : penDeviceWidth(rCtx);
|
|
30007
30035
|
const capBits = flags & 3840;
|
|
30008
30036
|
const joinBits = flags & 61440;
|
|
30009
|
-
const
|
|
30010
|
-
const
|
|
30037
|
+
const ellipse = !rCtx.wholeDevicePixels && state.penWidth * Math.abs(matrix[0]) * 16 >= 1 && state.penWidth * Math.abs(matrix[3]) * 16 >= 1 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6 && Math.abs(Math.abs(matrix[0]) - Math.abs(matrix[3])) > 1e-6;
|
|
30038
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
30039
|
+
const rotatedOrSheared = Math.abs(matrix[1]) >= 1e-6 || Math.abs(matrix[2]) >= 1e-6;
|
|
30040
|
+
const similar = Math.abs(matrix[0] - matrix[3]) < 1e-6 && Math.abs(matrix[1] + matrix[2]) < 1e-6 || Math.abs(matrix[0] + matrix[3]) < 1e-6 && Math.abs(matrix[1] - matrix[2]) < 1e-6;
|
|
30041
|
+
const general = !rCtx.wholeDevicePixels && rotatedOrSheared && !similar && Math.abs(det) > 1e-9 && state.penWidth * Math.sqrt(Math.abs(det)) * 16 >= 1;
|
|
30042
|
+
const dashes = state.penExtended ? ellipse || general ? geometricStyle(flags, state.penWidth, state.penUserStyle, 1) : geometricStyle(flags, widthPx, state.penUserStyle, widthPx / (state.penWidth || 1)) : null;
|
|
30043
|
+
const dashMetric = ellipse && dashes ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : void 0;
|
|
30044
|
+
if (general) {
|
|
30045
|
+
return {
|
|
30046
|
+
width: Math.round(state.penWidth * 16),
|
|
30047
|
+
matrix: [matrix[0], matrix[1], matrix[2], matrix[3]],
|
|
30048
|
+
cap: opts.roundPen || !state.penExtended || capBits === 0 ? "round" : capBits === 256 ? "square" : "flat",
|
|
30049
|
+
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30050
|
+
miterLimit: state.miterLimit ?? 10,
|
|
30051
|
+
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30052
|
+
shortenDashes: (flags & 15) !== 7
|
|
30053
|
+
};
|
|
30054
|
+
}
|
|
30011
30055
|
return {
|
|
30012
30056
|
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : widthPx) * 16),
|
|
30013
30057
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
|
@@ -30015,6 +30059,7 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
30015
30059
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
30016
30060
|
miterLimit: state.miterLimit ?? 10,
|
|
30017
30061
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30062
|
+
...dashMetric ? { dashMetric } : {},
|
|
30018
30063
|
shortenDashes: (flags & 15) !== 7,
|
|
30019
30064
|
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
30020
30065
|
// segments in whole pixels.
|