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