emf-converter 4.8.20 → 4.9.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/README.md +4 -33
- package/dist/browser.js +160 -41
- package/dist/browser.mjs +160 -41
- package/dist/index.js +160 -41
- package/dist/index.mjs +160 -41
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11662,11 +11662,20 @@ function ellipseBeziersBox(box, clockwise = false) {
|
|
|
11662
11662
|
if (!clockwise) {
|
|
11663
11663
|
return ellipsePoints(box, false);
|
|
11664
11664
|
}
|
|
11665
|
-
const
|
|
11665
|
+
const { halfX, ...plain } = box;
|
|
11666
|
+
const e = clockwiseEllipseBeziersBox(plain);
|
|
11666
11667
|
const out = [];
|
|
11667
11668
|
for (let i = e.length - 2; i >= 0; i -= 2) {
|
|
11668
11669
|
out.push(e[i], e[i + 1]);
|
|
11669
11670
|
}
|
|
11671
|
+
const odd = Math.abs(plain.exx) % 2;
|
|
11672
|
+
out[18] += odd;
|
|
11673
|
+
out[6] -= odd;
|
|
11674
|
+
if (halfX) {
|
|
11675
|
+
for (const k of [0, 1, 2, 3, 4, 5, 12]) {
|
|
11676
|
+
out[2 * k]++;
|
|
11677
|
+
}
|
|
11678
|
+
}
|
|
11670
11679
|
return out;
|
|
11671
11680
|
}
|
|
11672
11681
|
function clockwiseEllipseBeziersBox(box) {
|
|
@@ -11682,10 +11691,10 @@ function ellipsePoints(box, cwControls) {
|
|
|
11682
11691
|
const vMidHi = (v) => half(v, true);
|
|
11683
11692
|
const vCtl = (v) => Math.floor(v / 2) - Math.floor(KAPPA * Math.floor(v / 2));
|
|
11684
11693
|
const vCtlR = (v) => v - vCtl(v);
|
|
11685
|
-
const vDist = (v) => Math.ceil(KAPPA * Math.floor(v / 2));
|
|
11686
|
-
const rightUpper = cwControls ? (v) =>
|
|
11694
|
+
const vDist = (v) => v % 2 === 0 ? Math.ceil(KAPPA * Math.floor(v / 2)) : Math.floor(KAPPA * Math.ceil(v / 2));
|
|
11695
|
+
const rightUpper = cwControls ? (v) => vMidLo(v) - vDist(v) : vCtl;
|
|
11687
11696
|
const leftUpper = cwControls ? (v) => vMidLo(v) - vDist(v) : vCtl;
|
|
11688
|
-
const leftLower = cwControls ? (v) =>
|
|
11697
|
+
const leftLower = cwControls ? (v) => vMidHi(v) + vDist(v) : vCtlR;
|
|
11689
11698
|
const rightLower = cwControls ? (v) => vMidHi(v) + vDist(v) : vCtlR;
|
|
11690
11699
|
const zero = () => 0;
|
|
11691
11700
|
const full = (v) => v;
|
|
@@ -11927,7 +11936,7 @@ function unitPiece(from, to, small) {
|
|
|
11927
11936
|
}
|
|
11928
11937
|
return { start: p0, ctrl };
|
|
11929
11938
|
}
|
|
11930
|
-
function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
|
|
11939
|
+
function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise, halfX = false, framed = false) {
|
|
11931
11940
|
const w = r - l;
|
|
11932
11941
|
const h = b - t;
|
|
11933
11942
|
const Q = Math.PI / 2;
|
|
@@ -11947,11 +11956,25 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
|
|
|
11947
11956
|
} else {
|
|
11948
11957
|
while (a1 >= a0) a1 -= 2 * Math.PI;
|
|
11949
11958
|
}
|
|
11950
|
-
const px = (u) => Math.round(cx + rx * u);
|
|
11959
|
+
const px = (u, v) => clockwise && halfX ? Math.ceil(cx + rx * u + 0.5 - v) : Math.round(cx + rx * u + (halfX ? 1 + v : 0));
|
|
11951
11960
|
const py = (v) => Math.round(cy - ry * v);
|
|
11952
|
-
const
|
|
11961
|
+
const eb = axisBox(l, t, r, b);
|
|
11962
|
+
if (halfX) eb.halfX = true;
|
|
11963
|
+
const E = ellipseBeziersBox(eb);
|
|
11964
|
+
if (clockwise) {
|
|
11965
|
+
const cwPts = ellipseBeziersBox(eb, true);
|
|
11966
|
+
for (let i = 0; i < cwPts.length; i += 2) {
|
|
11967
|
+
E[cwPts.length - 2 - i] = cwPts[i];
|
|
11968
|
+
E[cwPts.length - 1 - i] = cwPts[i + 1];
|
|
11969
|
+
}
|
|
11970
|
+
}
|
|
11953
11971
|
const startUnit = small ? [Math.cos(a0), Math.sin(a0)] : polygonTrig(a0);
|
|
11954
|
-
const out = [px(startUnit[0]), py(startUnit[1])];
|
|
11972
|
+
const out = [px(startUnit[0], startUnit[1]), py(startUnit[1])];
|
|
11973
|
+
const onAxis = (angle2) => Math.abs(angle2 / Q - Math.round(angle2 / Q)) < 1e-9;
|
|
11974
|
+
const axisQuadrant = (angle2) => (Math.round(angle2 / Q) % 4 + 4) % 4;
|
|
11975
|
+
if (framed && onAxis(a0) && (s > 0 ? axisQuadrant(a0) === 1 || axisQuadrant(a0) === 2 : axisQuadrant(a0) === 2 || axisQuadrant(a0) === 3)) {
|
|
11976
|
+
out.push(out[0], out[1], out[0], out[1], out[0], out[1]);
|
|
11977
|
+
}
|
|
11955
11978
|
let a = a0;
|
|
11956
11979
|
for (let guard = 0; guard < 8 && (s > 0 ? a < a1 - 1e-12 : a > a1 + 1e-12); guard++) {
|
|
11957
11980
|
const next = s > 0 ? Math.floor(a / Q + 1e-9) * Q + Q : Math.ceil(a / Q - 1e-9) * Q - Q;
|
|
@@ -11973,10 +11996,16 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
|
|
|
11973
11996
|
const e = s > 0 ? Math.min(next, a1) : Math.max(next, a1);
|
|
11974
11997
|
const piece = unitPiece(a, e, small);
|
|
11975
11998
|
for (let i = 0; i < 6; i += 2) {
|
|
11976
|
-
out.push(px(piece.ctrl[i]), py(piece.ctrl[i + 1]));
|
|
11999
|
+
out.push(px(piece.ctrl[i], piece.ctrl[i + 1]), py(piece.ctrl[i + 1]));
|
|
11977
12000
|
}
|
|
11978
12001
|
a = e;
|
|
11979
12002
|
}
|
|
12003
|
+
if (framed && onAxis(a1) && (s > 0 ? axisQuadrant(a1) === 3 || axisQuadrant(a1) === 0 : axisQuadrant(a1) === 1 || axisQuadrant(a1) === 0)) {
|
|
12004
|
+
const endUnit = polygonTrig(a1);
|
|
12005
|
+
const ex = px(endUnit[0], endUnit[1]);
|
|
12006
|
+
const ey = py(endUnit[1]);
|
|
12007
|
+
out.push(ex, ey, ex, ey, ex, ey);
|
|
12008
|
+
}
|
|
11980
12009
|
return out;
|
|
11981
12010
|
}
|
|
11982
12011
|
var GdiRasterPath = class {
|
|
@@ -29615,7 +29644,7 @@ var Outliner = class {
|
|
|
29615
29644
|
this.flush();
|
|
29616
29645
|
}
|
|
29617
29646
|
};
|
|
29618
|
-
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors) {
|
|
29647
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric) {
|
|
29619
29648
|
const out = [];
|
|
29620
29649
|
const dashes = [];
|
|
29621
29650
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29635,8 +29664,8 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
29635
29664
|
const [x0, y0] = P[i];
|
|
29636
29665
|
const [x1, y1] = P[i + 1];
|
|
29637
29666
|
const dir = [x1 - x0, y1 - y0];
|
|
29638
|
-
const real = Math.hypot(dir[0], dir[1]);
|
|
29639
|
-
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]);
|
|
29640
29669
|
if (len === 0) {
|
|
29641
29670
|
if (on && cur) {
|
|
29642
29671
|
cur.pts.push(P[i + 1]);
|
|
@@ -29709,10 +29738,10 @@ function widenPath(path, opts) {
|
|
|
29709
29738
|
}
|
|
29710
29739
|
if (dashed) {
|
|
29711
29740
|
const run = closed ? [...P, P[0]] : P;
|
|
29712
|
-
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.width;
|
|
29741
|
+
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.dashMetric ? opts.width / opts.dashMetric[0] : opts.width;
|
|
29713
29742
|
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29714
29743
|
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29715
|
-
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors)) {
|
|
29744
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors, opts.dashMetric)) {
|
|
29716
29745
|
const pts = [piece.pts[0]];
|
|
29717
29746
|
const pdirs = [];
|
|
29718
29747
|
const pdraws = [];
|
|
@@ -29794,6 +29823,10 @@ function flipBox(box) {
|
|
|
29794
29823
|
}
|
|
29795
29824
|
function rectRasterPath(box, clockwise = false) {
|
|
29796
29825
|
const c = boxCorners(clockwise ? flipBox(box) : box);
|
|
29826
|
+
if (box.halfXRect) {
|
|
29827
|
+
c[4]--;
|
|
29828
|
+
c[6]--;
|
|
29829
|
+
}
|
|
29797
29830
|
const path = new GdiRasterPath();
|
|
29798
29831
|
path.moveTo(c[0], c[1]);
|
|
29799
29832
|
path.lineTo(c[2], c[3]);
|
|
@@ -29840,8 +29873,49 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = fal
|
|
|
29840
29873
|
pts.push(...map(q[i], clockwise ? f.t + f.b - q[i + 1] : q[i + 1]));
|
|
29841
29874
|
}
|
|
29842
29875
|
if (box.halfX) {
|
|
29843
|
-
|
|
29844
|
-
|
|
29876
|
+
if (box.halfXCompat || !clockwise) {
|
|
29877
|
+
const cy = (f.t + f.b) / 2;
|
|
29878
|
+
const ry = (f.b - f.t) / 2 || 1;
|
|
29879
|
+
for (let k = 0; k < 16; k++) {
|
|
29880
|
+
const v = (cy - pts[2 * k + 1]) / ry;
|
|
29881
|
+
pts[2 * k] += k >= 8 ? Math.round(1 + v) : Math.ceil(v - 0.5);
|
|
29882
|
+
}
|
|
29883
|
+
} else {
|
|
29884
|
+
const tall = box.cornerExact !== void 0 && box.cornerExact[1] * 2 >= Math.abs(box.eyy) - 1e-9;
|
|
29885
|
+
for (const k of tall ? [1, 2, 3, 4, 5, 6, 8, 15] : [0, 1, 2, 3, 4, 5, 6, 7]) {
|
|
29886
|
+
pts[2 * k]++;
|
|
29887
|
+
}
|
|
29888
|
+
}
|
|
29889
|
+
}
|
|
29890
|
+
if (box.cornerExact && isAxisBox(box)) {
|
|
29891
|
+
const w = f.r - f.l;
|
|
29892
|
+
const h = f.b - f.t;
|
|
29893
|
+
if (w >= 0 && h >= 0) {
|
|
29894
|
+
const hx = w === 0 ? 0 : Math.round(box.cornerExact[0] * (w + w % 2) / w / 2);
|
|
29895
|
+
const hy = h === 0 ? 0 : Math.round(box.cornerExact[1] * (clockwise ? h + h % 2 : h - h % 2) / h / 2);
|
|
29896
|
+
const hc = Math.ceil(KAPPA * hx);
|
|
29897
|
+
const vc = clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
|
|
29898
|
+
const set = (k, x, y) => {
|
|
29899
|
+
if (x !== null) pts[2 * k] = x;
|
|
29900
|
+
pts[2 * k + 1] = clockwise ? f.t + f.b - y : y;
|
|
29901
|
+
};
|
|
29902
|
+
const a = box.halfX ? 1 : 0;
|
|
29903
|
+
set(0, null, f.t + hy);
|
|
29904
|
+
set(1, null, f.t + hy - vc);
|
|
29905
|
+
set(2, f.r + a - hx + hc, f.t);
|
|
29906
|
+
set(3, f.r + a - hx, f.t);
|
|
29907
|
+
set(4, f.l + a + hx, f.t);
|
|
29908
|
+
set(5, f.l + a + hx - hc, f.t);
|
|
29909
|
+
set(6, null, f.t + hy - vc);
|
|
29910
|
+
set(7, null, f.t + hy);
|
|
29911
|
+
set(8, null, f.b - hy);
|
|
29912
|
+
set(9, null, f.b - hy + vc);
|
|
29913
|
+
set(10, f.l + hx - hc, f.b);
|
|
29914
|
+
set(11, f.l + hx, f.b);
|
|
29915
|
+
set(12, f.r - hx, f.b);
|
|
29916
|
+
set(13, f.r - hx + hc, f.b);
|
|
29917
|
+
set(14, null, f.b - hy + vc);
|
|
29918
|
+
set(15, null, f.b - hy);
|
|
29845
29919
|
}
|
|
29846
29920
|
}
|
|
29847
29921
|
return pts;
|
|
@@ -29884,7 +29958,7 @@ function arcRasterPath(box, s, e, clockwise, kind, from, path = new GdiRasterPat
|
|
|
29884
29958
|
cw = !cw;
|
|
29885
29959
|
}
|
|
29886
29960
|
}
|
|
29887
|
-
const bz = arcBeziers(f.l, f.t, f.r, f.b, sx, sy, ex, ey, cw);
|
|
29961
|
+
const bz = arcBeziers(f.l, f.t, f.r, f.b, sx, sy, ex, ey, cw, !!box.halfX, !!box.framed);
|
|
29888
29962
|
const pts = [];
|
|
29889
29963
|
for (let i = 0; i < bz.length; i += 2) {
|
|
29890
29964
|
pts.push(...map(bz[i], bz[i + 1]));
|
|
@@ -29898,7 +29972,7 @@ function arcRasterPath(box, s, e, clockwise, kind, from, path = new GdiRasterPat
|
|
|
29898
29972
|
if (kind === "pie") {
|
|
29899
29973
|
const w = f.r - f.l;
|
|
29900
29974
|
const h = f.b - f.t;
|
|
29901
|
-
const [cx, cy] = map(f.l + Math.ceil(w / 2), f.t + Math.ceil(h / 2));
|
|
29975
|
+
const [cx, cy] = map(f.l + Math.ceil(w / 2) + (box.halfX ? 1 : 0), f.t + Math.ceil(h / 2));
|
|
29902
29976
|
path.lineTo(cx, cy);
|
|
29903
29977
|
}
|
|
29904
29978
|
if (kind === "pie" || kind === "chord") {
|
|
@@ -29934,8 +30008,9 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
29934
30008
|
const widthPx = rCtx.wholeDevicePixels && (flags & 15) === 6 ? state.penWidth * Math.sqrt(Math.abs(matrix[0] * matrix[3] - matrix[1] * matrix[2])) : penDeviceWidth(rCtx);
|
|
29935
30009
|
const capBits = flags & 3840;
|
|
29936
30010
|
const joinBits = flags & 61440;
|
|
29937
|
-
const
|
|
29938
|
-
const
|
|
30011
|
+
const ellipse = !rCtx.wholeDevicePixels && state.penWidth * Math.abs(matrix[0]) * 16 >= 1 && state.penWidth * Math.abs(matrix[3]) * 16 >= 1 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6 && Math.abs(Math.abs(matrix[0]) - Math.abs(matrix[3])) > 1e-6;
|
|
30012
|
+
const dashes = state.penExtended ? ellipse ? geometricStyle(flags, state.penWidth, state.penUserStyle, 1) : geometricStyle(flags, widthPx, state.penUserStyle, widthPx / (state.penWidth || 1)) : null;
|
|
30013
|
+
const dashMetric = ellipse && dashes ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : void 0;
|
|
29939
30014
|
return {
|
|
29940
30015
|
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : widthPx) * 16),
|
|
29941
30016
|
...ellipse ? { height: Math.round(state.penWidth * Math.abs(matrix[3]) * 16) } : {},
|
|
@@ -29943,6 +30018,7 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
29943
30018
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
29944
30019
|
miterLimit: state.miterLimit ?? 10,
|
|
29945
30020
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
30021
|
+
...dashMetric ? { dashMetric } : {},
|
|
29946
30022
|
shortenDashes: (flags & 15) !== 7,
|
|
29947
30023
|
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
29948
30024
|
// segments in whole pixels.
|
|
@@ -30955,9 +31031,24 @@ function insideFrameInset(rCtx, box, rectangle = false, clockwiseRoundRect = fal
|
|
|
30955
31031
|
right: Math.round((rectangle ? lo : hi) * px),
|
|
30956
31032
|
top: y,
|
|
30957
31033
|
bottom: y,
|
|
30958
|
-
half: wx % 2 === 1 && !rectangle
|
|
31034
|
+
half: wx % 2 === 1 && !rectangle,
|
|
31035
|
+
halfRect: wx % 2 === 1 && rectangle
|
|
30959
31036
|
};
|
|
30960
31037
|
}
|
|
31038
|
+
function insideFramePenTooWide(rCtx, box) {
|
|
31039
|
+
if ((rCtx.state.penStyle & 15) !== PS_INSIDEFRAME || !isAxisBox(box) || hasWorldRotation(rCtx)) {
|
|
31040
|
+
return false;
|
|
31041
|
+
}
|
|
31042
|
+
const m = gdiDeviceMatrix(rCtx);
|
|
31043
|
+
const px = gdiDevicePixelX(rCtx);
|
|
31044
|
+
const py = gdiDevicePixelY(rCtx);
|
|
31045
|
+
const widthX = Math.abs(rCtx.state.penWidth * m[0]) / px * 16;
|
|
31046
|
+
const widthY = Math.abs(rCtx.state.penWidth * m[3]) / py * 16;
|
|
31047
|
+
if (Math.max(widthX, widthY) < 24) {
|
|
31048
|
+
return false;
|
|
31049
|
+
}
|
|
31050
|
+
return Math.abs(box.exx) / px < Math.round(widthX) || Math.abs(box.eyy) / py < Math.round(widthY);
|
|
31051
|
+
}
|
|
30961
31052
|
function insetFixBox(box, inset) {
|
|
30962
31053
|
const sx = box.exx < 0 ? -1 : 1;
|
|
30963
31054
|
const sy = box.eyy < 0 ? -1 : 1;
|
|
@@ -30967,11 +31058,15 @@ function insetFixBox(box, inset) {
|
|
|
30967
31058
|
exx: box.exx - sx * (inset.left + inset.right),
|
|
30968
31059
|
exy: 0,
|
|
30969
31060
|
eyx: 0,
|
|
30970
|
-
eyy: box.eyy - sy * (inset.top + inset.bottom)
|
|
31061
|
+
eyy: box.eyy - sy * (inset.top + inset.bottom),
|
|
31062
|
+
framed: true
|
|
30971
31063
|
};
|
|
30972
31064
|
if (inset.half && sx > 0) {
|
|
30973
31065
|
framed.halfX = true;
|
|
30974
31066
|
}
|
|
31067
|
+
if (inset.halfRect && sx > 0) {
|
|
31068
|
+
framed.halfXRect = true;
|
|
31069
|
+
}
|
|
30975
31070
|
return framed;
|
|
30976
31071
|
}
|
|
30977
31072
|
function sameEllipseRay(l, t, r, b, sx, sy, ex, ey) {
|
|
@@ -31054,7 +31149,7 @@ function handleRectangle(rCtx, dataOff, recSize) {
|
|
|
31054
31149
|
const r = view.getInt32(dataOff + 8, true);
|
|
31055
31150
|
const b = view.getInt32(dataOff + 12, true);
|
|
31056
31151
|
const unframed = uprightFixBox(rCtx, l, t, r, b);
|
|
31057
|
-
const inset = insideFrameInset(rCtx, unframed, true);
|
|
31152
|
+
const inset = insideFrameInset(rCtx, unframed, true, rCtx.state.arcDirection === 2);
|
|
31058
31153
|
const box = inset ? insetFixBox(unframed, inset) : unframed;
|
|
31059
31154
|
const clockwise = rCtx.state.arcDirection === 2;
|
|
31060
31155
|
if (!inPath) {
|
|
@@ -31240,6 +31335,13 @@ function handleRoundRect(rCtx, dataOff, recSize) {
|
|
|
31240
31335
|
gmh(rCtx, cornerH) / 2,
|
|
31241
31336
|
null
|
|
31242
31337
|
);
|
|
31338
|
+
if (inset) {
|
|
31339
|
+
const fullW = Math.abs((r - l) * devM[0]) * 16;
|
|
31340
|
+
const fullH = Math.abs((b - t) * devM[3]) * 16;
|
|
31341
|
+
if (fullW > 0 && fullH > 0) {
|
|
31342
|
+
framed.cornerExact = [Math.min(cornerFixW, fullW) * Math.abs(framed.exx) / fullW, Math.min(cornerFixH, fullH) * Math.abs(framed.eyy) / fullH];
|
|
31343
|
+
}
|
|
31344
|
+
}
|
|
31243
31345
|
const raster = (box = framed) => roundRectRasterPath(box, cw, ch, clockwise, cornerW === 0 || cornerH === 0);
|
|
31244
31346
|
if (inPath) {
|
|
31245
31347
|
const box = framed;
|
|
@@ -31293,7 +31395,7 @@ function handleEllipse(rCtx, dataOff, recSize) {
|
|
|
31293
31395
|
const b = view.getInt32(dataOff + 12, true);
|
|
31294
31396
|
const clockwise = rCtx.state.arcDirection === 2;
|
|
31295
31397
|
const unframed = uprightFixBox(rCtx, l, t, r, b);
|
|
31296
|
-
const inset = insideFrameInset(rCtx, unframed);
|
|
31398
|
+
const inset = insideFrameInset(rCtx, unframed, false, rCtx.state.arcDirection === 2);
|
|
31297
31399
|
const framed = inset ? insetFixBox(unframed, inset) : unframed;
|
|
31298
31400
|
const params = inset ? { cx: (framed.ax + framed.exx / 2) / 16, cy: (framed.ay + framed.eyy / 2) / 16, rx: Math.abs(framed.exx) / 32, ry: Math.abs(framed.eyy) / 32, rotation: 0 } : hasWorldRotation(rCtx) ? gdiEllipseParams(rCtx, (l + r) / 2, (t + b) / 2, Math.abs(r - l) / 2, Math.abs(b - t) / 2) : {
|
|
31299
31401
|
cx: gmx(rCtx, (l + r) / 2),
|
|
@@ -31343,7 +31445,10 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
|
|
|
31343
31445
|
const endAngle = fullEllipse ? startAngle + (clockwise ? 2 : -2) * Math.PI : Math.atan2((endY - cyA) / (ry || 1), (endX - cxA) / (rx || 1));
|
|
31344
31446
|
const rotated = hasWorldRotation(rCtx);
|
|
31345
31447
|
const unframed = fixBox(rCtx, l, t, r, b);
|
|
31346
|
-
|
|
31448
|
+
if (recType !== EMR_ARCTO && insideFramePenTooWide(rCtx, unframed)) {
|
|
31449
|
+
return true;
|
|
31450
|
+
}
|
|
31451
|
+
const inset = insideFrameInset(rCtx, unframed, false, rCtx.state.arcDirection === 2);
|
|
31347
31452
|
const framed = inset ? insetFixBox(unframed, inset) : unframed;
|
|
31348
31453
|
const params = inset ? { cx: (framed.ax + framed.exx / 2) / 16, cy: (framed.ay + framed.eyy / 2) / 16, rx: Math.abs(framed.exx) / 32, ry: Math.abs(framed.eyy) / 32, rotation: 0 } : rotated ? gdiEllipseParams(rCtx, cxA, cyA, rx, ry) : {
|
|
31349
31454
|
cx: gmx(rCtx, cxA),
|
|
@@ -31374,20 +31479,25 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
|
|
|
31374
31479
|
}
|
|
31375
31480
|
};
|
|
31376
31481
|
const kind = isArcTo ? "arcto" : recType === EMR_PIE ? "pie" : recType === EMR_CHORD ? "chord" : "arc";
|
|
31377
|
-
const
|
|
31482
|
+
const devM = gdiDeviceMatrix(rCtx);
|
|
31483
|
+
const rawFix = (x, y) => [(devM[0] * x + devM[2] * y + devM[4]) * 16, (devM[1] * x + devM[3] * y + devM[5]) * 16];
|
|
31484
|
+
const radialOnBox = (p, raw) => {
|
|
31378
31485
|
if (!inset) {
|
|
31379
31486
|
return p;
|
|
31380
31487
|
}
|
|
31381
|
-
const
|
|
31382
|
-
const
|
|
31383
|
-
|
|
31488
|
+
const [rl, rt] = rawFix(l, t);
|
|
31489
|
+
const [rr, rb] = rawFix(r, b);
|
|
31490
|
+
const kx = rr !== rl ? framed.exx / (rr - rl) : 1;
|
|
31491
|
+
const ky = rb !== rt ? framed.eyy / (rb - rt) : 1;
|
|
31492
|
+
const snap = (v) => Math.abs(v) < 1e-6 ? 0 : v;
|
|
31493
|
+
return [framed.ax + framed.exx / 2 + snap(raw[0] - (rl + rr) / 2) * kx, framed.ay + framed.eyy / 2 + snap(raw[1] - (rt + rb) / 2) * ky];
|
|
31384
31494
|
};
|
|
31385
31495
|
const rasterArgs = (immediate = false) => ({
|
|
31386
31496
|
box: inset ? framed : immediate && needsFill ? curvedFixBox(rCtx, l, t, r, b) : unframed,
|
|
31387
|
-
s: radialOnBox(fixPoint(rCtx, startX, startY)),
|
|
31497
|
+
s: radialOnBox(fixPoint(rCtx, startX, startY), rawFix(startX, startY)),
|
|
31388
31498
|
// Device FIX rounding can separate distinct radial points on the
|
|
31389
31499
|
// same logical ray. Preserve their proven endpoint identity.
|
|
31390
|
-
e: fullEllipse ? radialOnBox(fixPoint(rCtx, startX, startY)) : radialOnBox(fixPoint(rCtx, endX, endY)),
|
|
31500
|
+
e: fullEllipse ? radialOnBox(fixPoint(rCtx, startX, startY), rawFix(startX, startY)) : radialOnBox(fixPoint(rCtx, endX, endY), rawFix(endX, endY)),
|
|
31391
31501
|
from: currentFix(rCtx)
|
|
31392
31502
|
});
|
|
31393
31503
|
if (inPath) {
|
|
@@ -39684,6 +39794,7 @@ function compatBox(p, l, t, r, b, opts = {}) {
|
|
|
39684
39794
|
if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME2) {
|
|
39685
39795
|
const w = Math.round(penDeviceWidth(p.rCtx) / p.kx);
|
|
39686
39796
|
if (w > 1) {
|
|
39797
|
+
const whole = { ...box };
|
|
39687
39798
|
const matrix = gdiDeviceMatrix(p.rCtx);
|
|
39688
39799
|
const wx = Math.round(Math.abs(p.rCtx.state.penWidth * matrix[0]) / p.kx * 16);
|
|
39689
39800
|
const wy = Math.round(Math.abs(p.rCtx.state.penWidth * matrix[3]) / p.ky * 16);
|
|
@@ -39697,14 +39808,21 @@ function compatBox(p, l, t, r, b, opts = {}) {
|
|
|
39697
39808
|
if (half) {
|
|
39698
39809
|
box.halfX = true;
|
|
39699
39810
|
}
|
|
39811
|
+
if (opts.clampEmpty && (box.x1 < box.x0 || box.y1 < box.y0)) {
|
|
39812
|
+
return { x0: whole.x0, y0: whole.y0, x1: whole.x1 + Math.round(ux), y1: whole.y1 + Math.round(uy) };
|
|
39813
|
+
}
|
|
39700
39814
|
}
|
|
39701
39815
|
}
|
|
39702
39816
|
return box;
|
|
39703
39817
|
}
|
|
39704
|
-
function fixBoxOf(box) {
|
|
39705
|
-
const fix = axisBox(box.x0, box.y0, Math.max(box.x0, box.x1), Math.max(box.y0, box.y1));
|
|
39818
|
+
function fixBoxOf(box, cornerExact, keepInverted = false) {
|
|
39819
|
+
const fix = keepInverted ? axisBox(box.x0, box.y0, box.x1, box.y1) : axisBox(box.x0, box.y0, Math.max(box.x0, box.x1), Math.max(box.y0, box.y1));
|
|
39706
39820
|
if (box.halfX) {
|
|
39707
39821
|
fix.halfX = true;
|
|
39822
|
+
fix.halfXCompat = true;
|
|
39823
|
+
}
|
|
39824
|
+
if (cornerExact) {
|
|
39825
|
+
fix.cornerExact = cornerExact;
|
|
39708
39826
|
}
|
|
39709
39827
|
return fix;
|
|
39710
39828
|
}
|
|
@@ -39768,7 +39886,8 @@ function compatCorner(p, w, h, box, logical) {
|
|
|
39768
39886
|
const width2 = box.x1 - box.x0, height2 = box.y1 - box.y0;
|
|
39769
39887
|
const fullW2 = Math.abs((logical[2] - logical[0]) * m[0]) * 16 || width2;
|
|
39770
39888
|
const fullH2 = Math.abs((logical[3] - logical[1]) * m[3]) * 16 || height2;
|
|
39771
|
-
|
|
39889
|
+
const cornerW = Math.min(Math.abs(w * m[0]) * 16, fullW2) * width2 / fullW2;
|
|
39890
|
+
return [Math.floor(cornerW), Math.floor(Math.min(Math.abs(h * m[3]) * 16, fullH2) * height2 / fullH2), [cornerW, Math.min(Math.abs(h * m[3]) * 16, fullH2) * height2 / fullH2]];
|
|
39772
39891
|
}
|
|
39773
39892
|
const width = box.x1 - box.x0, height = box.y1 - box.y0;
|
|
39774
39893
|
const fullW = Math.abs((logical[2] - logical[0]) * m[0]) * 16 || width + ux;
|
|
@@ -39777,11 +39896,11 @@ function compatCorner(p, w, h, box, logical) {
|
|
|
39777
39896
|
return penIsCosmetic(p.rCtx) && !penIsNull(p) ? scaled2 : [Math.floor(scaled2[0]), Math.floor(scaled2[1])];
|
|
39778
39897
|
}
|
|
39779
39898
|
function wmfRoundRect(p, l, t, r, b, w, h) {
|
|
39780
|
-
const box = compatBox(p, l, t, r, b, { curved: true, half: true });
|
|
39899
|
+
const box = compatBox(p, l, t, r, b, { curved: true, half: true, clampEmpty: true });
|
|
39781
39900
|
if (box.x1 < box.x0 || box.y1 < box.y0) {
|
|
39782
39901
|
return;
|
|
39783
39902
|
}
|
|
39784
|
-
const [cw, ch] = compatCorner(p, w, h, box, [l, t, r, b]);
|
|
39903
|
+
const [cw, ch, half] = compatCorner(p, w, h, box, [l, t, r, b]);
|
|
39785
39904
|
const cr = canvasRect(box);
|
|
39786
39905
|
paintGdiShape(p.rCtx, {
|
|
39787
39906
|
build: (c) => {
|
|
@@ -39806,14 +39925,14 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
|
|
|
39806
39925
|
c.ellipse(cr.x + ex, cr.y + ey, ex, ey, 0, 2 * q, 3 * q);
|
|
39807
39926
|
c.closePath();
|
|
39808
39927
|
},
|
|
39809
|
-
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, !penIsNull(p) && penIsCosmetic(p.rCtx)),
|
|
39928
|
+
raster: () => roundRectRasterPath(fixBoxOf(box, half), cw, ch, clockwiseOf(p), w === 0 || h === 0, !penIsNull(p) && penIsCosmetic(p.rCtx)),
|
|
39810
39929
|
roundPen: true,
|
|
39811
39930
|
fill: true,
|
|
39812
39931
|
stroke: true
|
|
39813
39932
|
});
|
|
39814
39933
|
}
|
|
39815
39934
|
function wmfEllipse(p, l, t, r, b) {
|
|
39816
|
-
const box = compatBox(p, l, t, r, b, { curved: true, half: true });
|
|
39935
|
+
const box = compatBox(p, l, t, r, b, { curved: true, half: true, clampEmpty: true });
|
|
39817
39936
|
if (box.x1 < box.x0 || box.y1 < box.y0) {
|
|
39818
39937
|
return;
|
|
39819
39938
|
}
|
|
@@ -39829,9 +39948,9 @@ function wmfEllipse(p, l, t, r, b) {
|
|
|
39829
39948
|
stroke: true
|
|
39830
39949
|
});
|
|
39831
39950
|
}
|
|
39832
|
-
function compatArc(p, kind, l, t, r, b, xs, ys, xe, ye) {
|
|
39833
|
-
const box = compatBox(p, l, t, r, b, { curved: kind === "chord" || kind === "pie", roundFrame: true });
|
|
39834
|
-
if (box.
|
|
39951
|
+
function compatArc(p, kind, l, t, r, b, xs, ys, xe, ye, keepInverted = false) {
|
|
39952
|
+
const box = compatBox(p, l, t, r, b, { curved: kind === "chord" || kind === "pie", roundFrame: true, half: true });
|
|
39953
|
+
if (box.y1 < box.y0 || !keepInverted && box.x1 < box.x0) {
|
|
39835
39954
|
return null;
|
|
39836
39955
|
}
|
|
39837
39956
|
const m = gdiDeviceMatrix(p.rCtx);
|