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