emf-converter 4.3.1 → 4.3.3
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 +3 -3
- package/dist/index.js +448 -144
- package/dist/index.mjs +448 -144
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1737,7 +1737,21 @@ var KAPPA = 0.5522847498307936;
|
|
|
1737
1737
|
function axisBox(l, t, r, b) {
|
|
1738
1738
|
return { ax: l, ay: t, exx: r - l, exy: 0, eyx: 0, eyy: b - t };
|
|
1739
1739
|
}
|
|
1740
|
-
function ellipseBeziersBox(box) {
|
|
1740
|
+
function ellipseBeziersBox(box, clockwise = false) {
|
|
1741
|
+
if (!clockwise) {
|
|
1742
|
+
return ellipsePoints(box, false);
|
|
1743
|
+
}
|
|
1744
|
+
const e = clockwiseEllipseBeziersBox(box);
|
|
1745
|
+
const out = [];
|
|
1746
|
+
for (let i = e.length - 2; i >= 0; i -= 2) {
|
|
1747
|
+
out.push(e[i], e[i + 1]);
|
|
1748
|
+
}
|
|
1749
|
+
return out;
|
|
1750
|
+
}
|
|
1751
|
+
function clockwiseEllipseBeziersBox(box) {
|
|
1752
|
+
return ellipsePoints(box, true);
|
|
1753
|
+
}
|
|
1754
|
+
function ellipsePoints(box, cwControls) {
|
|
1741
1755
|
const half = (v, up) => up ? Math.ceil(v / 2) : Math.floor(v / 2);
|
|
1742
1756
|
const hMidLo = (v) => half(v, false);
|
|
1743
1757
|
const hMidHi = (v) => half(v, true);
|
|
@@ -1747,6 +1761,11 @@ function ellipseBeziersBox(box) {
|
|
|
1747
1761
|
const vMidHi = (v) => half(v, true);
|
|
1748
1762
|
const vCtl = (v) => Math.floor(v / 2) - Math.floor(KAPPA * Math.floor(v / 2));
|
|
1749
1763
|
const vCtlR = (v) => v - vCtl(v);
|
|
1764
|
+
const vDist = (v) => Math.ceil(KAPPA * Math.floor(v / 2));
|
|
1765
|
+
const rightUpper = cwControls ? (v) => vMidHi(v) - vDist(v) : vCtl;
|
|
1766
|
+
const leftUpper = cwControls ? (v) => vMidLo(v) - vDist(v) : vCtl;
|
|
1767
|
+
const leftLower = cwControls ? (v) => vMidLo(v) + vDist(v) : vCtlR;
|
|
1768
|
+
const rightLower = cwControls ? (v) => vMidHi(v) + vDist(v) : vCtlR;
|
|
1750
1769
|
const zero = () => 0;
|
|
1751
1770
|
const full = (v) => v;
|
|
1752
1771
|
const { ax, ay, exx, exy, eyx, eyy } = box;
|
|
@@ -1755,17 +1774,17 @@ function ellipseBeziersBox(box) {
|
|
|
1755
1774
|
out.push(ax + gx(exx) + gy(eyx), ay + gx(exy) + gy(eyy));
|
|
1756
1775
|
};
|
|
1757
1776
|
P(full, vMidHi);
|
|
1758
|
-
P(full,
|
|
1777
|
+
P(full, rightUpper);
|
|
1759
1778
|
P(hCtl, zero);
|
|
1760
1779
|
P(hMidLo, zero);
|
|
1761
1780
|
P(hCtl2, zero);
|
|
1762
|
-
P(zero,
|
|
1781
|
+
P(zero, leftUpper);
|
|
1763
1782
|
P(zero, vMidLo);
|
|
1764
|
-
P(zero,
|
|
1783
|
+
P(zero, leftLower);
|
|
1765
1784
|
P(hCtl2, full);
|
|
1766
1785
|
P(hMidHi, full);
|
|
1767
1786
|
P(hCtl, full);
|
|
1768
|
-
P(full,
|
|
1787
|
+
P(full, rightLower);
|
|
1769
1788
|
P(full, vMidHi);
|
|
1770
1789
|
return out;
|
|
1771
1790
|
}
|
|
@@ -1782,8 +1801,12 @@ function flattenBezierPath(pts) {
|
|
|
1782
1801
|
function roundRectCorners(l, t, r, b, cw, ch) {
|
|
1783
1802
|
const w = r - l;
|
|
1784
1803
|
const h = b - t;
|
|
1785
|
-
|
|
1786
|
-
|
|
1804
|
+
let ew = Math.min(Math.abs(cw), w);
|
|
1805
|
+
let eh = Math.min(Math.abs(ch), h);
|
|
1806
|
+
if (ew === 0 || eh === 0) {
|
|
1807
|
+
ew = 0;
|
|
1808
|
+
eh = 0;
|
|
1809
|
+
}
|
|
1787
1810
|
const hy = Math.floor(h / 2) - Math.floor((h - eh) / 2);
|
|
1788
1811
|
const topX = Math.floor(r - ew / 2);
|
|
1789
1812
|
const hx = r - topX;
|
|
@@ -1892,12 +1915,7 @@ function angleArcFix(box, startDeg, sweepDeg) {
|
|
|
1892
1915
|
const cx = l + w / 2;
|
|
1893
1916
|
const cy = t + h / 2;
|
|
1894
1917
|
const E = ellipseBeziers(l, t, l + w, t + h);
|
|
1895
|
-
const Ecw =
|
|
1896
|
-
const d = Math.ceil(KAPPA * Math.floor(h / 2));
|
|
1897
|
-
Ecw[3] = Ecw[1] - d;
|
|
1898
|
-
Ecw[11] = Ecw[13] - d;
|
|
1899
|
-
Ecw[15] = Ecw[13] + d;
|
|
1900
|
-
Ecw[23] = Ecw[1] + d;
|
|
1918
|
+
const Ecw = clockwiseEllipseBeziersBox(axisBox(l, t, l + w, t + h));
|
|
1901
1919
|
const start = startDeg * Math.PI / 180;
|
|
1902
1920
|
const out = [Math.round(cx + w / 2 * tableCos(start)), Math.round(cy - h / 2 * tableSin(start))];
|
|
1903
1921
|
for (const p of angleArcPieces(startDeg, sweepDeg)) {
|
|
@@ -1939,15 +1957,7 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
|
|
|
1939
1957
|
}
|
|
1940
1958
|
const px = (a2) => cx + rx * tableCos(a2);
|
|
1941
1959
|
const py = (a2) => cy - ry * tableSin(a2);
|
|
1942
|
-
const E = ellipseBeziers(l, t, r, b);
|
|
1943
|
-
if (clockwise) {
|
|
1944
|
-
const fh = Math.floor((b - t) / 2);
|
|
1945
|
-
const d = Math.ceil(KAPPA * fh);
|
|
1946
|
-
E[3] = E[1] - d;
|
|
1947
|
-
E[11] = E[13] - d;
|
|
1948
|
-
E[15] = E[13] + d;
|
|
1949
|
-
E[23] = E[1] + d;
|
|
1950
|
-
}
|
|
1960
|
+
const E = clockwise ? clockwiseEllipseBeziersBox(axisBox(l, t, r, b)) : ellipseBeziers(l, t, r, b);
|
|
1951
1961
|
const out = [Math.round(px(a0)), Math.round(py(a0))];
|
|
1952
1962
|
let a = a0;
|
|
1953
1963
|
for (let guard = 0; guard < 8 && (s > 0 ? a < a1 - 1e-12 : a > a1 + 1e-12); guard++) {
|
|
@@ -1980,12 +1990,45 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
|
|
|
1980
1990
|
var GdiRasterPath = class {
|
|
1981
1991
|
constructor() {
|
|
1982
1992
|
this.figures = [];
|
|
1993
|
+
/**
|
|
1994
|
+
* The path as `GetPath` reports it, before flattening: FIX points
|
|
1995
|
+
* (`[x0, y0, ...]`) and their `PT_*` types (`PT_MOVETO` 6, `PT_LINETO`
|
|
1996
|
+
* 2, `PT_BEZIERTO` 4, `PT_CLOSEFIGURE` 1 or-ed onto a figure's last
|
|
1997
|
+
* point). Used to check the geometry against Windows' own paths.
|
|
1998
|
+
*/
|
|
1999
|
+
this.getPath = { pts: [], types: [] };
|
|
1983
2000
|
this.current = null;
|
|
1984
2001
|
}
|
|
1985
2002
|
/** Starts a new figure at (`x`, `y`). */
|
|
1986
2003
|
moveTo(x, y) {
|
|
1987
2004
|
this.current = { pts: [x, y], closed: false };
|
|
1988
2005
|
this.figures.push(this.current);
|
|
2006
|
+
this.log(x, y, 6);
|
|
2007
|
+
}
|
|
2008
|
+
/**
|
|
2009
|
+
* Starts a new figure at the current position (`x`, `y`) unless the open
|
|
2010
|
+
* figure already ends there. GDI opens a new figure for a drawing call
|
|
2011
|
+
* that continues from the current position (`LineTo`, `PolylineTo`,
|
|
2012
|
+
* `ArcTo`, ...) when the path is empty, its last figure is closed, or
|
|
2013
|
+
* the current position has moved away from the path's last point (a
|
|
2014
|
+
* `MoveTo`, or a call such as `Polyline`, `Arc` or `PolyPolygon` that
|
|
2015
|
+
* adds to the path without moving the current position; Windows'
|
|
2016
|
+
* `GetPath`, Wine `gdi32/tests/path.c`, `test_all_functions`).
|
|
2017
|
+
*/
|
|
2018
|
+
continueAt(x, y) {
|
|
2019
|
+
const f = this.current;
|
|
2020
|
+
if (f && f.pts[f.pts.length - 2] === x && f.pts[f.pts.length - 1] === y) {
|
|
2021
|
+
return;
|
|
2022
|
+
}
|
|
2023
|
+
this.moveTo(x, y);
|
|
2024
|
+
}
|
|
2025
|
+
/** True when a figure is open (not closed and not ended by an appended path). */
|
|
2026
|
+
hasOpenFigure() {
|
|
2027
|
+
return this.current !== null;
|
|
2028
|
+
}
|
|
2029
|
+
log(x, y, type) {
|
|
2030
|
+
this.getPath.pts.push(x, y);
|
|
2031
|
+
this.getPath.types.push(type);
|
|
1989
2032
|
}
|
|
1990
2033
|
/** Adds a line to (`x`, `y`), starting a figure there when none is open. */
|
|
1991
2034
|
lineTo(x, y) {
|
|
@@ -1994,6 +2037,7 @@ var GdiRasterPath = class {
|
|
|
1994
2037
|
this.moveTo(last ? last[0] : x, last ? last[1] : y);
|
|
1995
2038
|
}
|
|
1996
2039
|
this.current.pts.push(x, y);
|
|
2040
|
+
this.log(x, y, 2);
|
|
1997
2041
|
}
|
|
1998
2042
|
/** Adds a cubic Bezier from the current point. */
|
|
1999
2043
|
bezierTo(c1x, c1y, c2x, c2y, x, y) {
|
|
@@ -2003,6 +2047,9 @@ var GdiRasterPath = class {
|
|
|
2003
2047
|
}
|
|
2004
2048
|
const p = this.current.pts;
|
|
2005
2049
|
this.flattenInto(p[p.length - 2], p[p.length - 1], c1x, c1y, c2x, c2y, x, y);
|
|
2050
|
+
this.log(c1x, c1y, 4);
|
|
2051
|
+
this.log(c2x, c2y, 4);
|
|
2052
|
+
this.log(x, y, 4);
|
|
2006
2053
|
}
|
|
2007
2054
|
/** Flattens one Bezier onto the open figure, recording its end tangents. */
|
|
2008
2055
|
flattenInto(x0, y0, c1x, c1y, c2x, c2y, x3, y3) {
|
|
@@ -2037,6 +2084,9 @@ var GdiRasterPath = class {
|
|
|
2037
2084
|
}
|
|
2038
2085
|
for (let i = 2; i + 5 < pts.length; i += 6) {
|
|
2039
2086
|
this.flattenInto(pts[i - 2], pts[i - 1], pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5]);
|
|
2087
|
+
for (let k = i; k < i + 6; k += 2) {
|
|
2088
|
+
this.log(pts[k], pts[k + 1], 4);
|
|
2089
|
+
}
|
|
2040
2090
|
}
|
|
2041
2091
|
}
|
|
2042
2092
|
/** Closes the open figure (the next drawing call starts a new one). */
|
|
@@ -2044,6 +2094,8 @@ var GdiRasterPath = class {
|
|
|
2044
2094
|
if (this.current) {
|
|
2045
2095
|
this.current.closed = true;
|
|
2046
2096
|
this.current = null;
|
|
2097
|
+
const t = this.getPath.types;
|
|
2098
|
+
t[t.length - 1] |= 1;
|
|
2047
2099
|
}
|
|
2048
2100
|
}
|
|
2049
2101
|
/** Appends every figure of `other`. */
|
|
@@ -2051,6 +2103,9 @@ var GdiRasterPath = class {
|
|
|
2051
2103
|
for (const f of other.figures) {
|
|
2052
2104
|
this.figures.push({ pts: f.pts.slice(), closed: f.closed, tangents: f.tangents && new Map(f.tangents) });
|
|
2053
2105
|
}
|
|
2106
|
+
for (let i = 0; i < other.getPath.types.length; i++) {
|
|
2107
|
+
this.log(other.getPath.pts[2 * i], other.getPath.pts[2 * i + 1], other.getPath.types[i]);
|
|
2108
|
+
}
|
|
2054
2109
|
this.current = null;
|
|
2055
2110
|
}
|
|
2056
2111
|
lastPoint() {
|
|
@@ -12647,7 +12702,10 @@ function dashFigure(pts, closed, pen) {
|
|
|
12647
12702
|
for (let i = 0; i + 1 < path.length; i++) {
|
|
12648
12703
|
const a = path[i];
|
|
12649
12704
|
const b = path[i + 1];
|
|
12650
|
-
|
|
12705
|
+
const m = pen.dashMetric;
|
|
12706
|
+
const vx = b.x - a.x;
|
|
12707
|
+
const vy = b.y - a.y;
|
|
12708
|
+
let segLen = m ? Math.hypot(m[0] * vx + m[2] * vy, m[1] * vx + m[3] * vy) : Math.hypot(vx, vy);
|
|
12651
12709
|
let t0 = 0;
|
|
12652
12710
|
while (segLen - t0 > remaining + 1e-9) {
|
|
12653
12711
|
t0 += remaining;
|
|
@@ -12675,6 +12733,26 @@ function dashFigure(pts, closed, pen) {
|
|
|
12675
12733
|
}
|
|
12676
12734
|
return out.filter((d) => d.pts.length > 1);
|
|
12677
12735
|
}
|
|
12736
|
+
var ARROW_ANCHOR = 20;
|
|
12737
|
+
function arrowAnchor(pp, atEnd, half) {
|
|
12738
|
+
const w = 2 * half;
|
|
12739
|
+
const tip = atEnd ? pp[pp.length - 1] : pp[0];
|
|
12740
|
+
const next = atEnd ? pp[pp.length - 2] : pp[1];
|
|
12741
|
+
const len = Math.hypot(next.x - tip.x, next.y - tip.y);
|
|
12742
|
+
const ux = (next.x - tip.x) / len;
|
|
12743
|
+
const uy = (next.y - tip.y) / len;
|
|
12744
|
+
const depth = 2 * w;
|
|
12745
|
+
const across = 2 * w / Math.sqrt(3);
|
|
12746
|
+
const base = { x: tip.x + ux * depth, y: tip.y + uy * depth };
|
|
12747
|
+
if (len > depth) {
|
|
12748
|
+
if (atEnd) {
|
|
12749
|
+
pp[pp.length - 1] = base;
|
|
12750
|
+
} else {
|
|
12751
|
+
pp[0] = base;
|
|
12752
|
+
}
|
|
12753
|
+
}
|
|
12754
|
+
return [tip, { x: base.x - uy * across, y: base.y + ux * across }, { x: base.x + uy * across, y: base.y - ux * across }];
|
|
12755
|
+
}
|
|
12678
12756
|
var MIN_DASH = 1 / 256;
|
|
12679
12757
|
function signedArea(pts) {
|
|
12680
12758
|
let a = 0;
|
|
@@ -12725,6 +12803,19 @@ function widenFigures(figures, pen) {
|
|
|
12725
12803
|
if (pp.length < 2) {
|
|
12726
12804
|
continue;
|
|
12727
12805
|
}
|
|
12806
|
+
const arrows = [];
|
|
12807
|
+
let startCapOverride = null;
|
|
12808
|
+
let endCapOverride = null;
|
|
12809
|
+
if (!pieceClosed && !(pen.dash && closed)) {
|
|
12810
|
+
if (piece.first && pen.startCap === ARROW_ANCHOR) {
|
|
12811
|
+
arrows.push(arrowAnchor(pp, false, h));
|
|
12812
|
+
startCapOverride = 0;
|
|
12813
|
+
}
|
|
12814
|
+
if (piece.last && pen.endCap === ARROW_ANCHOR) {
|
|
12815
|
+
arrows.push(arrowAnchor(pp, true, h));
|
|
12816
|
+
endCapOverride = 0;
|
|
12817
|
+
}
|
|
12818
|
+
}
|
|
12728
12819
|
for (const [o1, o2] of bands) {
|
|
12729
12820
|
if (pieceClosed) {
|
|
12730
12821
|
polys.push(sidePoints(pp, true, o2, pen));
|
|
@@ -12735,11 +12826,16 @@ function widenFigures(figures, pen) {
|
|
|
12735
12826
|
const right = sidePoints(pp, false, o1, pen).reverse();
|
|
12736
12827
|
const fEnd = frame(pp[pp.length - 2], pp[pp.length - 1]);
|
|
12737
12828
|
const f0 = frame(pp[1], pp[0]);
|
|
12738
|
-
const endCap = piece.last && !(pen.dash && closed) ? pen.endCap : pen.dashCap;
|
|
12739
|
-
const startCap = piece.first && !(pen.dash && closed) ? pen.startCap : pen.dashCap;
|
|
12829
|
+
const endCap = endCapOverride ?? (piece.last && !(pen.dash && closed) ? pen.endCap : pen.dashCap);
|
|
12830
|
+
const startCap = startCapOverride ?? (piece.first && !(pen.dash && closed) ? pen.startCap : pen.dashCap);
|
|
12740
12831
|
const capEnd = capPoints(pp[pp.length - 1], fEnd, o1, o2, endCap, h);
|
|
12741
12832
|
const capStart = capPoints(pp[0], f0, -o2, -o1, startCap, h);
|
|
12742
|
-
|
|
12833
|
+
const poly = [...left.slice(0, -1), ...capEnd, ...right.slice(1, -1), ...capStart];
|
|
12834
|
+
polys.push(poly);
|
|
12835
|
+
const sign = Math.sign(signedArea(poly));
|
|
12836
|
+
for (const arrow of arrows) {
|
|
12837
|
+
polys.push(Math.sign(signedArea(arrow)) === sign ? arrow : arrow.slice().reverse());
|
|
12838
|
+
}
|
|
12743
12839
|
}
|
|
12744
12840
|
}
|
|
12745
12841
|
}
|
|
@@ -16653,8 +16749,11 @@ function boxCorners(box) {
|
|
|
16653
16749
|
const { ax, ay, exx, exy, eyx, eyy } = box;
|
|
16654
16750
|
return [ax + exx, ay + exy, ax, ay, ax + eyx, ay + eyy, ax + exx + eyx, ay + exy + eyy];
|
|
16655
16751
|
}
|
|
16656
|
-
function
|
|
16657
|
-
|
|
16752
|
+
function flipBox(box) {
|
|
16753
|
+
return { ax: box.ax + box.eyx, ay: box.ay + box.eyy, exx: box.exx, exy: box.exy, eyx: -box.eyx, eyy: -box.eyy };
|
|
16754
|
+
}
|
|
16755
|
+
function rectRasterPath(box, clockwise = false) {
|
|
16756
|
+
const c = boxCorners(clockwise ? flipBox(box) : box);
|
|
16658
16757
|
const path = new GdiRasterPath();
|
|
16659
16758
|
path.moveTo(c[0], c[1]);
|
|
16660
16759
|
path.lineTo(c[2], c[3]);
|
|
@@ -16663,9 +16762,9 @@ function rectRasterPath(box) {
|
|
|
16663
16762
|
path.closeFigure();
|
|
16664
16763
|
return path;
|
|
16665
16764
|
}
|
|
16666
|
-
function ellipseRasterPath(box) {
|
|
16765
|
+
function ellipseRasterPath(box, clockwise = false) {
|
|
16667
16766
|
const path = new GdiRasterPath();
|
|
16668
|
-
path.addBeziers(ellipseBeziersBox(box), true);
|
|
16767
|
+
path.addBeziers(ellipseBeziersBox(box, clockwise), true);
|
|
16669
16768
|
path.closeFigure();
|
|
16670
16769
|
return path;
|
|
16671
16770
|
}
|
|
@@ -16691,13 +16790,16 @@ function boxFrame(box) {
|
|
|
16691
16790
|
const h = Math.round(Math.hypot(box.eyx, box.eyy));
|
|
16692
16791
|
return { l: 0, t: 0, r: w, b: h };
|
|
16693
16792
|
}
|
|
16694
|
-
function roundRectRasterPath(box, cw, ch) {
|
|
16793
|
+
function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false) {
|
|
16794
|
+
if (rectangle) {
|
|
16795
|
+
return rectRasterPath(box, clockwise);
|
|
16796
|
+
}
|
|
16695
16797
|
const f = boxFrame(box);
|
|
16696
16798
|
const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch);
|
|
16697
16799
|
const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
|
|
16698
16800
|
const pts = [];
|
|
16699
16801
|
for (let i = 0; i < q.length; i += 2) {
|
|
16700
|
-
pts.push(...map(q[i], q[i + 1]));
|
|
16802
|
+
pts.push(...map(q[i], clockwise ? f.t + f.b - q[i + 1] : q[i + 1]));
|
|
16701
16803
|
}
|
|
16702
16804
|
const path = new GdiRasterPath();
|
|
16703
16805
|
for (let c = 0; c < 4; c++) {
|
|
@@ -16740,7 +16842,7 @@ function arcRasterPath(box, s, e, clockwise, kind, from, path = new GdiRasterPat
|
|
|
16740
16842
|
pts.push(...map(bz[i], bz[i + 1]));
|
|
16741
16843
|
}
|
|
16742
16844
|
if (kind === "arcto" && from) {
|
|
16743
|
-
path.
|
|
16845
|
+
path.continueAt(from[0], from[1]);
|
|
16744
16846
|
path.addBeziers(pts, false);
|
|
16745
16847
|
} else {
|
|
16746
16848
|
path.addBeziers(pts, true);
|
|
@@ -19460,6 +19562,15 @@ function rasterPathOf(rCtx) {
|
|
|
19460
19562
|
rCtx.rasterPath ?? (rCtx.rasterPath = new GdiRasterPath());
|
|
19461
19563
|
return rCtx.rasterPath;
|
|
19462
19564
|
}
|
|
19565
|
+
function continueFigure(rCtx) {
|
|
19566
|
+
const path = rasterPathOf(rCtx);
|
|
19567
|
+
const [x, y] = currentFix(rCtx);
|
|
19568
|
+
const before = path.figures.length;
|
|
19569
|
+
path.continueAt(x, y);
|
|
19570
|
+
if (path.figures.length !== before) {
|
|
19571
|
+
gdiPathRecorder(rCtx).moveTo(x / 16, y / 16);
|
|
19572
|
+
}
|
|
19573
|
+
}
|
|
19463
19574
|
function lineStyleOf(rCtx) {
|
|
19464
19575
|
rCtx.lineStyle ?? (rCtx.lineStyle = { pos: 0 });
|
|
19465
19576
|
return rCtx.lineStyle;
|
|
@@ -19475,6 +19586,9 @@ function currentFix(rCtx) {
|
|
|
19475
19586
|
}
|
|
19476
19587
|
return fixPoint(rCtx, state.curX, state.curY);
|
|
19477
19588
|
}
|
|
19589
|
+
function uprightFixBox(rCtx, l, t, r, b) {
|
|
19590
|
+
return fixBox(rCtx, Math.min(l, r), Math.min(t, b), Math.max(l, r), Math.max(t, b));
|
|
19591
|
+
}
|
|
19478
19592
|
function fixExtent(rCtx, v, axis) {
|
|
19479
19593
|
const m = gdiDeviceMatrix(rCtx);
|
|
19480
19594
|
const k = axis === 0 ? Math.hypot(m[0], m[1]) : Math.hypot(m[2], m[3]);
|
|
@@ -19517,6 +19631,7 @@ function handleLineTo(rCtx, dataOff, recSize) {
|
|
|
19517
19631
|
const to = rotated ? gmapPoint(rCtx, lx, ly) : { x: gmx(rCtx, lx), y: gmy(rCtx, ly) };
|
|
19518
19632
|
const fixTo = fixPoint(rCtx, lx, ly);
|
|
19519
19633
|
if (inPath) {
|
|
19634
|
+
continueFigure(rCtx);
|
|
19520
19635
|
gdiPathRecorder(rCtx).lineTo(to.x, to.y);
|
|
19521
19636
|
rasterPathOf(rCtx).lineTo(fixTo[0], fixTo[1]);
|
|
19522
19637
|
} else {
|
|
@@ -19551,7 +19666,8 @@ function handleRectangle(rCtx, dataOff, recSize) {
|
|
|
19551
19666
|
const t = view.getInt32(dataOff + 4, true);
|
|
19552
19667
|
const r = view.getInt32(dataOff + 8, true);
|
|
19553
19668
|
const b = view.getInt32(dataOff + 12, true);
|
|
19554
|
-
const box =
|
|
19669
|
+
const box = uprightFixBox(rCtx, l, t, r, b);
|
|
19670
|
+
const clockwise = rCtx.state.arcDirection === 2;
|
|
19555
19671
|
if (!inPath) {
|
|
19556
19672
|
resetLineStyle(rCtx);
|
|
19557
19673
|
}
|
|
@@ -19570,14 +19686,14 @@ function handleRectangle(rCtx, dataOff, recSize) {
|
|
|
19570
19686
|
};
|
|
19571
19687
|
if (inPath) {
|
|
19572
19688
|
appendRect(gdiPathRecorder(rCtx));
|
|
19573
|
-
rasterPathOf(rCtx).append(rectRasterPath(box));
|
|
19689
|
+
rasterPathOf(rCtx).append(rectRasterPath(box, clockwise));
|
|
19574
19690
|
} else {
|
|
19575
19691
|
paintGdiShape(rCtx, {
|
|
19576
19692
|
build: (c) => {
|
|
19577
19693
|
c.beginPath();
|
|
19578
19694
|
appendRect(c);
|
|
19579
19695
|
},
|
|
19580
|
-
raster: () => rectRasterPath(box),
|
|
19696
|
+
raster: () => rectRasterPath(box, clockwise),
|
|
19581
19697
|
rectangle: true,
|
|
19582
19698
|
fill: true,
|
|
19583
19699
|
stroke: true,
|
|
@@ -19592,14 +19708,14 @@ function handleRectangle(rCtx, dataOff, recSize) {
|
|
|
19592
19708
|
const h = gmh(rCtx, b - t);
|
|
19593
19709
|
if (inPath) {
|
|
19594
19710
|
gdiPathRecorder(rCtx).rect(x, y, w, h);
|
|
19595
|
-
rasterPathOf(rCtx).append(rectRasterPath(box));
|
|
19711
|
+
rasterPathOf(rCtx).append(rectRasterPath(box, clockwise));
|
|
19596
19712
|
} else if (needsPathBasedRectangle(rCtx)) {
|
|
19597
19713
|
paintGdiShape(rCtx, {
|
|
19598
19714
|
build: (c) => {
|
|
19599
19715
|
c.beginPath();
|
|
19600
19716
|
c.rect(x, y, w, h);
|
|
19601
19717
|
},
|
|
19602
|
-
raster: () => rectRasterPath(box),
|
|
19718
|
+
raster: () => rectRasterPath(box, clockwise),
|
|
19603
19719
|
rectangle: true,
|
|
19604
19720
|
fill: true,
|
|
19605
19721
|
stroke: true,
|
|
@@ -19712,7 +19828,8 @@ function handleRoundRect(rCtx, dataOff, recSize) {
|
|
|
19712
19828
|
gmh(rCtx, cornerH) / 2,
|
|
19713
19829
|
null
|
|
19714
19830
|
);
|
|
19715
|
-
const
|
|
19831
|
+
const clockwise = rCtx.state.arcDirection === 2;
|
|
19832
|
+
const raster = (box = uprightFixBox(rCtx, l, t, r, b)) => roundRectRasterPath(box, fixExtent(rCtx, cornerW, 0), fixExtent(rCtx, cornerH, 1), clockwise, cornerW === 0 || cornerH === 0);
|
|
19716
19833
|
if (inPath) {
|
|
19717
19834
|
drawRoundRect(gdiPathRecorder(rCtx));
|
|
19718
19835
|
rasterPathOf(rCtx).append(raster());
|
|
@@ -19723,7 +19840,7 @@ function handleRoundRect(rCtx, dataOff, recSize) {
|
|
|
19723
19840
|
c.beginPath();
|
|
19724
19841
|
drawRoundRect(c);
|
|
19725
19842
|
},
|
|
19726
|
-
raster: () => raster(curvedFixBox(rCtx, l, t, r, b)),
|
|
19843
|
+
raster: () => raster(curvedFixBox(rCtx, l, t, r, b, true)),
|
|
19727
19844
|
roundPen: true,
|
|
19728
19845
|
fill: true,
|
|
19729
19846
|
stroke: true
|
|
@@ -19732,8 +19849,8 @@ function handleRoundRect(rCtx, dataOff, recSize) {
|
|
|
19732
19849
|
}
|
|
19733
19850
|
return true;
|
|
19734
19851
|
}
|
|
19735
|
-
function curvedFixBox(rCtx, l, t, r, b) {
|
|
19736
|
-
const box = fixBox(rCtx, l, t, r, b);
|
|
19852
|
+
function curvedFixBox(rCtx, l, t, r, b, upright = false) {
|
|
19853
|
+
const box = upright ? uprightFixBox(rCtx, l, t, r, b) : fixBox(rCtx, l, t, r, b);
|
|
19737
19854
|
if (rCtx.state.penStyle !== 5) {
|
|
19738
19855
|
return box;
|
|
19739
19856
|
}
|
|
@@ -19759,6 +19876,7 @@ function handleEllipse(rCtx, dataOff, recSize) {
|
|
|
19759
19876
|
const t = view.getInt32(dataOff + 4, true);
|
|
19760
19877
|
const r = view.getInt32(dataOff + 8, true);
|
|
19761
19878
|
const b = view.getInt32(dataOff + 12, true);
|
|
19879
|
+
const clockwise = rCtx.state.arcDirection === 2;
|
|
19762
19880
|
const params = hasWorldRotation(rCtx) ? gdiEllipseParams(rCtx, (l + r) / 2, (t + b) / 2, Math.abs(r - l) / 2, Math.abs(b - t) / 2) : {
|
|
19763
19881
|
cx: gmx(rCtx, (l + r) / 2),
|
|
19764
19882
|
cy: gmy(rCtx, (t + b) / 2),
|
|
@@ -19768,7 +19886,7 @@ function handleEllipse(rCtx, dataOff, recSize) {
|
|
|
19768
19886
|
};
|
|
19769
19887
|
if (inPath) {
|
|
19770
19888
|
gdiPathRecorder(rCtx).ellipse(params.cx, params.cy, params.rx, params.ry, params.rotation, 0, Math.PI * 2);
|
|
19771
|
-
rasterPathOf(rCtx).append(ellipseRasterPath(
|
|
19889
|
+
rasterPathOf(rCtx).append(ellipseRasterPath(uprightFixBox(rCtx, l, t, r, b), clockwise));
|
|
19772
19890
|
} else {
|
|
19773
19891
|
resetLineStyle(rCtx);
|
|
19774
19892
|
paintGdiShape(rCtx, {
|
|
@@ -19776,7 +19894,7 @@ function handleEllipse(rCtx, dataOff, recSize) {
|
|
|
19776
19894
|
c.beginPath();
|
|
19777
19895
|
c.ellipse(params.cx, params.cy, params.rx, params.ry, params.rotation, 0, Math.PI * 2);
|
|
19778
19896
|
},
|
|
19779
|
-
raster: () => ellipseRasterPath(curvedFixBox(rCtx, l, t, r, b)),
|
|
19897
|
+
raster: () => ellipseRasterPath(curvedFixBox(rCtx, l, t, r, b, true), clockwise),
|
|
19780
19898
|
roundPen: true,
|
|
19781
19899
|
fill: true,
|
|
19782
19900
|
stroke: true
|
|
@@ -19834,6 +19952,9 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
|
|
|
19834
19952
|
from: currentFix(rCtx)
|
|
19835
19953
|
});
|
|
19836
19954
|
if (inPath) {
|
|
19955
|
+
if (isArcTo) {
|
|
19956
|
+
continueFigure(rCtx);
|
|
19957
|
+
}
|
|
19837
19958
|
build(gdiPathRecorder(rCtx));
|
|
19838
19959
|
const a = rasterArgs();
|
|
19839
19960
|
arcRasterPath(a.box, a.s, a.e, clockwise, kind, a.from, rasterPathOf(rCtx));
|
|
@@ -19910,9 +20031,7 @@ function handleAngleArc(rCtx, dataOff, recSize) {
|
|
|
19910
20031
|
}
|
|
19911
20032
|
const e = [fixPts[fixPts.length - 2], fixPts[fixPts.length - 1]];
|
|
19912
20033
|
const buildRaster = (path, from) => {
|
|
19913
|
-
|
|
19914
|
-
path.moveTo(from[0], from[1]);
|
|
19915
|
-
}
|
|
20034
|
+
path.continueAt(from[0], from[1]);
|
|
19916
20035
|
path.addBeziers(fixPts, false);
|
|
19917
20036
|
};
|
|
19918
20037
|
const params = gdiEllipseParams(rCtx, cx, cy, radius, radius);
|
|
@@ -19926,9 +20045,9 @@ function handleAngleArc(rCtx, dataOff, recSize) {
|
|
|
19926
20045
|
c.ellipse(params.cx, params.cy, params.rx, params.ry, params.rotation, -a0, clockwise ? -a0 + span : -a0 - span, !clockwise);
|
|
19927
20046
|
};
|
|
19928
20047
|
if (inPath) {
|
|
19929
|
-
|
|
19930
|
-
buildCanvas(
|
|
19931
|
-
buildRaster(rasterPathOf(rCtx),
|
|
20048
|
+
continueFigure(rCtx);
|
|
20049
|
+
buildCanvas(gdiPathRecorder(rCtx));
|
|
20050
|
+
buildRaster(rasterPathOf(rCtx), currentFix(rCtx));
|
|
19932
20051
|
} else {
|
|
19933
20052
|
resetLineStyle(rCtx);
|
|
19934
20053
|
const from = currentFix(rCtx);
|
|
@@ -20007,50 +20126,111 @@ function readColorAdjustment(view, off) {
|
|
|
20007
20126
|
function isIdentityColorAdjustment(ca) {
|
|
20008
20127
|
return !ca || ca.flags === 0 && ca.redGamma === 1e4 && ca.greenGamma === 1e4 && ca.blueGamma === 1e4 && ca.referenceBlack === 0 && ca.referenceWhite === 1e4 && ca.contrast === 0 && ca.brightness === 0 && ca.colorfulness === 0 && ca.redGreenTint === 0;
|
|
20009
20128
|
}
|
|
20010
|
-
|
|
20011
|
-
|
|
20129
|
+
var CONTRAST_GAIN = 1.88;
|
|
20130
|
+
var BRIGHTNESS_GAIN = 78.5;
|
|
20131
|
+
var COLORFULNESS_GAIN = 1.335;
|
|
20132
|
+
var TINT_RADIANS = -1.135;
|
|
20133
|
+
var RGB_TO_XYZ = [
|
|
20134
|
+
[0.4124, 0.3576, 0.1805],
|
|
20135
|
+
[0.2126, 0.7152, 0.0722],
|
|
20136
|
+
[0.0193, 0.1192, 0.9505]
|
|
20137
|
+
];
|
|
20138
|
+
var XYZ_TO_RGB = invert3(RGB_TO_XYZ);
|
|
20139
|
+
var WHITE = RGB_TO_XYZ.map((row) => row[0] + row[1] + row[2]);
|
|
20140
|
+
var WHITE_D = WHITE[0] + 15 * WHITE[1] + 3 * WHITE[2];
|
|
20141
|
+
var WHITE_U = 4 * WHITE[0] / WHITE_D;
|
|
20142
|
+
var WHITE_V = 9 * WHITE[1] / WHITE_D;
|
|
20143
|
+
function invert3(m) {
|
|
20144
|
+
const [[a, b, c], [d, e, f], [g, h, i]] = m;
|
|
20145
|
+
const A = e * i - f * h;
|
|
20146
|
+
const B = f * g - d * i;
|
|
20147
|
+
const C = d * h - e * g;
|
|
20148
|
+
const det = a * A + b * B + c * C;
|
|
20149
|
+
return [
|
|
20150
|
+
[A / det, (c * h - b * i) / det, (b * f - c * e) / det],
|
|
20151
|
+
[B / det, (a * i - c * g) / det, (c * d - a * f) / det],
|
|
20152
|
+
[C / det, (b * g - a * h) / det, (a * e - b * d) / det]
|
|
20153
|
+
];
|
|
20154
|
+
}
|
|
20155
|
+
function lightness(t) {
|
|
20156
|
+
return t > 8856e-6 ? 116 * Math.cbrt(t) - 16 : 903.3 * t;
|
|
20157
|
+
}
|
|
20158
|
+
function fromLightness(l) {
|
|
20159
|
+
return l > 8 ? ((l + 16) / 116) ** 3 : l / 903.3;
|
|
20012
20160
|
}
|
|
20013
20161
|
var clamp012 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
20014
20162
|
function colorAdjustmentMapper(ca) {
|
|
20015
20163
|
const black = ca.referenceBlack / 1e4;
|
|
20016
20164
|
const span = Math.max(1e-6, ca.referenceWhite / 1e4 - black);
|
|
20017
20165
|
const gammas = [ca.redGamma / 1e4, ca.greenGamma / 1e4, ca.blueGamma / 1e4];
|
|
20018
|
-
const
|
|
20166
|
+
const negative = (ca.flags & CA_NEGATIVE) !== 0;
|
|
20167
|
+
const linear = gammas.map((gamma) => {
|
|
20019
20168
|
const table = new Float64Array(256);
|
|
20020
20169
|
for (let i = 0; i < 256; i++) {
|
|
20021
|
-
|
|
20022
|
-
|
|
20023
|
-
table[i] = ca.flags & CA_NEGATIVE ? 1 - v : v;
|
|
20170
|
+
const v = negative ? 1 - i / 255 : i / 255;
|
|
20171
|
+
table[i] = clamp012((v - black) / span) ** gamma;
|
|
20024
20172
|
}
|
|
20025
20173
|
return table;
|
|
20026
20174
|
});
|
|
20027
|
-
const chroma =
|
|
20028
|
-
const
|
|
20029
|
-
const
|
|
20030
|
-
const
|
|
20175
|
+
const chroma = ca.colorfulness < 0 ? 1 + ca.colorfulness / 100 : 1 + COLORFULNESS_GAIN * ca.colorfulness / 100;
|
|
20176
|
+
const angle = TINT_RADIANS * ca.redGreenTint / 100;
|
|
20177
|
+
const cos = Math.cos(angle) * chroma;
|
|
20178
|
+
const sin = Math.sin(angle) * chroma;
|
|
20179
|
+
const slope = Math.exp(CONTRAST_GAIN * ca.contrast / 100);
|
|
20180
|
+
const offset = 50 - 50 * slope + BRIGHTNESS_GAIN * ca.brightness / 100;
|
|
20031
20181
|
const log = (ca.flags & CA_LOG_FILTER) !== 0;
|
|
20032
|
-
const
|
|
20033
|
-
|
|
20182
|
+
const colour = ca.colorfulness !== 0 || ca.redGreenTint !== 0;
|
|
20183
|
+
const out = (v, c) => {
|
|
20184
|
+
v = clamp012(fromLightness(slope * lightness(clamp012(v)) + offset)) ** (1 / gammas[c]);
|
|
20034
20185
|
if (log) {
|
|
20035
20186
|
v = Math.log10(1 + 9 * v);
|
|
20036
20187
|
}
|
|
20037
20188
|
return Math.round(v * 255);
|
|
20038
20189
|
};
|
|
20039
20190
|
return (rgb2) => {
|
|
20040
|
-
|
|
20041
|
-
|
|
20042
|
-
|
|
20043
|
-
|
|
20044
|
-
|
|
20045
|
-
|
|
20046
|
-
|
|
20047
|
-
|
|
20048
|
-
|
|
20049
|
-
|
|
20050
|
-
|
|
20051
|
-
|
|
20191
|
+
let r = linear[0][rgb2 >> 16 & 255];
|
|
20192
|
+
let g = linear[1][rgb2 >> 8 & 255];
|
|
20193
|
+
let b = linear[2][rgb2 & 255];
|
|
20194
|
+
if (colour) {
|
|
20195
|
+
const x = RGB_TO_XYZ[0][0] * r + RGB_TO_XYZ[0][1] * g + RGB_TO_XYZ[0][2] * b;
|
|
20196
|
+
const y = RGB_TO_XYZ[1][0] * r + RGB_TO_XYZ[1][1] * g + RGB_TO_XYZ[1][2] * b;
|
|
20197
|
+
const z = RGB_TO_XYZ[2][0] * r + RGB_TO_XYZ[2][1] * g + RGB_TO_XYZ[2][2] * b;
|
|
20198
|
+
const d = x + 15 * y + 3 * z;
|
|
20199
|
+
if (d > 1e-12 && y > 1e-12) {
|
|
20200
|
+
const du = 4 * x / d - WHITE_U;
|
|
20201
|
+
const dv = 9 * y / d - WHITE_V;
|
|
20202
|
+
const u = WHITE_U + du * cos - dv * sin;
|
|
20203
|
+
const v = Math.max(1e-6, WHITE_V + du * sin + dv * cos);
|
|
20204
|
+
const x2 = y * 9 * u / (4 * v);
|
|
20205
|
+
const z2 = y * (12 - 3 * u - 20 * v) / (4 * v);
|
|
20206
|
+
r = XYZ_TO_RGB[0][0] * x2 + XYZ_TO_RGB[0][1] * y + XYZ_TO_RGB[0][2] * z2;
|
|
20207
|
+
g = XYZ_TO_RGB[1][0] * x2 + XYZ_TO_RGB[1][1] * y + XYZ_TO_RGB[1][2] * z2;
|
|
20208
|
+
b = XYZ_TO_RGB[2][0] * x2 + XYZ_TO_RGB[2][1] * y + XYZ_TO_RGB[2][2] * z2;
|
|
20209
|
+
}
|
|
20210
|
+
}
|
|
20211
|
+
return out(r, 0) << 16 | out(g, 1) << 8 | out(b, 2);
|
|
20052
20212
|
};
|
|
20053
20213
|
}
|
|
20214
|
+
function colorAdjustRgb(rgbs, ca) {
|
|
20215
|
+
if (!ca || isIdentityColorAdjustment(ca)) {
|
|
20216
|
+
return;
|
|
20217
|
+
}
|
|
20218
|
+
const map = colorAdjustmentMapper(ca);
|
|
20219
|
+
const cache = /* @__PURE__ */ new Map();
|
|
20220
|
+
for (let i = 0; i + 2 < rgbs.length; i += 3) {
|
|
20221
|
+
const rgb2 = rgbs[i] << 16 | rgbs[i + 1] << 8 | rgbs[i + 2];
|
|
20222
|
+
let v = cache.get(rgb2);
|
|
20223
|
+
if (v === void 0) {
|
|
20224
|
+
v = map(rgb2);
|
|
20225
|
+
if (cache.size < 65536) {
|
|
20226
|
+
cache.set(rgb2, v);
|
|
20227
|
+
}
|
|
20228
|
+
}
|
|
20229
|
+
rgbs[i] = v >> 16 & 255;
|
|
20230
|
+
rgbs[i + 1] = v >> 8 & 255;
|
|
20231
|
+
rgbs[i + 2] = v & 255;
|
|
20232
|
+
}
|
|
20233
|
+
}
|
|
20054
20234
|
function applyColorAdjustment(pixels, ca) {
|
|
20055
20235
|
if (!ca || isIdentityColorAdjustment(ca)) {
|
|
20056
20236
|
return;
|
|
@@ -20145,64 +20325,160 @@ function stretchGdi(src, sx, sy, sw, sh, dw, dh, mode) {
|
|
|
20145
20325
|
}
|
|
20146
20326
|
return { width: W, height: H, data };
|
|
20147
20327
|
}
|
|
20148
|
-
|
|
20149
|
-
|
|
20328
|
+
var FIX = 65536;
|
|
20329
|
+
function halftoneNearest(i, srcLen, dstLen) {
|
|
20330
|
+
const num = (2 * i + 1) * srcLen;
|
|
20331
|
+
const den = 2 * dstLen;
|
|
20332
|
+
let k = Math.floor(num / den);
|
|
20333
|
+
if (k * den === num) {
|
|
20334
|
+
k--;
|
|
20335
|
+
}
|
|
20336
|
+
return Math.max(0, Math.min(srcLen - 1, k));
|
|
20337
|
+
}
|
|
20338
|
+
function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
20339
|
+
const taps = [];
|
|
20150
20340
|
if (dstLen <= 0 || srcLen <= 0) {
|
|
20151
|
-
return
|
|
20341
|
+
return taps;
|
|
20152
20342
|
}
|
|
20153
|
-
const at = (k) => reverse ?
|
|
20343
|
+
const at = (k) => reverse ? start + srcLen - 1 - k : start + k;
|
|
20344
|
+
if (dstLen >= srcLen) {
|
|
20345
|
+
for (let i = 0; i < dstLen; i++) {
|
|
20346
|
+
taps.push([[at(halftoneNearest(i, srcLen, dstLen)), 1]]);
|
|
20347
|
+
}
|
|
20348
|
+
return taps;
|
|
20349
|
+
}
|
|
20350
|
+
const step = Math.ceil(srcLen * FIX / dstLen);
|
|
20154
20351
|
for (let i = 0; i < dstLen; i++) {
|
|
20155
|
-
const a = i *
|
|
20156
|
-
const b = (i + 1) *
|
|
20157
|
-
const
|
|
20158
|
-
for (let k = Math.floor(a /
|
|
20159
|
-
const overlap = Math.min(b, (k + 1) *
|
|
20352
|
+
const a = i * step;
|
|
20353
|
+
const b = (i + 1) * step;
|
|
20354
|
+
const run = [];
|
|
20355
|
+
for (let k = Math.floor(a / FIX); k * FIX < b && k < srcLen; k++) {
|
|
20356
|
+
const overlap = Math.min(b, (k + 1) * FIX) - Math.max(a, k * FIX);
|
|
20160
20357
|
if (overlap > 0) {
|
|
20161
|
-
|
|
20358
|
+
run.push([at(k), overlap]);
|
|
20359
|
+
}
|
|
20360
|
+
}
|
|
20361
|
+
taps.push(run);
|
|
20362
|
+
}
|
|
20363
|
+
return taps;
|
|
20364
|
+
}
|
|
20365
|
+
var SPECKLE_OVERSHOOT = 4;
|
|
20366
|
+
function halftoneDespeckle(px, w, h) {
|
|
20367
|
+
const src = px.slice();
|
|
20368
|
+
const at = (x, y, c) => src[(y * w + x) * 3 + c];
|
|
20369
|
+
const over = (v) => v < -SPECKLE_OVERSHOOT * 4 || v > (255 + SPECKLE_OVERSHOOT) * 4;
|
|
20370
|
+
for (let y = 0; y < h; y++) {
|
|
20371
|
+
const up = y > 0 ? y - 1 : Math.min(h - 1, y + 1);
|
|
20372
|
+
const down = y < h - 1 ? y + 1 : Math.max(0, y - 1);
|
|
20373
|
+
for (let x = 0; x < w; x++) {
|
|
20374
|
+
const left = x > 0 ? x - 1 : Math.min(w - 1, x + 1);
|
|
20375
|
+
const right = x < w - 1 ? x + 1 : Math.max(0, x - 1);
|
|
20376
|
+
let hClip = 0;
|
|
20377
|
+
let vClip = 0;
|
|
20378
|
+
for (let c = 0; c < 3; c++) {
|
|
20379
|
+
const v = at(x, y, c);
|
|
20380
|
+
if (over(6 * v - at(left, y, c) - at(right, y, c))) {
|
|
20381
|
+
hClip++;
|
|
20382
|
+
}
|
|
20383
|
+
if (over(6 * v - at(x, up, c) - at(x, down, c))) {
|
|
20384
|
+
vClip++;
|
|
20385
|
+
}
|
|
20386
|
+
}
|
|
20387
|
+
if (hClip < 2 || vClip < 2) {
|
|
20388
|
+
continue;
|
|
20389
|
+
}
|
|
20390
|
+
for (let c = 0; c < 3; c++) {
|
|
20391
|
+
px[(y * w + x) * 3 + c] = at(left, y, c) + 2 * at(x, y, c) + at(right, y, c) + 2 >> 2;
|
|
20162
20392
|
}
|
|
20163
20393
|
}
|
|
20164
|
-
out.push(taps);
|
|
20165
20394
|
}
|
|
20166
|
-
return out;
|
|
20167
20395
|
}
|
|
20168
|
-
function
|
|
20396
|
+
function halftoneSharpen(px, w, h) {
|
|
20397
|
+
const src = px.slice();
|
|
20398
|
+
const at = (x, y, c) => src[(Math.max(0, Math.min(h - 1, y)) * w + Math.max(0, Math.min(w - 1, x))) * 3 + c];
|
|
20399
|
+
for (let y = 0; y < h; y++) {
|
|
20400
|
+
for (let x = 0; x < w; x++) {
|
|
20401
|
+
for (let c = 0; c < 3; c++) {
|
|
20402
|
+
const v = at(x, y, c);
|
|
20403
|
+
const sum = at(x - 1, y, c) + at(x + 1, y, c) + at(x, y - 1, c) + at(x, y + 1, c);
|
|
20404
|
+
const out = v + Math.floor((4 * v - sum) / 8);
|
|
20405
|
+
px[(y * w + x) * 3 + c] = out < 0 ? 0 : out > 255 ? 255 : out;
|
|
20406
|
+
}
|
|
20407
|
+
}
|
|
20408
|
+
}
|
|
20409
|
+
}
|
|
20410
|
+
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
20169
20411
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
20170
20412
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
20413
|
+
const SW = Math.round(Math.abs(sw));
|
|
20414
|
+
const SH = Math.round(Math.abs(sh));
|
|
20415
|
+
const x0 = Math.round(Math.min(sx, sx + sw));
|
|
20416
|
+
const y0 = Math.round(Math.min(sy, sy + sh));
|
|
20171
20417
|
const flipX = dw < 0 !== sw < 0;
|
|
20172
20418
|
const flipY = dh < 0 !== sh < 0;
|
|
20173
|
-
const cols = axisBoxWeights(Math.round(Math.min(sx, sx + sw)), Math.round(Math.abs(sw)), W, flipX);
|
|
20174
|
-
const rows = axisBoxWeights(Math.round(Math.min(sy, sy + sh)), Math.round(Math.abs(sh)), H, flipY);
|
|
20175
20419
|
const data = new Uint8ClampedArray(W * H * 4);
|
|
20176
|
-
|
|
20420
|
+
if (W === 0 || H === 0 || SW === 0 || SH === 0) {
|
|
20421
|
+
return { width: W, height: H, data };
|
|
20422
|
+
}
|
|
20423
|
+
const rect = new Int32Array(SW * SH * 3);
|
|
20424
|
+
for (let y = 0; y < SH; y++) {
|
|
20425
|
+
const yy = y0 + y;
|
|
20426
|
+
for (let x = 0; x < SW; x++) {
|
|
20427
|
+
const xx = x0 + x;
|
|
20428
|
+
if (yy < 0 || yy >= src.height || xx < 0 || xx >= src.width) {
|
|
20429
|
+
continue;
|
|
20430
|
+
}
|
|
20431
|
+
const i = (yy * src.width + xx) * 4;
|
|
20432
|
+
const o = (y * SW + x) * 3;
|
|
20433
|
+
rect[o] = src.data[i];
|
|
20434
|
+
rect[o + 1] = src.data[i + 1];
|
|
20435
|
+
rect[o + 2] = src.data[i + 2];
|
|
20436
|
+
}
|
|
20437
|
+
}
|
|
20438
|
+
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
20439
|
+
const reducing = W < SW && H < SH;
|
|
20440
|
+
if (enlarging) {
|
|
20441
|
+
halftoneDespeckle(rect, SW, SH);
|
|
20442
|
+
}
|
|
20443
|
+
if (adjust) {
|
|
20444
|
+
adjust(rect);
|
|
20445
|
+
}
|
|
20446
|
+
const cols = halftoneAxis(0, SW, W, flipX);
|
|
20447
|
+
const rows = halftoneAxis(0, SH, H, flipY);
|
|
20448
|
+
const out = new Int32Array(W * H * 3);
|
|
20177
20449
|
for (let y = 0; y < H; y++) {
|
|
20178
|
-
const ys = rows[y]
|
|
20450
|
+
const ys = rows[y];
|
|
20179
20451
|
for (let x = 0; x < W; x++) {
|
|
20180
|
-
const xs = cols[x]
|
|
20452
|
+
const xs = cols[x];
|
|
20181
20453
|
let r = 0;
|
|
20182
20454
|
let g = 0;
|
|
20183
20455
|
let b = 0;
|
|
20456
|
+
let total = 0;
|
|
20184
20457
|
for (const [yy, wy] of ys) {
|
|
20185
|
-
if (yy < 0 || yy >= src.height) {
|
|
20186
|
-
continue;
|
|
20187
|
-
}
|
|
20188
20458
|
for (const [xx, wx] of xs) {
|
|
20189
|
-
if (xx < 0 || xx >= src.width) {
|
|
20190
|
-
continue;
|
|
20191
|
-
}
|
|
20192
20459
|
const w = wx * wy;
|
|
20193
|
-
|
|
20194
|
-
|
|
20195
|
-
|
|
20196
|
-
|
|
20460
|
+
total += w;
|
|
20461
|
+
const i = (yy * SW + xx) * 3;
|
|
20462
|
+
r += rect[i] * w;
|
|
20463
|
+
g += rect[i + 1] * w;
|
|
20464
|
+
b += rect[i + 2] * w;
|
|
20197
20465
|
}
|
|
20198
20466
|
}
|
|
20199
|
-
const o = (y * W + x) *
|
|
20200
|
-
|
|
20201
|
-
|
|
20202
|
-
|
|
20203
|
-
data[o + 3] = 255;
|
|
20467
|
+
const o = (y * W + x) * 3;
|
|
20468
|
+
out[o] = Math.floor((2 * r + total) / (2 * total));
|
|
20469
|
+
out[o + 1] = Math.floor((2 * g + total) / (2 * total));
|
|
20470
|
+
out[o + 2] = Math.floor((2 * b + total) / (2 * total));
|
|
20204
20471
|
}
|
|
20205
20472
|
}
|
|
20473
|
+
if (reducing) {
|
|
20474
|
+
halftoneSharpen(out, W, H);
|
|
20475
|
+
}
|
|
20476
|
+
for (let i = 0, o = 0; i < W * H; i++, o += 3) {
|
|
20477
|
+
data[i * 4] = out[o];
|
|
20478
|
+
data[i * 4 + 1] = out[o + 1];
|
|
20479
|
+
data[i * 4 + 2] = out[o + 2];
|
|
20480
|
+
data[i * 4 + 3] = 255;
|
|
20481
|
+
}
|
|
20206
20482
|
return { width: W, height: H, data };
|
|
20207
20483
|
}
|
|
20208
20484
|
|
|
@@ -20228,7 +20504,7 @@ function patternOperand(rCtx, brush) {
|
|
|
20228
20504
|
function drawSourceMapped(target, decoded, req, offsetX, offsetY, mode) {
|
|
20229
20505
|
const dLeft = Math.min(req.dx, req.dx + req.dw) - offsetX;
|
|
20230
20506
|
const dTop = Math.min(req.dy, req.dy + req.dh) - offsetY;
|
|
20231
|
-
const px = mode === HALFTONE ? stretchHalftone(decoded.pixels, req.sx, req.sy, req.sw, req.sh, req.dw, req.dh) : stretchGdi(decoded.pixels, req.sx, req.sy, req.sw, req.sh, req.dw, req.dh, mode);
|
|
20507
|
+
const px = mode === HALFTONE ? stretchHalftone(decoded.pixels, req.sx, req.sy, req.sw, req.sh, req.dw, req.dh, decoded.adjust) : stretchGdi(decoded.pixels, req.sx, req.sy, req.sw, req.sh, req.dw, req.dh, mode);
|
|
20232
20508
|
if (px.width === 0 || px.height === 0) {
|
|
20233
20509
|
return;
|
|
20234
20510
|
}
|
|
@@ -20256,15 +20532,14 @@ function decodeSource(rCtx, req) {
|
|
|
20256
20532
|
if (!image) {
|
|
20257
20533
|
return null;
|
|
20258
20534
|
}
|
|
20259
|
-
|
|
20260
|
-
|
|
20261
|
-
}
|
|
20535
|
+
const ca = rCtx.state.colorAdjustment;
|
|
20536
|
+
const adjust = req.stretch && rCtx.state.stretchBltMode === HALFTONE && ca ? (rgb2) => colorAdjustRgb(rgb2, ca) : void 0;
|
|
20262
20537
|
let { sy } = req;
|
|
20263
20538
|
if (req.dibOrigin === "bottom-left" && rCtx.view.getInt32(req.source.bmi + 8, true) > 0) {
|
|
20264
20539
|
sy = image.height - sy - req.sh;
|
|
20265
20540
|
}
|
|
20266
20541
|
return {
|
|
20267
|
-
decoded: { pixels: image },
|
|
20542
|
+
decoded: { pixels: image, adjust },
|
|
20268
20543
|
req: { ...req, sy }
|
|
20269
20544
|
};
|
|
20270
20545
|
}
|
|
@@ -20420,6 +20695,9 @@ function executeRotatedBlit(rCtx, logDx, logDy, logDw, logDh, rop, source, sx, s
|
|
|
20420
20695
|
return;
|
|
20421
20696
|
}
|
|
20422
20697
|
src = decoded.decoded.pixels;
|
|
20698
|
+
if (decoded.decoded.adjust) {
|
|
20699
|
+
applyColorAdjustment(src, rCtx.state.colorAdjustment);
|
|
20700
|
+
}
|
|
20423
20701
|
srcX = decoded.req.sx;
|
|
20424
20702
|
srcY = decoded.req.sy;
|
|
20425
20703
|
}
|
|
@@ -22775,9 +23053,12 @@ function handlePoly(rCtx, recType, count, readPt, kinds) {
|
|
|
22775
23053
|
}
|
|
22776
23054
|
};
|
|
22777
23055
|
if (inPath) {
|
|
23056
|
+
if (isTo) {
|
|
23057
|
+
continueFigure(rCtx);
|
|
23058
|
+
}
|
|
22778
23059
|
build(gdiPathRecorder(rCtx));
|
|
22779
23060
|
rCtx.rasterPath ?? (rCtx.rasterPath = new GdiRasterPath());
|
|
22780
|
-
buildRaster(rCtx.rasterPath,
|
|
23061
|
+
buildRaster(rCtx.rasterPath, null);
|
|
22781
23062
|
} else {
|
|
22782
23063
|
const from = isTo ? currentFix(rCtx) : null;
|
|
22783
23064
|
const start = isTo ? gmapPoint(rCtx, state.curX, state.curY) : null;
|
|
@@ -22800,10 +23081,11 @@ function handlePoly(rCtx, recType, count, readPt, kinds) {
|
|
|
22800
23081
|
fillRule: state.polyFillMode === 2 ? "nonzero" : "evenodd"
|
|
22801
23082
|
});
|
|
22802
23083
|
}
|
|
22803
|
-
if (count > 0) {
|
|
23084
|
+
if (isTo && count > 0) {
|
|
22804
23085
|
const [x, y] = readPt(count - 1);
|
|
22805
23086
|
state.curX = x;
|
|
22806
23087
|
state.curY = y;
|
|
23088
|
+
rCtx.curFix = void 0;
|
|
22807
23089
|
}
|
|
22808
23090
|
}
|
|
22809
23091
|
function handlePoly32(rCtx, recType, offset, dataOff, recSize) {
|
|
@@ -22908,9 +23190,11 @@ function handlePolyDraw(rCtx, offset, dataOff, recSize, pointSize) {
|
|
|
22908
23190
|
};
|
|
22909
23191
|
const startsWithMove = (typeAt(0) & ~PT_CLOSEFIGURE) === PT_MOVETO;
|
|
22910
23192
|
if (inPath) {
|
|
23193
|
+
if (!startsWithMove) {
|
|
23194
|
+
continueFigure(rCtx);
|
|
23195
|
+
}
|
|
22911
23196
|
rCtx.rasterPath ?? (rCtx.rasterPath = new GdiRasterPath());
|
|
22912
|
-
|
|
22913
|
-
walk2(gdiPathRecorder(rCtx), rCtx.rasterPath, !startsWithMove && fresh ? currentFix(rCtx) : null, null);
|
|
23197
|
+
walk2(gdiPathRecorder(rCtx), rCtx.rasterPath, null, null);
|
|
22914
23198
|
} else {
|
|
22915
23199
|
const from = startsWithMove ? null : currentFix(rCtx);
|
|
22916
23200
|
const fromPx = startsWithMove ? null : gmapPoint(rCtx, state.curX, state.curY);
|
|
@@ -23881,12 +24165,12 @@ function hslToRgb(h, s, l) {
|
|
|
23881
24165
|
const [r, g, b] = hp < 1 ? [c, x, 0] : hp < 2 ? [x, c, 0] : hp < 3 ? [0, c, x] : hp < 4 ? [0, x, c] : hp < 5 ? [x, 0, c] : [c, 0, x];
|
|
23882
24166
|
return [r + m, g + m, b + m];
|
|
23883
24167
|
}
|
|
23884
|
-
function applyHueSaturationLightness(src, hue, saturation,
|
|
24168
|
+
function applyHueSaturationLightness(src, hue, saturation, lightness2) {
|
|
23885
24169
|
const out = new Uint8ClampedArray(src);
|
|
23886
24170
|
const push = (v, t) => t >= 0 ? v + (1 - v) * (t / 100) : v * (1 + t / 100);
|
|
23887
24171
|
for (let i = 0; i < src.length; i += 4) {
|
|
23888
24172
|
const [h, s, l] = rgbToHsl(src[i] / 255, src[i + 1] / 255, src[i + 2] / 255);
|
|
23889
|
-
const [r, g, b] = hslToRgb(h + hue, push(s, saturation), push(l,
|
|
24173
|
+
const [r, g, b] = hslToRgb(h + hue, push(s, saturation), push(l, lightness2));
|
|
23890
24174
|
out[i] = Math.round(r * 255);
|
|
23891
24175
|
out[i + 1] = Math.round(g * 255);
|
|
23892
24176
|
out[i + 2] = Math.round(b * 255);
|
|
@@ -24577,6 +24861,7 @@ function strokePlusGeometry(rCtx, pen, buildPath, points, closedFigure = false)
|
|
|
24577
24861
|
}
|
|
24578
24862
|
};
|
|
24579
24863
|
if (pen) {
|
|
24864
|
+
const nibDashed = !!nib && penDashArray(pen).length > 0;
|
|
24580
24865
|
applyPlusPenStyle(ctx, pen, widthScale);
|
|
24581
24866
|
const mode = plusRasterMode(rCtx);
|
|
24582
24867
|
let sampler = pen.brush && !isSvgContext(ctx) ? brushSampler(rCtx, pen.brush) : null;
|
|
@@ -24591,7 +24876,7 @@ function strokePlusGeometry(rCtx, pen, buildPath, points, closedFigure = false)
|
|
|
24591
24876
|
if (mode !== "canvas" && size && strokeGdiplus(rCtx, pen, nib, sampler, buildPath, device, size, mode, closedFigure)) {
|
|
24592
24877
|
return;
|
|
24593
24878
|
}
|
|
24594
|
-
const outline = hasCustomCap(pen) ? penOutlineWorld(rCtx, pen, nib, buildPath, closedFigure) : null;
|
|
24879
|
+
const outline = hasCustomCap(pen) || nibDashed ? penOutlineWorld(rCtx, pen, nib, buildPath, closedFigure) : null;
|
|
24595
24880
|
let box = null;
|
|
24596
24881
|
if (size && outline) {
|
|
24597
24882
|
box = deviceBounds(outline.flat(), device, size, 2);
|
|
@@ -24621,7 +24906,7 @@ function strokePlusGeometry(rCtx, pen, buildPath, points, closedFigure = false)
|
|
|
24621
24906
|
}
|
|
24622
24907
|
}
|
|
24623
24908
|
const paint = pen.brush ? brushPaint2(rCtx, pen.brush) : pen.color;
|
|
24624
|
-
if ((hasCustomCap(pen) || nib && typeof paint !== "string") && fillPenOutline(rCtx, pen, nib, paint, buildPath, closedFigure)) {
|
|
24909
|
+
if ((hasCustomCap(pen) || nibDashed || nib && typeof paint !== "string") && fillPenOutline(rCtx, pen, nib, paint, buildPath, closedFigure)) {
|
|
24625
24910
|
return;
|
|
24626
24911
|
}
|
|
24627
24912
|
ctx.strokeStyle = paint;
|
|
@@ -24643,7 +24928,9 @@ function resolvePenTransform(pen) {
|
|
|
24643
24928
|
return { pen: { ...plain, width: pen.width === 0 ? 1 : pen.width }, nib: null };
|
|
24644
24929
|
}
|
|
24645
24930
|
if (Math.abs(sx - sy) <= 1e-6 * sx && Math.abs(dot) <= 1e-6 * sx * sy) {
|
|
24646
|
-
|
|
24931
|
+
const pattern = pen.dashStyle === 5 ? pen.dashPattern : DASH_PATTERNS[pen.dashStyle];
|
|
24932
|
+
const dashed = pattern && pattern.length > 0 ? { dashStyle: 5, dashPattern: pattern.map((v) => v / sx), dashOffset: (pen.dashOffset ?? 0) / sx } : {};
|
|
24933
|
+
return { pen: { ...plain, ...dashed, width: pen.width * sx }, nib: null };
|
|
24647
24934
|
}
|
|
24648
24935
|
return { pen: plain, nib: [a, b, c, d, 0, 0] };
|
|
24649
24936
|
}
|
|
@@ -24668,7 +24955,7 @@ function penFrame(device, nib) {
|
|
|
24668
24955
|
toDevice: mulMatrix(full, [1 / unit, 0, 0, 1 / unit, 0, 0])
|
|
24669
24956
|
};
|
|
24670
24957
|
}
|
|
24671
|
-
function framePen(pen, unit) {
|
|
24958
|
+
function framePen(pen, unit, nib = null) {
|
|
24672
24959
|
const dash = penDashArray(pen).map((v) => v * unit);
|
|
24673
24960
|
return {
|
|
24674
24961
|
half: (pen.width || 1) * unit / 2,
|
|
@@ -24679,6 +24966,7 @@ function framePen(pen, unit) {
|
|
|
24679
24966
|
dashCap: pen.dashCap ?? 0,
|
|
24680
24967
|
dash: dash.length > 0 ? dash : null,
|
|
24681
24968
|
dashOffset: (pen.dashOffset ?? 0) * (pen.width || 1) * unit,
|
|
24969
|
+
dashMetric: nib ? [nib[0], nib[1], nib[2], nib[3]] : void 0,
|
|
24682
24970
|
compound: pen.compound ?? null,
|
|
24683
24971
|
inset: pen.alignment === 1
|
|
24684
24972
|
};
|
|
@@ -24706,7 +24994,7 @@ function strokeGdiplus(rCtx, pen, nib, sampler, buildPath, device, size, mode, c
|
|
|
24706
24994
|
figures = figures.map((f) => ({ ...f, closed: true }));
|
|
24707
24995
|
}
|
|
24708
24996
|
const width = (pen.width || 1) * frame2.unit;
|
|
24709
|
-
const devicePen = framePen(pen, frame2.unit);
|
|
24997
|
+
const devicePen = framePen(pen, frame2.unit, nib);
|
|
24710
24998
|
const antialias = mode === "gdiplus-aa";
|
|
24711
24999
|
const toFix = (poly) => {
|
|
24712
25000
|
const m = frame2.toDevice;
|
|
@@ -24798,7 +25086,7 @@ function penOutlineWorld(rCtx, pen, nib, buildPath, closedFigure) {
|
|
|
24798
25086
|
figures = figures.map((f) => ({ ...f, closed: true }));
|
|
24799
25087
|
}
|
|
24800
25088
|
const width = (pen.width || 1) * frame2.unit;
|
|
24801
|
-
const devicePen = framePen(pen, frame2.unit);
|
|
25089
|
+
const devicePen = framePen(pen, frame2.unit, nib);
|
|
24802
25090
|
const outline = hasCustomCap(pen) ? customCapOutline(figures, width, devicePen, pen) : widenFigures(figures, devicePen);
|
|
24803
25091
|
const m = mulMatrix(deviceInv, frame2.toDevice);
|
|
24804
25092
|
return outline.map((poly) => poly.map((p) => ({ x: m[0] * p.x + m[2] * p.y + m[4], y: m[1] * p.x + m[3] * p.y + m[5] })));
|
|
@@ -27366,7 +27654,8 @@ function wmfSetDibToDev(p, d, end) {
|
|
|
27366
27654
|
const hv = new DataView(bmi.buffer);
|
|
27367
27655
|
const fullH = hv.getInt32(8, true);
|
|
27368
27656
|
hv.setInt32(8, fullH < 0 ? -scanCount : scanCount, true);
|
|
27369
|
-
const [
|
|
27657
|
+
const [mx, oy] = deviceDest(p, dx, dy, 0, 0);
|
|
27658
|
+
const ox = p.layout & 1 ? mx - w : mx;
|
|
27370
27659
|
playStretchDibits(p, 13369376, ox, oy + (sy + h - hi), w, hi - lo, sx, lo - startScan, w, hi - lo, { bmi, bits: dib.bits }, true);
|
|
27371
27660
|
}
|
|
27372
27661
|
|
|
@@ -27713,25 +28002,30 @@ function wmfRectangle(p, l, t, r, b) {
|
|
|
27713
28002
|
c.beginPath();
|
|
27714
28003
|
c.rect(cr.x, cr.y, cr.w, cr.h);
|
|
27715
28004
|
},
|
|
27716
|
-
raster: () => rectRasterPath(fixBoxOf(box)),
|
|
28005
|
+
raster: () => rectRasterPath(fixBoxOf(box), clockwiseOf(p)),
|
|
27717
28006
|
rectangle: true,
|
|
27718
28007
|
fill: true,
|
|
27719
28008
|
stroke: true,
|
|
27720
28009
|
axisRect: { interior: rectInterior(p, box) }
|
|
27721
28010
|
});
|
|
27722
28011
|
}
|
|
28012
|
+
function compatCorner(p, w, h) {
|
|
28013
|
+
const m = gdiDeviceMatrix(p.rCtx);
|
|
28014
|
+
const cw = Math.round(Math.abs(w * m[0]) * 16);
|
|
28015
|
+
const ch = Math.round(Math.abs(h * m[3]) * 16);
|
|
28016
|
+
const ux = 16 * p.kx;
|
|
28017
|
+
const uy = 16 * p.ky;
|
|
28018
|
+
if (!penIsNull(p) && !penIsCosmetic(p.rCtx)) {
|
|
28019
|
+
return [Math.round(Math.floor(cw / (2 * ux)) * 2 * ux), Math.round(Math.floor(ch / (2 * uy)) * 2 * uy)];
|
|
28020
|
+
}
|
|
28021
|
+
return [Math.round(Math.floor(Math.round(cw / ux) / 2) * 2 * ux), Math.round(Math.floor(Math.round(ch / uy) / 2) * 2 * uy)];
|
|
28022
|
+
}
|
|
27723
28023
|
function wmfRoundRect(p, l, t, r, b, w, h) {
|
|
27724
28024
|
const box = compatBox(p, l, t, r, b, { curved: true });
|
|
27725
28025
|
if (box.x1 < box.x0 || box.y1 < box.y0) {
|
|
27726
28026
|
return;
|
|
27727
28027
|
}
|
|
27728
|
-
const
|
|
27729
|
-
let cw = Math.round(Math.abs(w * m[0]) * 16);
|
|
27730
|
-
let ch = Math.round(Math.abs(h * m[3]) * 16);
|
|
27731
|
-
if (!penIsNull(p) && !penIsCosmetic(p.rCtx)) {
|
|
27732
|
-
cw = Math.floor(cw / 32) * 32;
|
|
27733
|
-
ch = Math.floor(ch / 32) * 32;
|
|
27734
|
-
}
|
|
28028
|
+
const [cw, ch] = compatCorner(p, w, h);
|
|
27735
28029
|
const cr = canvasRect(box);
|
|
27736
28030
|
paintGdiShape(p.rCtx, {
|
|
27737
28031
|
build: (c) => {
|
|
@@ -27756,7 +28050,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
|
|
|
27756
28050
|
c.ellipse(cr.x + ex, cr.y + ey, ex, ey, 0, 2 * q, 3 * q);
|
|
27757
28051
|
c.closePath();
|
|
27758
28052
|
},
|
|
27759
|
-
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch),
|
|
28053
|
+
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0),
|
|
27760
28054
|
roundPen: true,
|
|
27761
28055
|
fill: true,
|
|
27762
28056
|
stroke: true
|
|
@@ -27773,24 +28067,31 @@ function wmfEllipse(p, l, t, r, b) {
|
|
|
27773
28067
|
c.beginPath();
|
|
27774
28068
|
c.ellipse(cr.x + cr.w / 2, cr.y + cr.h / 2, cr.w / 2, cr.h / 2, 0, 0, Math.PI * 2);
|
|
27775
28069
|
},
|
|
27776
|
-
raster: () => ellipseRasterPath(fixBoxOf(box)),
|
|
28070
|
+
raster: () => ellipseRasterPath(fixBoxOf(box), clockwiseOf(p)),
|
|
27777
28071
|
roundPen: true,
|
|
27778
28072
|
fill: true,
|
|
27779
28073
|
stroke: true
|
|
27780
28074
|
});
|
|
27781
28075
|
}
|
|
27782
|
-
function
|
|
27783
|
-
const box = compatBox(p, l, t, r, b, { curved: kind
|
|
28076
|
+
function compatArc(p, kind, l, t, r, b, xs, ys, xe, ye) {
|
|
28077
|
+
const box = compatBox(p, l, t, r, b, { curved: kind === "chord" || kind === "pie" });
|
|
27784
28078
|
if (box.x1 < box.x0 || box.y1 < box.y0) {
|
|
27785
|
-
return;
|
|
28079
|
+
return null;
|
|
27786
28080
|
}
|
|
27787
28081
|
const raw = compatBox(p, l, t, r, b, { exclusive: false });
|
|
27788
|
-
const
|
|
27789
|
-
const
|
|
27790
|
-
|
|
27791
|
-
|
|
27792
|
-
|
|
27793
|
-
|
|
28082
|
+
const onBox = (v, r0, r1, b0, b1) => (b0 + b1) / 2 + (r1 !== r0 ? (v - (r0 + r1) / 2) * (b1 - b0) / (r1 - r0) : v - (r0 + r1) / 2);
|
|
28083
|
+
const radial = (x, y) => {
|
|
28084
|
+
const [fx, fy] = fixPoint(p.rCtx, x, y);
|
|
28085
|
+
return [onBox(fx, raw.x0, raw.x1, box.x0, box.x1), onBox(fy, raw.y0, raw.y1, box.y0, box.y1)];
|
|
28086
|
+
};
|
|
28087
|
+
return { box, s: radial(xs, ys), e: radial(xe, ye) };
|
|
28088
|
+
}
|
|
28089
|
+
function wmfArcFamily(p, kind, l, t, r, b, xs, ys, xe, ye) {
|
|
28090
|
+
const geom = compatArc(p, kind, l, t, r, b, xs, ys, xe, ye);
|
|
28091
|
+
if (!geom) {
|
|
28092
|
+
return;
|
|
28093
|
+
}
|
|
28094
|
+
const { box, s, e } = geom;
|
|
27794
28095
|
const clockwise = p.rCtx.state.arcDirection === 2;
|
|
27795
28096
|
const cr = canvasRect(box);
|
|
27796
28097
|
const cx = cr.x + cr.w / 2;
|
|
@@ -27816,6 +28117,9 @@ function wmfArcFamily(p, kind, l, t, r, b, xs, ys, xe, ye) {
|
|
|
27816
28117
|
stroke: true
|
|
27817
28118
|
});
|
|
27818
28119
|
}
|
|
28120
|
+
function clockwiseOf(p) {
|
|
28121
|
+
return p.rCtx.state.arcDirection === 2;
|
|
28122
|
+
}
|
|
27819
28123
|
function penIsNull(p) {
|
|
27820
28124
|
return (p.rCtx.state.penStyle & 15) === PS_NULL3;
|
|
27821
28125
|
}
|