emf-converter 4.7.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +595 -253
- package/dist/browser.mjs +595 -253
- package/dist/index.js +595 -253
- package/dist/index.mjs +595 -253
- package/package.json +1 -1
package/dist/browser.mjs
CHANGED
|
@@ -11773,19 +11773,73 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = fa
|
|
|
11773
11773
|
];
|
|
11774
11774
|
}
|
|
11775
11775
|
var TRIG_STEP = 2 * Math.PI / 128;
|
|
11776
|
-
|
|
11776
|
+
var TRIG_NODES = [
|
|
11777
|
+
1,
|
|
11778
|
+
0.99879566,
|
|
11779
|
+
0.99518639,
|
|
11780
|
+
0.98917961,
|
|
11781
|
+
0.98079146,
|
|
11782
|
+
0.97003981,
|
|
11783
|
+
0.95695228,
|
|
11784
|
+
0.94155978,
|
|
11785
|
+
0.92389844,
|
|
11786
|
+
0.90401145,
|
|
11787
|
+
0.88194619,
|
|
11788
|
+
0.85775575,
|
|
11789
|
+
0.83149879,
|
|
11790
|
+
0.80323775,
|
|
11791
|
+
0.77303903,
|
|
11792
|
+
0.74098864,
|
|
11793
|
+
0.70710648,
|
|
11794
|
+
0.67151859,
|
|
11795
|
+
0.63435836,
|
|
11796
|
+
0.59565849,
|
|
11797
|
+
0.55552672,
|
|
11798
|
+
0.51405765,
|
|
11799
|
+
0.47135039,
|
|
11800
|
+
0.42750875,
|
|
11801
|
+
0.38263811,
|
|
11802
|
+
0.33684632,
|
|
11803
|
+
0.29024443,
|
|
11804
|
+
0.24294646,
|
|
11805
|
+
0.19505974,
|
|
11806
|
+
0.14670808,
|
|
11807
|
+
0.0980012,
|
|
11808
|
+
0.04906089,
|
|
11809
|
+
0
|
|
11810
|
+
];
|
|
11811
|
+
var TRIG_TABLE = (() => {
|
|
11812
|
+
const cos = [];
|
|
11813
|
+
const sin = [];
|
|
11814
|
+
for (let k = 0; k <= 128; k++) {
|
|
11815
|
+
const q = k >> 5;
|
|
11816
|
+
const i = k & 31;
|
|
11817
|
+
const c = TRIG_NODES[i];
|
|
11818
|
+
const s = TRIG_NODES[32 - i];
|
|
11819
|
+
if (k === 128) {
|
|
11820
|
+
cos.push(1);
|
|
11821
|
+
sin.push(0);
|
|
11822
|
+
continue;
|
|
11823
|
+
}
|
|
11824
|
+
cos.push([c, -s, -c, s][q]);
|
|
11825
|
+
sin.push([s, c, -s, -c][q]);
|
|
11826
|
+
}
|
|
11827
|
+
return { cos, sin };
|
|
11828
|
+
})();
|
|
11829
|
+
function tableTrig(table) {
|
|
11777
11830
|
return (a) => {
|
|
11778
11831
|
let b = a % (2 * Math.PI);
|
|
11779
11832
|
if (b < 0) {
|
|
11780
11833
|
b += 2 * Math.PI;
|
|
11781
11834
|
}
|
|
11782
|
-
const
|
|
11783
|
-
const
|
|
11784
|
-
|
|
11835
|
+
const x = b / TRIG_STEP;
|
|
11836
|
+
const i = Math.min(127, Math.floor(x));
|
|
11837
|
+
const f = x - i;
|
|
11838
|
+
return table[i] * (1 - f) + table[i + 1] * f;
|
|
11785
11839
|
};
|
|
11786
11840
|
}
|
|
11787
|
-
var tableCos = tableTrig(
|
|
11788
|
-
var tableSin = tableTrig(
|
|
11841
|
+
var tableCos = tableTrig(TRIG_TABLE.cos);
|
|
11842
|
+
var tableSin = tableTrig(TRIG_TABLE.sin);
|
|
11789
11843
|
function angleArcPieces(startDeg, sweepDeg) {
|
|
11790
11844
|
const out = [];
|
|
11791
11845
|
const arc = (from, to) => {
|
|
@@ -11856,6 +11910,38 @@ function angleArcFix(box, startDeg, sweepDeg) {
|
|
|
11856
11910
|
}
|
|
11857
11911
|
return out;
|
|
11858
11912
|
}
|
|
11913
|
+
var SMALL_SWEEP = 3 * Math.PI / 180;
|
|
11914
|
+
function anchoredPiece(boundary, free, rx, ry, cx, cy, smallArc) {
|
|
11915
|
+
const sweep = Math.abs(free - boundary);
|
|
11916
|
+
const small = smallArc;
|
|
11917
|
+
const cos = small ? Math.cos : tableCos;
|
|
11918
|
+
const sin = small ? Math.sin : tableSin;
|
|
11919
|
+
const anchor = [Math.round(cx + rx * Math.cos(boundary)), Math.round(cy - ry * Math.sin(boundary))];
|
|
11920
|
+
const point = [cx + rx * cos(free), cy - ry * sin(free)];
|
|
11921
|
+
let t;
|
|
11922
|
+
let kappa;
|
|
11923
|
+
if (small) {
|
|
11924
|
+
t = Math.tan(sweep / 2);
|
|
11925
|
+
kappa = 2 / 3 * (1 - Math.tan(sweep / 4) ** 2);
|
|
11926
|
+
} else {
|
|
11927
|
+
const c = tableCos(sweep);
|
|
11928
|
+
const sn = tableSin(sweep);
|
|
11929
|
+
t = (1 - c) / sn;
|
|
11930
|
+
const q = t / (1 + Math.sqrt(1 + t * t));
|
|
11931
|
+
kappa = 2 / 3 * (1 - q * q);
|
|
11932
|
+
}
|
|
11933
|
+
const dir = free > boundary ? 1 : -1;
|
|
11934
|
+
const tx = -Math.round(Math.sin(boundary));
|
|
11935
|
+
const ty = -Math.round(Math.cos(boundary));
|
|
11936
|
+
const length = tx !== 0 ? rx : ry;
|
|
11937
|
+
const X = [anchor[0] + dir * tx * length * t, anchor[1] + dir * ty * length * t];
|
|
11938
|
+
return {
|
|
11939
|
+
anchor,
|
|
11940
|
+
free: point,
|
|
11941
|
+
cAnchor: [anchor[0] + kappa * (X[0] - anchor[0]), anchor[1] + kappa * (X[1] - anchor[1])],
|
|
11942
|
+
cFree: [point[0] + kappa * (X[0] - point[0]), point[1] + kappa * (X[1] - point[1])]
|
|
11943
|
+
};
|
|
11944
|
+
}
|
|
11859
11945
|
function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
|
|
11860
11946
|
const w = r - l;
|
|
11861
11947
|
const h = b - t;
|
|
@@ -11894,6 +11980,21 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
|
|
|
11894
11980
|
continue;
|
|
11895
11981
|
}
|
|
11896
11982
|
const e = s > 0 ? Math.min(next, a1) : Math.max(next, a1);
|
|
11983
|
+
const endOnBoundary = Math.abs(e / Q - Math.round(e / Q)) < 1e-9;
|
|
11984
|
+
if (onBoundary !== endOnBoundary) {
|
|
11985
|
+
const piece = anchoredPiece(onBoundary ? a : e, onBoundary ? e : a, rx, ry, cx, cy, Math.abs(a1 - a0) <= SMALL_SWEEP);
|
|
11986
|
+
if (onBoundary) {
|
|
11987
|
+
out.push(...[piece.cAnchor, piece.cFree, piece.free].flatMap((q) => [Math.round(q[0]), Math.round(q[1])]));
|
|
11988
|
+
} else {
|
|
11989
|
+
if (out.length === 2) {
|
|
11990
|
+
out[0] = Math.round(piece.free[0]);
|
|
11991
|
+
out[1] = Math.round(piece.free[1]);
|
|
11992
|
+
}
|
|
11993
|
+
out.push(...[piece.cFree, piece.cAnchor, piece.anchor].flatMap((q) => [Math.round(q[0]), Math.round(q[1])]));
|
|
11994
|
+
}
|
|
11995
|
+
a = e;
|
|
11996
|
+
continue;
|
|
11997
|
+
}
|
|
11897
11998
|
const k = 4 / 3 * Math.tan((e - a) / 4);
|
|
11898
11999
|
out.push(
|
|
11899
12000
|
Math.round(px(a) - k * rx * tableSin(a)),
|
|
@@ -11988,6 +12089,10 @@ var GdiRasterPath = class {
|
|
|
11988
12089
|
};
|
|
11989
12090
|
const t0 = tangent(x0, y0, c1x, c1y, c2x, c2y, x3, y3);
|
|
11990
12091
|
const t1 = tangent(c2x, c2y, x3, y3, x3, y3, x3, y3) ?? tangent(c1x, c1y, x3, y3, x3, y3, x3, y3) ?? tangent(x0, y0, x3, y3, x3, y3, x3, y3);
|
|
12092
|
+
f.curveSegs ?? (f.curveSegs = /* @__PURE__ */ new Set());
|
|
12093
|
+
for (let k = first; k <= last; k++) {
|
|
12094
|
+
f.curveSegs.add(k);
|
|
12095
|
+
}
|
|
11991
12096
|
f.tangents ?? (f.tangents = /* @__PURE__ */ new Map());
|
|
11992
12097
|
if (t0) f.tangents.set(first, t0);
|
|
11993
12098
|
if (t1) f.tangents.set(last, t1);
|
|
@@ -12021,7 +12126,7 @@ var GdiRasterPath = class {
|
|
|
12021
12126
|
/** Appends every figure of `other`. */
|
|
12022
12127
|
append(other) {
|
|
12023
12128
|
for (const f of other.figures) {
|
|
12024
|
-
this.figures.push({ pts: f.pts.slice(), closed: f.closed, tangents: f.tangents && new Map(f.tangents), roundWiden: f.roundWiden });
|
|
12129
|
+
this.figures.push({ pts: f.pts.slice(), closed: f.closed, tangents: f.tangents && new Map(f.tangents), curveSegs: f.curveSegs && new Set(f.curveSegs), roundWiden: f.roundWiden });
|
|
12025
12130
|
}
|
|
12026
12131
|
for (let i = 0; i < other.getPath.types.length; i++) {
|
|
12027
12132
|
this.log(other.getPath.pts[2 * i], other.getPath.pts[2 * i + 1], other.getPath.types[i]);
|
|
@@ -16438,23 +16543,241 @@ function applyTint(src, hue, amount) {
|
|
|
16438
16543
|
function applyRedEyeCorrection(src, width, height, areas) {
|
|
16439
16544
|
const out = new Uint8ClampedArray(src);
|
|
16440
16545
|
for (const a of areas) {
|
|
16441
|
-
|
|
16442
|
-
|
|
16443
|
-
|
|
16444
|
-
|
|
16445
|
-
|
|
16446
|
-
|
|
16447
|
-
|
|
16448
|
-
|
|
16449
|
-
|
|
16450
|
-
|
|
16451
|
-
|
|
16452
|
-
|
|
16546
|
+
correctRedEyeArea(out, width, clamp(a.left, 0, width), clamp(a.top, 0, height), clamp(a.right, 0, width), clamp(a.bottom, 0, height));
|
|
16547
|
+
}
|
|
16548
|
+
return out;
|
|
16549
|
+
}
|
|
16550
|
+
var RED_EYE_FALLOFF = new Float64Array(
|
|
16551
|
+
[
|
|
16552
|
+
24930,
|
|
16553
|
+
24570,
|
|
16554
|
+
24201,
|
|
16555
|
+
23836,
|
|
16556
|
+
23471,
|
|
16557
|
+
23107,
|
|
16558
|
+
22744,
|
|
16559
|
+
22367,
|
|
16560
|
+
21976,
|
|
16561
|
+
21587,
|
|
16562
|
+
21198,
|
|
16563
|
+
20824,
|
|
16564
|
+
20490,
|
|
16565
|
+
20165,
|
|
16566
|
+
19832,
|
|
16567
|
+
19499,
|
|
16568
|
+
19157,
|
|
16569
|
+
18817,
|
|
16570
|
+
18480,
|
|
16571
|
+
18151,
|
|
16572
|
+
17820,
|
|
16573
|
+
17490,
|
|
16574
|
+
17160,
|
|
16575
|
+
16831,
|
|
16576
|
+
16506,
|
|
16577
|
+
16189,
|
|
16578
|
+
15878,
|
|
16579
|
+
15569,
|
|
16580
|
+
15273,
|
|
16581
|
+
14973,
|
|
16582
|
+
14668,
|
|
16583
|
+
14362,
|
|
16584
|
+
14059,
|
|
16585
|
+
13768,
|
|
16586
|
+
13484,
|
|
16587
|
+
13203,
|
|
16588
|
+
12923,
|
|
16589
|
+
12642,
|
|
16590
|
+
12366,
|
|
16591
|
+
12094,
|
|
16592
|
+
11828,
|
|
16593
|
+
11564,
|
|
16594
|
+
11301,
|
|
16595
|
+
11034,
|
|
16596
|
+
10770,
|
|
16597
|
+
10507,
|
|
16598
|
+
10253,
|
|
16599
|
+
10011,
|
|
16600
|
+
9771,
|
|
16601
|
+
9530,
|
|
16602
|
+
9290,
|
|
16603
|
+
9053,
|
|
16604
|
+
8819,
|
|
16605
|
+
8588,
|
|
16606
|
+
8359,
|
|
16607
|
+
8134,
|
|
16608
|
+
7914,
|
|
16609
|
+
7697,
|
|
16610
|
+
7481,
|
|
16611
|
+
7267,
|
|
16612
|
+
7056,
|
|
16613
|
+
6851,
|
|
16614
|
+
6651,
|
|
16615
|
+
6453,
|
|
16616
|
+
6256,
|
|
16617
|
+
6061,
|
|
16618
|
+
5871,
|
|
16619
|
+
5684,
|
|
16620
|
+
5499,
|
|
16621
|
+
5317,
|
|
16622
|
+
5138,
|
|
16623
|
+
4962,
|
|
16624
|
+
4789,
|
|
16625
|
+
4619,
|
|
16626
|
+
4452,
|
|
16627
|
+
4289,
|
|
16628
|
+
4130,
|
|
16629
|
+
3974,
|
|
16630
|
+
3820,
|
|
16631
|
+
3669,
|
|
16632
|
+
3520,
|
|
16633
|
+
3375,
|
|
16634
|
+
3232,
|
|
16635
|
+
3093,
|
|
16636
|
+
2958,
|
|
16637
|
+
2825,
|
|
16638
|
+
2695,
|
|
16639
|
+
2568,
|
|
16640
|
+
2444,
|
|
16641
|
+
2325,
|
|
16642
|
+
2207,
|
|
16643
|
+
2092,
|
|
16644
|
+
1980,
|
|
16645
|
+
1872,
|
|
16646
|
+
1768,
|
|
16647
|
+
1666,
|
|
16648
|
+
1567,
|
|
16649
|
+
1470,
|
|
16650
|
+
1377,
|
|
16651
|
+
1287,
|
|
16652
|
+
1200,
|
|
16653
|
+
1116,
|
|
16654
|
+
1034,
|
|
16655
|
+
956,
|
|
16656
|
+
881,
|
|
16657
|
+
808,
|
|
16658
|
+
739,
|
|
16659
|
+
674,
|
|
16660
|
+
612,
|
|
16661
|
+
541,
|
|
16662
|
+
462,
|
|
16663
|
+
381,
|
|
16664
|
+
299,
|
|
16665
|
+
220,
|
|
16666
|
+
147,
|
|
16667
|
+
85,
|
|
16668
|
+
36,
|
|
16669
|
+
3,
|
|
16670
|
+
0
|
|
16671
|
+
].map((v) => v / 1e5)
|
|
16672
|
+
);
|
|
16673
|
+
function redEyeFalloff(u) {
|
|
16674
|
+
const t = u * 128;
|
|
16675
|
+
const i = Math.floor(t);
|
|
16676
|
+
if (i >= RED_EYE_FALLOFF.length - 1) {
|
|
16677
|
+
return 0;
|
|
16678
|
+
}
|
|
16679
|
+
return RED_EYE_FALLOFF[i] + (t - i) * (RED_EYE_FALLOFF[i + 1] - RED_EYE_FALLOFF[i]);
|
|
16680
|
+
}
|
|
16681
|
+
var RED_EYE_SECTORS = 60;
|
|
16682
|
+
var RED_EYE_BLUE_WEIGHT = 0.225;
|
|
16683
|
+
var RED_EYE_WEIGHT_CAP = 6;
|
|
16684
|
+
var RED_EYE_PURE_WEIGHT = RED_EYE_WEIGHT_CAP;
|
|
16685
|
+
var RED_EYE_DARK_STRENGTH = 0.49;
|
|
16686
|
+
var RED_EYE_DARK_RATIO = 0.6;
|
|
16687
|
+
var RED_EYE_GREEN_SHARE = 80 / 255;
|
|
16688
|
+
function correctRedEyeArea(out, stride, x0, y0, x1, y1) {
|
|
16689
|
+
const w = x1 - x0;
|
|
16690
|
+
const h = y1 - y0;
|
|
16691
|
+
const count = w * h;
|
|
16692
|
+
const redness = new Float64Array(count);
|
|
16693
|
+
const dark = new Float64Array(count);
|
|
16694
|
+
let sx = 0;
|
|
16695
|
+
let sy = 0;
|
|
16696
|
+
let sw = 0;
|
|
16697
|
+
for (let y = 0; y < h; y++) {
|
|
16698
|
+
for (let x = 0; x < w; x++) {
|
|
16699
|
+
const i = ((y0 + y) * stride + x0 + x) * 4;
|
|
16700
|
+
const r = out[i];
|
|
16701
|
+
const g = out[i + 1];
|
|
16702
|
+
const b = out[i + 2];
|
|
16703
|
+
const k = y * w + x;
|
|
16704
|
+
dark[k] = Math.min(g, b);
|
|
16705
|
+
const v = r - Math.max(g, b);
|
|
16706
|
+
if (v > 0) {
|
|
16707
|
+
redness[k] = v;
|
|
16708
|
+
const denominator = g + RED_EYE_BLUE_WEIGHT * b;
|
|
16709
|
+
{
|
|
16710
|
+
const weight = denominator >= 1 ? Math.min(RED_EYE_WEIGHT_CAP, v / denominator) : RED_EYE_PURE_WEIGHT;
|
|
16711
|
+
sx += weight * (x + 0.5);
|
|
16712
|
+
sy += weight * (y + 0.5);
|
|
16713
|
+
sw += weight;
|
|
16453
16714
|
}
|
|
16454
16715
|
}
|
|
16455
16716
|
}
|
|
16456
16717
|
}
|
|
16457
|
-
|
|
16718
|
+
if (sw === 0) {
|
|
16719
|
+
if (!redness.some((v) => v > 0)) {
|
|
16720
|
+
return;
|
|
16721
|
+
}
|
|
16722
|
+
sx = w / 2;
|
|
16723
|
+
sy = h / 2;
|
|
16724
|
+
sw = 1;
|
|
16725
|
+
}
|
|
16726
|
+
const cx = sx / sw;
|
|
16727
|
+
const cy = sy / sw;
|
|
16728
|
+
const radius = Math.min(cx, cy) - 0.5;
|
|
16729
|
+
if (!(radius > 0)) {
|
|
16730
|
+
return;
|
|
16731
|
+
}
|
|
16732
|
+
const sector = new Uint8Array(count);
|
|
16733
|
+
const distance = new Float64Array(count);
|
|
16734
|
+
const sectorSum = new Float64Array(RED_EYE_SECTORS);
|
|
16735
|
+
const sectorDark = new Float64Array(RED_EYE_SECTORS);
|
|
16736
|
+
const sectorCount = new Float64Array(RED_EYE_SECTORS);
|
|
16737
|
+
const degrees = 180 / Math.PI;
|
|
16738
|
+
for (let y = 0; y < h; y++) {
|
|
16739
|
+
for (let x = 0; x < w; x++) {
|
|
16740
|
+
const dx = x + 0.5 - cx;
|
|
16741
|
+
const dy = y + 0.5 - cy;
|
|
16742
|
+
const k = y * w + x;
|
|
16743
|
+
const d = Math.hypot(dx, dy);
|
|
16744
|
+
distance[k] = d;
|
|
16745
|
+
let angle = Math.atan2(dy, dx) * degrees;
|
|
16746
|
+
if (angle < 0) {
|
|
16747
|
+
angle += 360;
|
|
16748
|
+
}
|
|
16749
|
+
const s = Math.min(RED_EYE_SECTORS - 1, Math.floor(angle / 6));
|
|
16750
|
+
sector[k] = s;
|
|
16751
|
+
if (d < radius) {
|
|
16752
|
+
sectorSum[s] += redness[k];
|
|
16753
|
+
sectorDark[s] += dark[k];
|
|
16754
|
+
sectorCount[s]++;
|
|
16755
|
+
}
|
|
16756
|
+
}
|
|
16757
|
+
}
|
|
16758
|
+
for (let y = 0; y < h; y++) {
|
|
16759
|
+
for (let x = 0; x < w; x++) {
|
|
16760
|
+
const k = y * w + x;
|
|
16761
|
+
const v = redness[k];
|
|
16762
|
+
if (v <= 0 || distance[k] >= radius) {
|
|
16763
|
+
continue;
|
|
16764
|
+
}
|
|
16765
|
+
const s = sector[k];
|
|
16766
|
+
const mean = sectorSum[s] / sectorCount[s];
|
|
16767
|
+
const meanDark = sectorDark[s] / sectorCount[s];
|
|
16768
|
+
const ratio = meanDark > 0 ? dark[k] / meanDark : 1;
|
|
16769
|
+
const falloff = Math.max(redEyeFalloff(distance[k] / radius), RED_EYE_DARK_STRENGTH * Math.max(0, 1 - ratio / RED_EYE_DARK_RATIO));
|
|
16770
|
+
const rest = (1 - falloff) * mean;
|
|
16771
|
+
if (rest >= v) {
|
|
16772
|
+
continue;
|
|
16773
|
+
}
|
|
16774
|
+
const removed = v - rest;
|
|
16775
|
+
const i = ((y0 + y) * stride + x0 + x) * 4;
|
|
16776
|
+
out[i] = Math.round(out[i] - (1 - RED_EYE_GREEN_SHARE) * removed);
|
|
16777
|
+
out[i + 1] = Math.round(out[i + 1] + RED_EYE_GREEN_SHARE * removed);
|
|
16778
|
+
out[i + 2] = Math.round(out[i + 2] + RED_EYE_GREEN_SHARE * removed);
|
|
16779
|
+
}
|
|
16780
|
+
}
|
|
16458
16781
|
}
|
|
16459
16782
|
function blurKernel(radius) {
|
|
16460
16783
|
const taps = Math.ceil(radius);
|
|
@@ -16486,8 +16809,8 @@ function mirror(p, n) {
|
|
|
16486
16809
|
function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, verticalRows = Math.ceil(h / w)) {
|
|
16487
16810
|
const k = blurKernel(radius);
|
|
16488
16811
|
const taps = (k.length - 1) / 2;
|
|
16489
|
-
const horizontalIndex = taps >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
|
|
16490
|
-
const verticalIndex = taps >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
|
|
16812
|
+
const horizontalIndex = (taps | 1) >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
|
|
16813
|
+
const verticalIndex = (taps | 1) >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
|
|
16491
16814
|
const out = new Float64Array(w * h * 4);
|
|
16492
16815
|
for (let y = 0; y < h; y++) {
|
|
16493
16816
|
const row2 = y * w * 4;
|
|
@@ -16498,11 +16821,12 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, verticalRows
|
|
|
16498
16821
|
let s3 = 0;
|
|
16499
16822
|
for (let j = -taps; j <= taps; j++) {
|
|
16500
16823
|
const p = row2 + horizontalIndex(x + j) * 4;
|
|
16501
|
-
const kw = k[j + taps] * 256;
|
|
16502
|
-
|
|
16503
|
-
|
|
16504
|
-
|
|
16505
|
-
|
|
16824
|
+
const kw = j === 0 ? k[taps] * 128 : k[j + taps] * 256;
|
|
16825
|
+
const times = j === 0 ? 2 : 1;
|
|
16826
|
+
s0 += times * Math.round(kw * src[p]);
|
|
16827
|
+
s1 += times * Math.round(kw * src[p + 1]);
|
|
16828
|
+
s2 += times * Math.round(kw * src[p + 2]);
|
|
16829
|
+
s3 += times * Math.round(kw * src[p + 3]);
|
|
16506
16830
|
}
|
|
16507
16831
|
const o = row2 + x * 4;
|
|
16508
16832
|
out[o] = Math.floor((s0 + 128) / 256);
|
|
@@ -16522,8 +16846,10 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, verticalRows
|
|
|
16522
16846
|
continue;
|
|
16523
16847
|
}
|
|
16524
16848
|
const base = verticalIndex(yy) * w * 4;
|
|
16849
|
+
const kw = j === 0 ? k[taps] * 128 : k[j + taps] * 256;
|
|
16850
|
+
const times = j === 0 ? 2 : 1;
|
|
16525
16851
|
for (let i = 0; i < w * 4; i++) {
|
|
16526
|
-
col[i] += Math.round(
|
|
16852
|
+
col[i] += times * Math.round(kw * horizontal[base + i]) / 256;
|
|
16527
16853
|
}
|
|
16528
16854
|
}
|
|
16529
16855
|
out.set(col, row2 * w * 4);
|
|
@@ -16538,10 +16864,12 @@ function blurAxis(length, lanes, factor, k, edgeLength, get, put, span = { start
|
|
|
16538
16864
|
const inner = Math.ceil(span.size / factor);
|
|
16539
16865
|
const n = inner + 2 * span.pad;
|
|
16540
16866
|
const taps = (k.length - 1) / 2;
|
|
16541
|
-
const index = taps >= edgeLength ? (i) => clamp(i, 0, n - 1) : (i) => mirror(i, n);
|
|
16867
|
+
const index = (taps | 1) >= edgeLength ? (i) => clamp(i, 0, n - 1) : (i) => mirror(i, n);
|
|
16542
16868
|
const reduced = new Float64Array(n);
|
|
16543
16869
|
const filtered = new Float64Array(n);
|
|
16544
16870
|
const k256 = k.map((w) => w * 256);
|
|
16871
|
+
const half = k256[taps] / 2;
|
|
16872
|
+
k256[taps] = 0;
|
|
16545
16873
|
for (let lane = 0; lane < lanes; lane++) for (let c = 0; c < 4; c++) {
|
|
16546
16874
|
for (let b = span.pad; b < span.pad + inner; b++) {
|
|
16547
16875
|
const from = span.start + (b - span.pad) * factor;
|
|
@@ -16555,33 +16883,48 @@ function blurAxis(length, lanes, factor, k, edgeLength, get, put, span = { start
|
|
|
16555
16883
|
if (b >= taps && b + taps < n) {
|
|
16556
16884
|
for (let j = 0; j < k256.length; j++) sum += Math.round(k256[j] * reduced[b - taps + j]);
|
|
16557
16885
|
} else {
|
|
16558
|
-
for (let j = 0; j < k256.length; j++)
|
|
16886
|
+
for (let j = 0; j < k256.length; j++) {
|
|
16887
|
+
const at = b - taps + j;
|
|
16888
|
+
sum += Math.round(k256[j] * (span.zeroOutside && (at < 0 || at >= n) ? 0 : reduced[index(at)]));
|
|
16889
|
+
}
|
|
16559
16890
|
}
|
|
16891
|
+
sum += 2 * Math.round(half * reduced[b]);
|
|
16560
16892
|
filtered[b] = Math.floor((sum + 128) / 256);
|
|
16561
16893
|
}
|
|
16894
|
+
const lone = inner === 1 && span.pad > 0;
|
|
16895
|
+
const skipped2 = inner === 1 && span.size - Math.ceil(factor / 2) === 1 ? span.start + span.size - 1 : -1;
|
|
16562
16896
|
for (let i = 0; i < length; i++) {
|
|
16563
|
-
|
|
16564
|
-
|
|
16897
|
+
if (i === skipped2) {
|
|
16898
|
+
if (span.pad > 0) put(i, lane, c, 0);
|
|
16899
|
+
continue;
|
|
16900
|
+
}
|
|
16901
|
+
const p = (i - span.start + 0.5) / factor - 0.5;
|
|
16902
|
+
if (lone) {
|
|
16903
|
+
const distance = Math.abs(i - span.start - (Math.min(span.size, factor / 2) - 0.5)) / factor;
|
|
16904
|
+
put(i, lane, c, clamp(Math.floor((1 + distance) * filtered[span.pad] + 1e-9), 0, 255));
|
|
16905
|
+
continue;
|
|
16906
|
+
}
|
|
16907
|
+
const a = clamp(Math.floor(p), 0, Math.max(0, inner - 2));
|
|
16565
16908
|
const t = p - a;
|
|
16566
|
-
put(i, lane, c, clamp(Math.floor((1 - t) * filtered[a] + t * filtered[Math.min(
|
|
16909
|
+
put(i, lane, c, clamp(Math.floor((1 - t) * filtered[span.pad + a] + t * filtered[span.pad + Math.min(inner - 1, a + 1)] + 1e-9), 0, 255));
|
|
16567
16910
|
}
|
|
16568
16911
|
}
|
|
16569
16912
|
}
|
|
16570
|
-
function effectBlur(src, width, height, radius, region) {
|
|
16913
|
+
function effectBlur(src, width, height, radius, region, expanded = false) {
|
|
16571
16914
|
const factor = blurReduction(radius);
|
|
16572
16915
|
if (factor === 1) {
|
|
16573
16916
|
return gdipBlur(src, width, height, radius);
|
|
16574
16917
|
}
|
|
16575
16918
|
const k = blurKernel(radius / factor);
|
|
16576
16919
|
const pad = region ? Math.ceil(Math.ceil(radius) / factor) : 0;
|
|
16577
|
-
const spanX = region ? { start: region.x, size: region.w, pad } : void 0;
|
|
16578
|
-
const spanY = region ? { start: region.y, size: region.h, pad } : void 0;
|
|
16579
|
-
const rows = new Uint8Array(src
|
|
16580
|
-
blurAxis(width, height, factor, k, Math.
|
|
16920
|
+
const spanX = region ? { start: region.x, size: region.w, pad, zeroOutside: true } : expanded ? { start: 0, size: width, pad: 0, zeroOutside: true } : void 0;
|
|
16921
|
+
const spanY = region ? { start: region.y, size: region.h, pad, zeroOutside: true } : expanded ? { start: 0, size: height, pad: 0, zeroOutside: true } : void 0;
|
|
16922
|
+
const rows = new Uint8Array(src);
|
|
16923
|
+
blurAxis(width, height, factor, k, Math.ceil(width / factor), (i, lane, c) => src[(lane * width + i) * 4 + c], (i, lane, c, v) => {
|
|
16581
16924
|
rows[(lane * width + i) * 4 + c] = v;
|
|
16582
16925
|
}, spanX);
|
|
16583
|
-
const out =
|
|
16584
|
-
blurAxis(height, width, factor, k, Math.
|
|
16926
|
+
const out = Float64Array.from(rows);
|
|
16927
|
+
blurAxis(height, width, factor, k, Math.ceil(height / factor), (i, lane, c) => rows[(i * width + lane) * 4 + c], (i, lane, c, v) => {
|
|
16585
16928
|
out[(i * width + lane) * 4 + c] = v;
|
|
16586
16929
|
}, spanY);
|
|
16587
16930
|
return out;
|
|
@@ -16669,7 +17012,7 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
|
|
|
16669
17012
|
const gy1 = Math.min(height, y1 + r);
|
|
16670
17013
|
copyBlock(rgba, width, gx0, gy0, gx1 - gx0, gy1 - gy0, buf, bw, gx0 - (x0 - r), gy0 - (y0 - r));
|
|
16671
17014
|
}
|
|
16672
|
-
const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, cropped ? { x: r, y: r, w: x1 - x0, h: y1 - y0 } : void 0) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, Math.ceil((y1 - y0) / (x1 - x0)));
|
|
17015
|
+
const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, cropped ? { x: r, y: r, w: x1 - x0, h: y1 - y0 } : void 0, true) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, Math.ceil((y1 - y0) / (x1 - x0)));
|
|
16673
17016
|
const w = x1 - x0;
|
|
16674
17017
|
const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
|
|
16675
17018
|
for (let y = 0; y < y1 - y0; y++) {
|
|
@@ -28734,118 +29077,19 @@ var HOBBY = [
|
|
|
28734
29077
|
[[8, -48], [-8, -48], [-24, -40], [-40, -24], [-48, -8], [-48, 8], [-40, 24], [-24, 40], [-8, 48], [8, 48], [24, 40], [40, 24], [48, 8], [48, -8], [40, -24], [24, -40]]
|
|
28735
29078
|
];
|
|
28736
29079
|
var HOBBY_LIMIT = 104;
|
|
28737
|
-
|
|
28738
|
-
|
|
28739
|
-
8: [9, "dFee", "ededededbdbdbd"],
|
|
28740
|
-
9: [9, "df..", "ddddddddbDbdbd"],
|
|
28741
|
-
10: [9, "de..", "dededeDebEbebE"],
|
|
28742
|
-
11: [9, "ce..", "eeeeeeEececece"],
|
|
28743
|
-
12: [13, "ce..", "eeeeeeeeeeeececEcecece"],
|
|
28744
|
-
13: [17, "ce..", "eeeeededdddddeDebebebdbdcdcdce"],
|
|
28745
|
-
14: [17, "df..", "ddedeeeededeeeedcDcebebecececd"],
|
|
28746
|
-
15: [17, "dF..", "ddedeeeeeeeedeDdbdbecececececd"],
|
|
28747
|
-
16: [17, "ce..", "eeeededededeeeeececebebebebece"],
|
|
28748
|
-
17: [17, "df..", "ddedededededdeddbdbebdbdbdbdcd"],
|
|
28749
|
-
18: [17, "de..", "deeededeededeeEdcDcecdcdbebece"],
|
|
28750
|
-
19: [17, "cf..", "ededeeeedddddeDebEbecdcdbebecd"],
|
|
28751
|
-
20: [17, "ce..", "eeeeddddeeeeddDdbdbdcecebdbdce"],
|
|
28752
|
-
21: [17, "dF..", "ddddededededddDdbdbdcdcdcdcdbd"],
|
|
28753
|
-
22: [17, "ce..", "eeeededeeeeedeDebebececebebece"],
|
|
28754
|
-
23: [17, "cf..", "edededededededEdcDcdcdcdcdcdcD"],
|
|
28755
|
-
24: [17, "dF..", "ddddddddddddddDdbdbdbdbdbdbdbd"],
|
|
28756
|
-
25: [17, "cE..", "eeeeededededeeEecEcecdcdcdcdce"],
|
|
28757
|
-
26: [17, "cf..", "ededdedeededdedebEbecdcdbebecd"],
|
|
28758
|
-
27: [17, "de..", "dedeededdedeededcDcdbebecdcdbe"],
|
|
28759
|
-
28: [17, "cf..", "ededddddeeeedeDebEbebebecdcdcd"],
|
|
28760
|
-
29: [17, "ce..", "eeeeeeeededededebebebebececece"],
|
|
28761
|
-
30: [17, "dF..", "dddddedeeeeeedEdcdcdcecebebebd"],
|
|
28762
|
-
31: [17, "de..", "dedeededededdeDebebecdcdcdcdbe"],
|
|
28763
|
-
32: [17, "cf..", "ededdededdddeeeecEcebdbdbebecd"],
|
|
28764
|
-
33: [17, "de..", "dedeeeeeededddDdbdbdcdcdcecebe"],
|
|
28765
|
-
34: [17, "de..", "dedeeeeeddddedEdcdcdbdbdcecebe"],
|
|
28766
|
-
35: [17, "cf..", "ededededdededeDebebebebecdcdcd"],
|
|
28767
|
-
36: [17, "deee", "eeeeeeeeddddddDdcdcdcdcDbebebe"],
|
|
28768
|
-
37: [17, "dF..", "dddddededededdDdbdbdcecececebd"],
|
|
28769
|
-
38: [17, "ce..", "eeeeddddddddeeEececebdbdbdbdce"],
|
|
28770
|
-
39: [17, "cF..", "ededddddddddededcdcdbdbDbdbdcd"],
|
|
28771
|
-
40: [17, "de..", "dededededdddddddbdbdbdbdbebebe"],
|
|
28772
|
-
41: [17, "ce..", "eeeeeeeeeeeeeeEececececececece"],
|
|
28773
|
-
42: [17, "cf..", "ededeeeedddddedebebebdbdcececd"],
|
|
28774
|
-
43: [17, "df..", "ddddeeeededeedEdcdcdbebececebd"],
|
|
28775
|
-
44: [17, "cF..", "ededdedeededdeDebebecdcdbebecd"],
|
|
28776
|
-
45: [17, "ce..", "eeeededededeeeeecEcebebebebece"],
|
|
28777
|
-
46: [17, "dF..", "ddddededddddedEdcDcdcdcdbdbdbd"],
|
|
28778
|
-
47: [17, "ce..", "dedededededededececececececece"],
|
|
28779
|
-
48: [25, "cf..", "ededeeeeeeeeededeeeeeeEecececececdcdcececececd"],
|
|
28780
|
-
49: [25, "cF..", "ededddddededeeeeededdeDebebecdcdcececdcdbdbdcd"],
|
|
28781
|
-
50: [25, "ce..", "eeeeddddededdededededeDebebebebebEbecdcdbdbdce"],
|
|
28782
|
-
51: [25, "ce..", "eeeeededddddeeeededeeeEececebebececebdbdcdcdce"],
|
|
28783
|
-
52: [25, "ce..", "eeeededededeededededeeEecececdcdcdcdbebebebece"],
|
|
28784
|
-
53: [25, "dF..", "ddedeeeedddddddddedeeeEdcdcebebebdbDbdbdcececd"],
|
|
28785
|
-
54: [25, "dF..", "ddedddddededededdddddEDdbdbebdbdcdcdcdcdbdbdcd"],
|
|
28786
|
-
55: [25, "dF..", "ddeddedeeeeeeeeedededeDdbdbebebebebebebebebecd"],
|
|
28787
|
-
56: [25, "dE..", "deeeeeeeededeeeededeeEedcdcebebecececdcdcecece"],
|
|
28788
|
-
57: [25, "de..", "deeedddddddddedeededeeEdcDcecDcdcececdcdbdbDce"],
|
|
28789
|
-
58: [25, "dF..", "ddedddddeeeedddddedeeeEdcdcebebebdbdcecebdbdcd"],
|
|
28790
|
-
59: [33, "cF..", "ededdedeededddddeeeeeeeedddddeDebebebdbdcecececebdbdcdcdbebecd"],
|
|
28791
|
-
60: [33, "cf..", "ededeeeeededededddddeeeeeeeedeDebebececececebdbdcdcdcdcdcececd"],
|
|
28792
|
-
61: [33, "ce..", "eeeeeeeeddddeeeeeeeeddddeeeeeeeececececebdbdcecececebdbdcecece"],
|
|
28793
|
-
62: [33, "ce..", "eeeeddddeeeeededededeeeeddddeeEecEcebdbdcececdcdcdcdcecebdbdce"],
|
|
28794
|
-
63: [33, "cf..", "ededededeeeededededeeeeeeeeeeeEececececececebebEbebecececdcdcd"],
|
|
28795
|
-
64: [33, "cF..", "ededeeeedddddedeeeeededeeeeedeDebebececebebececebebebdbdcececd"],
|
|
28796
|
-
65: [33, "df..", "ddedededededddddddddeeeeeeeedeDdbdbececececebdbdbdbdcdcdcdcdcd"],
|
|
28797
|
-
66: [33, "de..", "deeeededdedeeeeedddddededddddeDdbdbebdbdbebecdcdbebebebecdcdce"],
|
|
28798
|
-
67: [33, "de..", "deeeddddddddededdddddededdddeeEdcDcebdbdbebebdbdcdcdbdbdbdbdce"],
|
|
28799
|
-
68: [33, "dE..", "deeeeeeeeeeeeeeeddddeeeeeeeeeeEdcdcececececebdbdcecececececece"],
|
|
28800
|
-
69: [33, "df..", "ddedededdedeeeeeddddededededdeDdbdbecdcdcdcdbdbdcecebebecdcdcd"],
|
|
28801
|
-
70: [33, "dF..", "ddeddddddddddddddededededddddeDdbdbebdbdbebebebebdbdbdbdbdbDcd"],
|
|
28802
|
-
71: [33, "ce..", "eeeeddddeeeededeeeeededeededdeDebebecdcdbebececebebececebdbdce"],
|
|
28803
|
-
72: [33, "ce..", "eeeededededeededededddddddddeeEececebdbdbdbdcdcdcdcdbebebebece"],
|
|
28804
|
-
73: [33, "ce..", "eeeeededededddddededdedeeeeeeeEececececebebecdcdbdbdcdcDcdcdce"],
|
|
28805
|
-
74: [33, "cf..", "ededddddededededededdededddddeDebebebdbdbebecdcDcdcdcdcdbdbdcd"],
|
|
28806
|
-
75: [33, "cF..", "ededdededededdddddddeeeedddddeDebebebdbdcececdcdcdcdbebebebecd"],
|
|
28807
|
-
76: [33, "ce..", "eeeeeeeeeeeeeeeeeeeededeeeeedeDebebececebebecececececececececE"],
|
|
28808
|
-
77: [33, "ce..", "eeeeeeeedededddddededdddedededEdcDcdcdcdbdbdbebebdbdbebececece"],
|
|
28809
|
-
78: [33, "de..", "dedeededdedededeeeeeeeeededeedEdcdcdbebececececebebebebecdcdbe"],
|
|
28810
|
-
79: [33, "dF..", "ddddddddededdededdddeeeeedededEdcDcdcdcdcecebdbdbebecdcdbdbdbd"],
|
|
28811
|
-
80: [33, "dF..", "dddddededdddeeeeddddddddededddDdbdbdcdcdbdbdbdbDcecebdbdbebEbd"],
|
|
28812
|
-
81: [33, "de..", "dedeeeeeeeeededeededeeeedededdDdbdbdbebecececdcdbebececececebe"],
|
|
28813
|
-
82: [33, "de..", "dedeededdedeededdedededeedededEdcdcdcdcdbebebebecdcdbebecdcDbe"],
|
|
28814
|
-
83: [33, "de..", "dededededddddededdddeeeededeeeEececebebececebdbdbebebdbdbebebe"],
|
|
28815
|
-
84: [33, "cF..", "ededddddeeeeddddeeeeeeeeededeeEecececdcdcecebebecdcdcecebdbdcd"],
|
|
28816
|
-
85: [33, "cf..", "ededdddddededddddddddedeeeeedeDebebececebebebdbdbdbdbebebdbdcd"],
|
|
28817
|
-
86: [33, "ce..", "eeeeededddddeeeeeeeedededededeDebebebebebebebebebebebdbdcdcdce"],
|
|
28818
|
-
87: [33, "ce..", "eeeeddddeeeeddddddddeeeeddddeeeececebdbdcecebdbDbdbdcecebdbdce"],
|
|
28819
|
-
88: [33, "ce..", "eeeedededdddeeeeededededededeeeecececdcdcdcdcdcdcecebdbdbebece"],
|
|
28820
|
-
89: [33, "cF..", "ededeeeeddddddddededdedededeeeEecEcebebEbebecdcdbdbdbdbdcececd"],
|
|
28821
|
-
90: [33, "dF..", "ddddededeeeeededeeeedededededdDdbdbdbebebEbecececdcdcececdcdbd"],
|
|
28822
|
-
91: [33, "df..", "ddddeeeededededeededdddddededdDdbdbdbebebdbdcdcdbebebebececebd"],
|
|
28823
|
-
92: [33, "de..", "dedededeededdddddededededdddedEdcdcdbdbdbebebebebdbdcdcdbebebe"],
|
|
28824
|
-
93: [33, "de..", "dededddddddddedeededeeeeeeeeededcdcdcececececdcdbebebdbdbdbdbe"],
|
|
28825
|
-
94: [33, "dF..", "ddddeeeeddddeeeeddddeeeededeedEdcDcdbebececebdbDcecebdbdcecebd"],
|
|
28826
|
-
95: [33, "df..", "ddddddddededeeeedddddededdddddDdbdbDbdbdbebecdcdbebecdcdbdbdbd"],
|
|
28827
|
-
96: [33, "cf..", "ededeeeededeeeeedededdddeeeedeDebebececebdbdbebececebebecececd"],
|
|
28828
|
-
97: [33, "ce..", "eeeedededededededdddeeeedddddeDebebebdbdcEcebdbdbebebEbebebece"],
|
|
28829
|
-
98: [33, "ce..", "eeeeededededeeeeeeeededededeeeEececebebebebecececececdcdcdcdce"],
|
|
28830
|
-
99: [33, "cf..", "ededededddddddddddddededdedeeeEececebebecdcdbdbdbdbdbdbdcdcdcd"],
|
|
28831
|
-
100: [33, "cf..", "ededdedeeeeededededeeeeeededdeDebebecdcdcecebebebebececebebecd"]
|
|
28832
|
-
};
|
|
28833
|
-
function sectorBias(code) {
|
|
28834
|
-
return code >= 97 ? (code - 97) / 2 - 1.5 : (code - 65) / 2 - 1.5 - 1 / 64;
|
|
29080
|
+
function oddEdgeAdjustment(odd, firstEdge) {
|
|
29081
|
+
return odd ? firstEdge ? 0.5 : -0.5 : 0;
|
|
28835
29082
|
}
|
|
28836
|
-
|
|
28837
|
-
|
|
28838
|
-
|
|
28839
|
-
if (width < HOBBY_LIMIT || width > 1400) {
|
|
28840
|
-
return void 0;
|
|
29083
|
+
function floorDivision(a, b) {
|
|
29084
|
+
if (Number.isSafeInteger(a) && Number.isSafeInteger(b)) {
|
|
29085
|
+
return Math.floor(a / b);
|
|
28841
29086
|
}
|
|
28842
|
-
|
|
28843
|
-
|
|
28844
|
-
|
|
28845
|
-
|
|
28846
|
-
}
|
|
29087
|
+
const A = BigInt(Math.round(a)), B = BigInt(Math.round(b));
|
|
29088
|
+
let q = A / B;
|
|
29089
|
+
if (A % B !== 0n && A < 0n !== B < 0n) {
|
|
29090
|
+
q -= 1n;
|
|
28847
29091
|
}
|
|
28848
|
-
return
|
|
29092
|
+
return Number(q);
|
|
28849
29093
|
}
|
|
28850
29094
|
var penCache = /* @__PURE__ */ new Map();
|
|
28851
29095
|
function penPolygon(width) {
|
|
@@ -28917,6 +29161,9 @@ function perpendicularVectors(width, dx0, dy0) {
|
|
|
28917
29161
|
best = i;
|
|
28918
29162
|
}
|
|
28919
29163
|
}
|
|
29164
|
+
if (flip && best === 0 && nx * pen[n - 1][0] + ny * pen[n - 1][1] === bh) {
|
|
29165
|
+
best = n - 1;
|
|
29166
|
+
}
|
|
28920
29167
|
const P = pen[(best + n - 1) % n];
|
|
28921
29168
|
const N = pen[(best + 1) % n];
|
|
28922
29169
|
const D = pen[best];
|
|
@@ -28925,20 +29172,19 @@ function perpendicularVectors(width, dx0, dy0) {
|
|
|
28925
29172
|
const [B, hB, hS] = hP >= hN ? [P, hP, hN] : [N, hN, hP];
|
|
28926
29173
|
const den = 2 * (bh - hB + (bh - hS));
|
|
28927
29174
|
const w = den === 0 ? 0 : (hB - hS) / den;
|
|
28928
|
-
const r = (v) => 8 * Math.floor((v + 4) / 8);
|
|
28929
29175
|
const x = D[0] + (B[0] - D[0]) * w, y = D[1] + (B[1] - D[1]) * w;
|
|
28930
|
-
|
|
28931
|
-
const
|
|
28932
|
-
|
|
28933
|
-
|
|
28934
|
-
const
|
|
28935
|
-
if (
|
|
28936
|
-
|
|
28937
|
-
|
|
28938
|
-
|
|
28939
|
-
|
|
28940
|
-
|
|
28941
|
-
const vx =
|
|
29176
|
+
const signs = [dx === 0 ? 0 : Math.sign(dy), Math.sign(dx)];
|
|
29177
|
+
const firstEdge = best === 0 && hP >= hN;
|
|
29178
|
+
const num = hB - hS;
|
|
29179
|
+
const rounded = [0, 1].map((c) => {
|
|
29180
|
+
const bias2 = signs[c] + 2 * oddEdgeAdjustment(Math.abs(B[c] - D[c]) % 2 === 1, firstEdge);
|
|
29181
|
+
if (den === 0) {
|
|
29182
|
+
return 8 * (c === 1 && dy < 0 ? Math.ceil((D[c] + bias2 / 2 + 4) / 8) - 1 : Math.floor((D[c] + bias2 / 2 + 4) / 8));
|
|
29183
|
+
}
|
|
29184
|
+
const top = D[c] * den + (B[c] - D[c]) * num;
|
|
29185
|
+
return 8 * floorDivision(2 * top + den * (bias2 + 8) - (c === 1 && dy < 0 ? 1 : 0), 16 * den);
|
|
29186
|
+
});
|
|
29187
|
+
const vx = rounded[0], vy = rounded[1];
|
|
28942
29188
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
28943
29189
|
}
|
|
28944
29190
|
function squareExtension(width, dx, dy) {
|
|
@@ -28968,7 +29214,6 @@ var Outliner = class {
|
|
|
28968
29214
|
this.n = this.pen.length;
|
|
28969
29215
|
this.rr = opts.cap === "round" && opts.join === "round";
|
|
28970
29216
|
this.originalRoundJoinSides = opts.join === "round" && opts.cap !== "flat";
|
|
28971
|
-
this.roundJoinSides = !!opts.roundCurveJoins || this.originalRoundJoinSides;
|
|
28972
29217
|
this.maxX = Math.max(...this.pen.map((q) => Math.abs(q[0])));
|
|
28973
29218
|
}
|
|
28974
29219
|
/**
|
|
@@ -28976,14 +29221,14 @@ var Outliner = class {
|
|
|
28976
29221
|
* `drawDir` (a curve's end tangent) only picks the draw vertices, the
|
|
28977
29222
|
* perpendicular following the chord (measured on Bezier ends).
|
|
28978
29223
|
*/
|
|
28979
|
-
seg(a, b, dir, drawDir) {
|
|
29224
|
+
seg(a, b, dir, drawDir, curve = false) {
|
|
28980
29225
|
const dx = dir ? dir[0] : b[0] - a[0];
|
|
28981
29226
|
const dy = dir ? dir[1] : b[1] - a[1];
|
|
28982
29227
|
const d = drawDir ?? [dx, dy];
|
|
28983
29228
|
const [L, R] = drawVertices(this.pen, d[0], d[1]);
|
|
28984
|
-
const perpendicular =
|
|
29229
|
+
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
28985
29230
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
|
|
28986
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width,
|
|
29231
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
28987
29232
|
}
|
|
28988
29233
|
push(p, v) {
|
|
28989
29234
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29018,7 +29263,7 @@ var Outliner = class {
|
|
|
29018
29263
|
* vertex exactly on `A`'s ray is included when `startIncl`, one on `B`'s
|
|
29019
29264
|
* ray when `endIncl`.
|
|
29020
29265
|
*/
|
|
29021
|
-
wedge(p, A, B, startIncl, endIncl) {
|
|
29266
|
+
wedge(p, A, B, startIncl, endIncl, tail = -1) {
|
|
29022
29267
|
const TWO = Math.PI * 2;
|
|
29023
29268
|
const aA = Math.atan2(A[1], A[0]);
|
|
29024
29269
|
const angleOf = (Q) => {
|
|
@@ -29049,13 +29294,21 @@ var Outliner = class {
|
|
|
29049
29294
|
}
|
|
29050
29295
|
}
|
|
29051
29296
|
list.sort((x, y) => x[0] - y[0]);
|
|
29297
|
+
if (tail >= 0 && !list.some(([, k]) => k === tail)) {
|
|
29298
|
+
list.push([Infinity, tail]);
|
|
29299
|
+
}
|
|
29052
29300
|
for (const [, k] of list) {
|
|
29053
29301
|
this.penAt(p, k);
|
|
29054
29302
|
}
|
|
29055
29303
|
}
|
|
29304
|
+
/** The pen's extreme-x vertex `k` that a steep segment `s` rests on, or -1 when the rule does not apply. */
|
|
29305
|
+
extremeTail(applies, k, s) {
|
|
29306
|
+
const q = this.pen[k];
|
|
29307
|
+
return applies && Math.abs(s.dy) > Math.abs(s.dx) && Math.abs(q[0]) === this.maxX && q[1] === 0 ? k : -1;
|
|
29308
|
+
}
|
|
29056
29309
|
/** Side offset of segment `s` at a join. */
|
|
29057
29310
|
joinSide(s, side) {
|
|
29058
|
-
if (this.
|
|
29311
|
+
if (this.originalRoundJoinSides || s.curve) {
|
|
29059
29312
|
const q = this.pen[side === "L" ? s.L : s.R];
|
|
29060
29313
|
return [halfPixel(q[0]), halfPixel(q[1])];
|
|
29061
29314
|
}
|
|
@@ -29103,32 +29356,36 @@ var Outliner = class {
|
|
|
29103
29356
|
*/
|
|
29104
29357
|
join(p, a, b, side, outer) {
|
|
29105
29358
|
const { cap, width, miterLimit } = this.opts;
|
|
29106
|
-
const
|
|
29359
|
+
const curveJoin = a.curve && b.curve;
|
|
29360
|
+
const join = curveJoin ? "round" : this.opts.join;
|
|
29361
|
+
const roundSides = this.originalRoundJoinSides || curveJoin;
|
|
29107
29362
|
let sa = this.joinSide(a, side);
|
|
29108
29363
|
let sb = this.joinSide(b, side);
|
|
29109
29364
|
const rayA = side === "R" ? a.vRaw : [-a.vRaw[0], -a.vRaw[1]];
|
|
29110
29365
|
const rayB = side === "R" ? b.vRaw : [-b.vRaw[0], -b.vRaw[1]];
|
|
29111
|
-
if (
|
|
29112
|
-
|
|
29113
|
-
sb = side === "R" ?
|
|
29366
|
+
if (curveJoin && !this.originalRoundJoinSides && a.curveEnd && b.curveEnd) {
|
|
29367
|
+
const t = a.tangentLength >= b.tangentLength ? a : b;
|
|
29368
|
+
sa = sb = side === "R" ? t.v : [-t.v[0], -t.v[1]];
|
|
29114
29369
|
}
|
|
29115
29370
|
const Da = side === "R" ? a.R : a.L;
|
|
29116
29371
|
const Db = side === "R" ? b.R : b.L;
|
|
29117
|
-
if (
|
|
29372
|
+
if (roundSides && (Da === Db || curveJoin && sa[0] === sb[0] && sa[1] === sb[1])) {
|
|
29118
29373
|
this.push(p, sa);
|
|
29119
29374
|
return;
|
|
29120
29375
|
}
|
|
29121
29376
|
this.push(p, sa);
|
|
29122
29377
|
if (outer) {
|
|
29123
29378
|
if (join === "round") {
|
|
29124
|
-
if (
|
|
29379
|
+
if (roundSides) {
|
|
29125
29380
|
const q = this.pen[Db];
|
|
29126
29381
|
const steep = Math.abs(b.dy) > Math.abs(b.dx);
|
|
29127
29382
|
const incl = side === "L" && steep && Math.abs(q[0]) === this.maxX && q[0] * q[1] <= 0;
|
|
29128
29383
|
this.walk(p, Da, Db, false, incl);
|
|
29129
29384
|
} else {
|
|
29130
29385
|
const anti = sa[0] === -sb[0] && sa[1] === -sb[1];
|
|
29131
|
-
|
|
29386
|
+
if (Da !== Db || anti) {
|
|
29387
|
+
this.wedge(p, rayA, rayB, !anti, false, this.extremeTail(side === "L" && !anti, Db, b));
|
|
29388
|
+
}
|
|
29132
29389
|
}
|
|
29133
29390
|
} else if (join === "miter") {
|
|
29134
29391
|
const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit, side);
|
|
@@ -29138,14 +29395,16 @@ var Outliner = class {
|
|
|
29138
29395
|
}
|
|
29139
29396
|
} else {
|
|
29140
29397
|
this.pts.push([p[0], p[1]]);
|
|
29141
|
-
if (
|
|
29398
|
+
if (curveJoin && !this.originalRoundJoinSides) {
|
|
29142
29399
|
this.push(p, sb);
|
|
29143
29400
|
this.push(p, sa);
|
|
29144
29401
|
this.pts.push([p[0], p[1]]);
|
|
29145
29402
|
}
|
|
29146
|
-
if (join === "round" && cap === "flat" && !
|
|
29403
|
+
if (join === "round" && cap === "flat" && !curveJoin) {
|
|
29147
29404
|
this.push(p, sb);
|
|
29148
|
-
|
|
29405
|
+
if (Da !== Db) {
|
|
29406
|
+
this.wedge(p, rayB, rayA, false, false, this.extremeTail(side === "L", Da, a));
|
|
29407
|
+
}
|
|
29149
29408
|
this.push(p, sa);
|
|
29150
29409
|
this.pts.push([p[0], p[1]]);
|
|
29151
29410
|
}
|
|
@@ -29178,17 +29437,17 @@ var Outliner = class {
|
|
|
29178
29437
|
* lets a single point stand for a zero-length dash along `dirs[0]`;
|
|
29179
29438
|
* `draws` (curve end tangents) picks draw vertices only.
|
|
29180
29439
|
*/
|
|
29181
|
-
open(P, dirs, draws) {
|
|
29440
|
+
open(P, dirs, draws, curves) {
|
|
29182
29441
|
if (P.length < 2 && !dirs?.[0]) {
|
|
29183
29442
|
this.dot(P[0]);
|
|
29184
29443
|
return;
|
|
29185
29444
|
}
|
|
29186
29445
|
const segs2 = [];
|
|
29187
29446
|
for (let i = 0; i + 1 < P.length; i++) {
|
|
29188
|
-
segs2.push(this.seg(P[i], P[i + 1], dirs?.[i], draws?.[i]));
|
|
29447
|
+
segs2.push(this.seg(P[i], P[i + 1], dirs?.[i], draws?.[i], curves?.[i]));
|
|
29189
29448
|
}
|
|
29190
29449
|
if (segs2.length === 0) {
|
|
29191
|
-
const s = this.seg(P[0], P[0], dirs?.[0], draws?.[0]);
|
|
29450
|
+
const s = this.seg(P[0], P[0], dirs?.[0], draws?.[0], curves?.[0]);
|
|
29192
29451
|
this.cap(P[0], s, true);
|
|
29193
29452
|
this.cap(P[0], s, false);
|
|
29194
29453
|
this.flush();
|
|
@@ -29219,11 +29478,11 @@ var Outliner = class {
|
|
|
29219
29478
|
this.flush();
|
|
29220
29479
|
}
|
|
29221
29480
|
/** Outlines a closed polygon (distinct consecutive points, not repeating the first). */
|
|
29222
|
-
closed(P, draws) {
|
|
29481
|
+
closed(P, draws, curves) {
|
|
29223
29482
|
const m = P.length;
|
|
29224
29483
|
const segs2 = [];
|
|
29225
29484
|
for (let i = 0; i < m; i++) {
|
|
29226
|
-
segs2.push(this.seg(P[i], P[(i + 1) % m], void 0, draws?.[i]));
|
|
29485
|
+
segs2.push(this.seg(P[i], P[(i + 1) % m], void 0, draws?.[i], curves?.[i]));
|
|
29227
29486
|
}
|
|
29228
29487
|
for (let j = 1; j <= m; j++) {
|
|
29229
29488
|
const i = j % m;
|
|
@@ -29315,9 +29574,10 @@ function widenPath(path, opts) {
|
|
|
29315
29574
|
const out = [];
|
|
29316
29575
|
const dashed = !!opts.dashes && opts.dashes.length > 0;
|
|
29317
29576
|
for (const fig of path.figures) {
|
|
29318
|
-
const outliner = new Outliner(
|
|
29577
|
+
const outliner = new Outliner(opts, out);
|
|
29319
29578
|
let P = [];
|
|
29320
29579
|
const dirs = [];
|
|
29580
|
+
const curves = [];
|
|
29321
29581
|
for (let i = 0; i + 1 < fig.pts.length; i += 2) {
|
|
29322
29582
|
const q = [fig.pts[i], fig.pts[i + 1]];
|
|
29323
29583
|
const last = P[P.length - 1];
|
|
@@ -29326,6 +29586,7 @@ function widenPath(path, opts) {
|
|
|
29326
29586
|
}
|
|
29327
29587
|
if (last) {
|
|
29328
29588
|
dirs.push(fig.tangents?.get(i / 2 - 1));
|
|
29589
|
+
curves.push(!!fig.roundWiden || !!fig.curveSegs?.has(i / 2 - 1));
|
|
29329
29590
|
}
|
|
29330
29591
|
P.push(q);
|
|
29331
29592
|
}
|
|
@@ -29352,14 +29613,14 @@ function widenPath(path, opts) {
|
|
|
29352
29613
|
pdraws.push(piece.draws[i - 1]);
|
|
29353
29614
|
}
|
|
29354
29615
|
}
|
|
29355
|
-
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]]);
|
|
29616
|
+
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]], pts.map(() => !!fig.roundWiden));
|
|
29356
29617
|
}
|
|
29357
29618
|
} else if (closed && P.length >= 3) {
|
|
29358
|
-
outliner.closed(P, dirs);
|
|
29619
|
+
outliner.closed(P, dirs, curves);
|
|
29359
29620
|
} else if (closed && P.length === 2) {
|
|
29360
29621
|
outliner.open([P[0], P[1], P[0]]);
|
|
29361
29622
|
} else {
|
|
29362
|
-
outliner.open(P, void 0, dirs);
|
|
29623
|
+
outliner.open(P, void 0, dirs, curves);
|
|
29363
29624
|
}
|
|
29364
29625
|
}
|
|
29365
29626
|
return out;
|
|
@@ -31104,6 +31365,10 @@ function hasIlluminant(ca) {
|
|
|
31104
31365
|
return illuminantCube(ca.illuminant) !== null;
|
|
31105
31366
|
}
|
|
31106
31367
|
var PALETTE = Array.from({ length: 32 }, (_, n) => Math.round(n * 255 / 31));
|
|
31368
|
+
function exactPaletteLevel(v) {
|
|
31369
|
+
const n = Math.round(v * 31 / 255);
|
|
31370
|
+
return PALETTE[n] === v ? 255 * n / 31 : v;
|
|
31371
|
+
}
|
|
31107
31372
|
function paletteIndex(v) {
|
|
31108
31373
|
const x = clamp012(v) * 255;
|
|
31109
31374
|
let n = Math.min(30, Math.floor(x * 31 / 255));
|
|
@@ -31189,6 +31454,7 @@ function invert3(m) {
|
|
|
31189
31454
|
}
|
|
31190
31455
|
var clamp012 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
31191
31456
|
var clamp255 = (v) => v < 0 ? 0 : v > 255 ? 255 : v;
|
|
31457
|
+
var roundHalfUp = (v) => Math.floor(v + 0.5 + 1e-7);
|
|
31192
31458
|
function adjustChroma(r, g, b, scale, angle) {
|
|
31193
31459
|
const x = RGB_TO_XYZ[0][0] * r + RGB_TO_XYZ[0][1] * g + RGB_TO_XYZ[0][2] * b;
|
|
31194
31460
|
const y = RGB_TO_XYZ[1][0] * r + RGB_TO_XYZ[1][1] * g + RGB_TO_XYZ[1][2] * b;
|
|
@@ -31240,7 +31506,7 @@ function colorAdjustmentMapper(ca) {
|
|
|
31240
31506
|
if (negative) {
|
|
31241
31507
|
v = 255 - clamp255(v);
|
|
31242
31508
|
}
|
|
31243
|
-
return
|
|
31509
|
+
return roundHalfUp(clamp255(v));
|
|
31244
31510
|
};
|
|
31245
31511
|
if (!illuminant && !chroma) {
|
|
31246
31512
|
const tables = [0, 1, 2].map((channel) => Uint8Array.from({ length: 256 }, (_, i) => curve(i, channel)));
|
|
@@ -31253,7 +31519,11 @@ function colorAdjustmentMapper(ca) {
|
|
|
31253
31519
|
c = [mapped[0] * 255, mapped[1] * 255, mapped[2] * 255];
|
|
31254
31520
|
}
|
|
31255
31521
|
if (chroma) {
|
|
31522
|
+
if (!illuminant) {
|
|
31523
|
+
c = c.map(exactPaletteLevel);
|
|
31524
|
+
}
|
|
31256
31525
|
c = adjustChroma(clamp255(c[0]), clamp255(c[1]), clamp255(c[2]), scale, angle);
|
|
31526
|
+
c = c.map(roundHalfUp);
|
|
31257
31527
|
}
|
|
31258
31528
|
return curve(c[0], 0) << 16 | curve(c[1], 1) << 8 | curve(c[2], 2);
|
|
31259
31529
|
};
|
|
@@ -31287,27 +31557,6 @@ function colorAdjustRgb(rgbs, ca) {
|
|
|
31287
31557
|
rgbs[i + 2] = v & 255;
|
|
31288
31558
|
}
|
|
31289
31559
|
}
|
|
31290
|
-
function applyColorAdjustment(pixels, ca) {
|
|
31291
|
-
if (!ca || isIdentityColorAdjustment(ca)) {
|
|
31292
|
-
return;
|
|
31293
|
-
}
|
|
31294
|
-
const map = colorAdjustmentMapper(ca);
|
|
31295
|
-
const d = pixels.data;
|
|
31296
|
-
const cache2 = /* @__PURE__ */ new Map();
|
|
31297
|
-
for (let i = 0; i + 3 < d.length; i += 4) {
|
|
31298
|
-
const rgb2 = d[i] << 16 | d[i + 1] << 8 | d[i + 2];
|
|
31299
|
-
let v = cache2.get(rgb2);
|
|
31300
|
-
if (v === void 0) {
|
|
31301
|
-
v = map(rgb2);
|
|
31302
|
-
if (cache2.size < 65536) {
|
|
31303
|
-
cache2.set(rgb2, v);
|
|
31304
|
-
}
|
|
31305
|
-
}
|
|
31306
|
-
d[i] = v >> 16 & 255;
|
|
31307
|
-
d[i + 1] = v >> 8 & 255;
|
|
31308
|
-
d[i + 2] = v & 255;
|
|
31309
|
-
}
|
|
31310
|
-
}
|
|
31311
31560
|
|
|
31312
31561
|
// src/emf-gdi-halftone-dither.ts
|
|
31313
31562
|
var THRESHOLDS = [
|
|
@@ -31466,22 +31715,22 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
31466
31715
|
if (reverse) taps.reverse();
|
|
31467
31716
|
return taps;
|
|
31468
31717
|
}
|
|
31718
|
+
var REDUCE_BITS = 13;
|
|
31469
31719
|
function halftoneReduceTaps(srcLen, dstLen, reverse) {
|
|
31470
31720
|
if (dstLen >= srcLen) return halftoneAxis(0, srcLen, dstLen, reverse);
|
|
31721
|
+
const shares = 2 ** REDUCE_BITS;
|
|
31722
|
+
const scale = FIX / shares;
|
|
31471
31723
|
const taps = [];
|
|
31472
31724
|
for (let i = 0; i < dstLen; i++) {
|
|
31473
31725
|
const from = i * srcLen;
|
|
31474
31726
|
const to = (i + 1) * srcLen;
|
|
31475
31727
|
const run = [];
|
|
31476
|
-
let rest = 0;
|
|
31477
31728
|
for (let k = Math.floor(from / dstLen); k * dstLen < to; k++) {
|
|
31478
|
-
const
|
|
31479
|
-
|
|
31480
|
-
|
|
31481
|
-
run.push([k,
|
|
31482
|
-
if (run.length > 1) rest += w;
|
|
31729
|
+
const lo = Math.max(from, k * dstLen) - from;
|
|
31730
|
+
const hi = Math.min(to, (k + 1) * dstLen) - from;
|
|
31731
|
+
if (hi <= lo) continue;
|
|
31732
|
+
run.push([k, (Math.floor(hi * shares / srcLen) - Math.floor(lo * shares / srcLen)) * scale]);
|
|
31483
31733
|
}
|
|
31484
|
-
if (run.length > 1) run[0][1] = FIX - rest;
|
|
31485
31734
|
taps.push(run);
|
|
31486
31735
|
}
|
|
31487
31736
|
if (reverse) taps.reverse();
|
|
@@ -31555,7 +31804,7 @@ function halftoneEnlargeTaps(src, dst) {
|
|
|
31555
31804
|
}
|
|
31556
31805
|
function ditherPixels(px, w, h, dither, flipX, flipY, phaseX, phaseY) {
|
|
31557
31806
|
for (let y = 0; y < h; y++) {
|
|
31558
|
-
const yy = phaseY ? phaseY[y] :
|
|
31807
|
+
const yy = phaseY ? phaseY[y] : y;
|
|
31559
31808
|
for (let x = 0; x < w; x++) {
|
|
31560
31809
|
const xx = phaseX ? phaseX[x] : x;
|
|
31561
31810
|
const threshold = ditherThreshold(dither.startX, dither.startY, xx, yy);
|
|
@@ -31642,11 +31891,33 @@ function halftoneSharpen(px, w, h) {
|
|
|
31642
31891
|
}
|
|
31643
31892
|
}
|
|
31644
31893
|
}
|
|
31894
|
+
function halftonePairDespeckle(px, w, h, rows) {
|
|
31895
|
+
const n = rows ? w : h;
|
|
31896
|
+
const at = (k, side) => (rows ? side * w + k : k * w + side) * 3;
|
|
31897
|
+
const same = (i, j) => px[i] === px[j] && px[i + 1] === px[j + 1] && px[i + 2] === px[j + 2];
|
|
31898
|
+
const checker = (k) => k >= 0 && k + 1 < n && same(at(k, 0), at(k + 1, 1)) && same(at(k, 1), at(k + 1, 0)) && !same(at(k, 0), at(k, 1));
|
|
31899
|
+
const mean = Array.from({ length: n }, (_, k) => checker(k - 1) || checker(k));
|
|
31900
|
+
for (let k = 0; k < n; k++) {
|
|
31901
|
+
if (!mean[k]) continue;
|
|
31902
|
+
const first = at(k, 0);
|
|
31903
|
+
const last = at(k, 1);
|
|
31904
|
+
for (let c = 0; c < 3; c++) px[first + c] = px[last + c] = px[first + c] + px[last + c] + 1 >> 1;
|
|
31905
|
+
}
|
|
31906
|
+
}
|
|
31907
|
+
function halftoneKeepLast(px, w, h, rows) {
|
|
31908
|
+
const n = rows ? w : h;
|
|
31909
|
+
const out = new Int32Array(n * 3);
|
|
31910
|
+
for (let k = 0; k < n; k++) {
|
|
31911
|
+
const last = (rows ? w + k : k * w + 1) * 3;
|
|
31912
|
+
for (let c = 0; c < 3; c++) out[k * 3 + c] = px[last + c];
|
|
31913
|
+
}
|
|
31914
|
+
return out;
|
|
31915
|
+
}
|
|
31645
31916
|
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSampling = false, directDib = false, dither, curves) {
|
|
31646
31917
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
31647
31918
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
31648
|
-
|
|
31649
|
-
|
|
31919
|
+
let SW = Math.round(Math.abs(sw));
|
|
31920
|
+
let SH = Math.round(Math.abs(sh));
|
|
31650
31921
|
const x0 = Math.round(Math.min(sx, sx + sw));
|
|
31651
31922
|
const y0 = Math.round(Math.min(sy, sy + sh));
|
|
31652
31923
|
const flipX = dw < 0 !== sw < 0;
|
|
@@ -31655,7 +31926,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31655
31926
|
if (W === 0 || H === 0 || SW === 0 || SH === 0) {
|
|
31656
31927
|
return { width: W, height: H, data };
|
|
31657
31928
|
}
|
|
31658
|
-
|
|
31929
|
+
let rect = new Int32Array(SW * SH * 3);
|
|
31659
31930
|
for (let y = 0; y < SH; y++) {
|
|
31660
31931
|
const yy = y0 + y;
|
|
31661
31932
|
for (let x = 0; x < SW; x++) {
|
|
@@ -31670,19 +31941,40 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31670
31941
|
rect[o + 2] = src.data[i + 2];
|
|
31671
31942
|
}
|
|
31672
31943
|
}
|
|
31944
|
+
const pairRows = SH === 2 && H === 1 && W > SW && (!adjust || adjustAfterSampling || !!dither);
|
|
31945
|
+
const pairColumns = SW === 2 && W === 1 && H > SH && (!adjust || adjustAfterSampling || !!dither);
|
|
31946
|
+
if (pairRows || pairColumns) {
|
|
31947
|
+
if (!directDib) halftonePairDespeckle(rect, SW, SH, pairRows);
|
|
31948
|
+
if (pairRows && W >= 2 * SW) {
|
|
31949
|
+
rect = halftoneKeepLast(rect, SW, SH, true);
|
|
31950
|
+
SH = 1;
|
|
31951
|
+
} else if (pairColumns && H >= 2 * SH) {
|
|
31952
|
+
rect = halftoneKeepLast(rect, SW, SH, false);
|
|
31953
|
+
SW = 1;
|
|
31954
|
+
}
|
|
31955
|
+
}
|
|
31673
31956
|
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
31674
31957
|
const reducing = W < SW && H < SH;
|
|
31675
31958
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
31676
31959
|
const dithered = !!dither && !!adjust && !adjustAfterSampling;
|
|
31677
31960
|
const nearestMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
31678
31961
|
const nativeMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W > SW && H * 2 <= SH || H > SH && W * 2 <= SW);
|
|
31679
|
-
if ((enlarging || nearestMixed) && !directDib) {
|
|
31962
|
+
if ((enlarging || nearestMixed) && !directDib && !pairRows && !pairColumns) {
|
|
31680
31963
|
halftoneDespeckle(rect, SW, SH);
|
|
31681
31964
|
}
|
|
31682
31965
|
const reducedEven = W < SW ? SW % 2 === 0 && H % SH === 0 : SH % 2 === 0 && W % SW === 0;
|
|
31683
31966
|
const ditherAtSource = dithered && (W >= SW && H >= SH || nativeMixed && reducedEven);
|
|
31684
31967
|
if (ditherAtSource) {
|
|
31685
|
-
ditherPixels(
|
|
31968
|
+
ditherPixels(
|
|
31969
|
+
rect,
|
|
31970
|
+
SW,
|
|
31971
|
+
SH,
|
|
31972
|
+
dither,
|
|
31973
|
+
false,
|
|
31974
|
+
false,
|
|
31975
|
+
void 0,
|
|
31976
|
+
flipY ? Int32Array.from({ length: SH }, (_, j) => H - 1 - j) : void 0
|
|
31977
|
+
);
|
|
31686
31978
|
}
|
|
31687
31979
|
if (adjust && !adjustAfterSampling && (!dithered || ditherAtSource)) {
|
|
31688
31980
|
adjust(rect);
|
|
@@ -31798,17 +32090,13 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31798
32090
|
}
|
|
31799
32091
|
}
|
|
31800
32092
|
if (dithered && !ditherAtSource) {
|
|
31801
|
-
const phase = (n, src2, dst, selectSource) => Int32Array.from({ length: n }, (_, i) => dst > src2 ? Math.
|
|
31802
|
-
|
|
31803
|
-
|
|
31804
|
-
|
|
31805
|
-
|
|
31806
|
-
|
|
31807
|
-
|
|
31808
|
-
false,
|
|
31809
|
-
nearestMixed ? phase(W, SW, W, true) : void 0,
|
|
31810
|
-
nearestMixed ? phase(H, SH, H, false) : void 0
|
|
31811
|
-
);
|
|
32093
|
+
const phase = (n, src2, dst, selectSource) => Int32Array.from({ length: n }, (_, i) => dst > src2 ? Math.max(0, Math.ceil((2 * i + 1) * src2 / (2 * dst)) - 1) : selectSource ? Math.max(0, Math.min(src2 - 1, Math.floor(((i + 1) * 2 * src2 - dst) / (2 * dst)))) : i);
|
|
32094
|
+
const sourcePhase = nearestMixed && W * H > SW * SH;
|
|
32095
|
+
let phaseX = sourcePhase ? phase(W, SW, W, true) : void 0;
|
|
32096
|
+
let phaseY = sourcePhase ? phase(H, SH, H, false) : void 0;
|
|
32097
|
+
if (phaseX && flipX) phaseX = phaseX.slice().reverse();
|
|
32098
|
+
if (phaseY && flipY && H > SH) phaseY = phaseY.slice().reverse().map((v) => H - 1 - v);
|
|
32099
|
+
ditherPixels(out, W, H, dither, false, false, phaseX, phaseY);
|
|
31812
32100
|
adjust(out);
|
|
31813
32101
|
}
|
|
31814
32102
|
if (adjust && adjustAfterSampling) adjust(out);
|
|
@@ -31871,7 +32159,7 @@ function drawSourceMapped(target, decoded, req, offsetX, offsetY, mode, brushOrg
|
|
|
31871
32159
|
canvasDrawImage(target, tile.canvas, Math.round(dLeft), Math.round(dTop), px.width, px.height);
|
|
31872
32160
|
target.restore();
|
|
31873
32161
|
}
|
|
31874
|
-
function decodeSource(rCtx, req) {
|
|
32162
|
+
function decodeSource(rCtx, req, rotated = false) {
|
|
31875
32163
|
if (!req.source) {
|
|
31876
32164
|
return null;
|
|
31877
32165
|
}
|
|
@@ -31886,6 +32174,9 @@ function decodeSource(rCtx, req) {
|
|
|
31886
32174
|
return null;
|
|
31887
32175
|
}
|
|
31888
32176
|
const ca = rCtx.state.colorAdjustment;
|
|
32177
|
+
if (req.stretch && rCtx.state.stretchBltMode === HALFTONE && rCtx.halftoneRotatedAdjusts === void 0) {
|
|
32178
|
+
rCtx.halftoneRotatedAdjusts = !rotated && !!ca;
|
|
32179
|
+
}
|
|
31889
32180
|
const halftone = req.stretch && rCtx.state.stretchBltMode === HALFTONE && ca;
|
|
31890
32181
|
const channelOnly = isChannelOnlyColorAdjustment(ca);
|
|
31891
32182
|
const split = halftone && !channelOnly ? splitColorAdjustment(ca) : void 0;
|
|
@@ -32033,6 +32324,7 @@ function executeRotatedBlit(rCtx, logDx, logDy, logDw, logDh, rop, source, sx, s
|
|
|
32033
32324
|
let src = null;
|
|
32034
32325
|
let srcX = sx;
|
|
32035
32326
|
let srcY = sy;
|
|
32327
|
+
let adjustTexel;
|
|
32036
32328
|
if (operands.usesS) {
|
|
32037
32329
|
const decoded = decodeSource(rCtx, {
|
|
32038
32330
|
plan: { kind: "ternary", index, operands },
|
|
@@ -32047,13 +32339,30 @@ function executeRotatedBlit(rCtx, logDx, logDy, logDw, logDh, rop, source, sx, s
|
|
|
32047
32339
|
sh,
|
|
32048
32340
|
dibOrigin,
|
|
32049
32341
|
stretch
|
|
32050
|
-
});
|
|
32342
|
+
}, true);
|
|
32051
32343
|
if (!decoded) {
|
|
32052
32344
|
return;
|
|
32053
32345
|
}
|
|
32054
32346
|
src = decoded.decoded.pixels;
|
|
32055
|
-
if (decoded.decoded.adjust) {
|
|
32056
|
-
|
|
32347
|
+
if (decoded.decoded.adjust && rCtx.halftoneRotatedAdjusts) {
|
|
32348
|
+
const { adjust, adjustAfterSampling, curves } = decoded.decoded;
|
|
32349
|
+
const startX = ditherStartX(0, rCtx.state.brushOrgX);
|
|
32350
|
+
const startY = ditherStartY(0, rCtx.state.brushOrgY);
|
|
32351
|
+
const triple = new Int32Array(3);
|
|
32352
|
+
adjustTexel = (rgb2, x, y) => {
|
|
32353
|
+
triple[0] = rgb2 >> 16 & 255;
|
|
32354
|
+
triple[1] = rgb2 >> 8 & 255;
|
|
32355
|
+
triple[2] = rgb2 & 255;
|
|
32356
|
+
if (!adjustAfterSampling) {
|
|
32357
|
+
const t = ditherThreshold(startX, startY, x, y);
|
|
32358
|
+
for (let c = 0; c < 3; c++) {
|
|
32359
|
+
triple[c] = ditherQuantize(triple[c], t);
|
|
32360
|
+
}
|
|
32361
|
+
}
|
|
32362
|
+
adjust(triple);
|
|
32363
|
+
curves?.(triple);
|
|
32364
|
+
return triple[0] << 16 | triple[1] << 8 | triple[2];
|
|
32365
|
+
};
|
|
32057
32366
|
}
|
|
32058
32367
|
srcX = decoded.req.sx;
|
|
32059
32368
|
srcY = decoded.req.sy;
|
|
@@ -32077,7 +32386,10 @@ function executeRotatedBlit(rCtx, logDx, logDy, logDw, logDh, rop, source, sx, s
|
|
|
32077
32386
|
sw,
|
|
32078
32387
|
sh,
|
|
32079
32388
|
(ix, iy, x, y, d) => {
|
|
32080
|
-
|
|
32389
|
+
let s = operands.usesS ? texel(ix, iy) : 0;
|
|
32390
|
+
if (adjustTexel && operands.usesS) {
|
|
32391
|
+
s = adjustTexel(s, x, y);
|
|
32392
|
+
}
|
|
32081
32393
|
const p = typeof pattern === "function" ? pattern(x, y) : pattern;
|
|
32082
32394
|
return evalRop3(index, p, s, d);
|
|
32083
32395
|
}
|
|
@@ -32132,6 +32444,19 @@ function alignMirroredDest(rCtx, req) {
|
|
|
32132
32444
|
dy: req.dh < 0 ? req.dy + pxY : req.dy
|
|
32133
32445
|
};
|
|
32134
32446
|
}
|
|
32447
|
+
function executePlgBltAsStretch(rCtx, dx, dy, dw, dh, source, r) {
|
|
32448
|
+
executeBlit(rCtx, {
|
|
32449
|
+
plan: classifyRop3(13369376),
|
|
32450
|
+
dx,
|
|
32451
|
+
dy,
|
|
32452
|
+
dw,
|
|
32453
|
+
dh,
|
|
32454
|
+
source,
|
|
32455
|
+
...r,
|
|
32456
|
+
dibOrigin: "top-left",
|
|
32457
|
+
stretch: true
|
|
32458
|
+
});
|
|
32459
|
+
}
|
|
32135
32460
|
function executeBlit(rCtx, request) {
|
|
32136
32461
|
const { ctx } = rCtx;
|
|
32137
32462
|
const req = alignMirroredDest(rCtx, request);
|
|
@@ -32634,6 +32959,18 @@ function handlePlgBlt(rCtx, offset, dataOff, recSize) {
|
|
|
32634
32959
|
if (b[1] === a[1] && q[0] === a[0]) {
|
|
32635
32960
|
const W = Math.round(Math.abs(b[0] - a[0]) / 16);
|
|
32636
32961
|
const H = Math.round(Math.abs(q[1] - a[1]) / 16);
|
|
32962
|
+
if (!mask && rCtx.state.stretchBltMode === HALFTONE && W > 0 && H > 0) {
|
|
32963
|
+
executePlgBltAsStretch(
|
|
32964
|
+
rCtx,
|
|
32965
|
+
Math.round(a[0] / 16),
|
|
32966
|
+
Math.round(a[1] / 16),
|
|
32967
|
+
b[0] < a[0] ? -W : W,
|
|
32968
|
+
q[1] < a[1] ? -H : H,
|
|
32969
|
+
sourceOf(offset, view.getUint32(dataOff + 88, true), view.getUint32(dataOff + 92, true), view.getUint32(dataOff + 96, true), view.getUint32(dataOff + 100, true), view.getUint32(dataOff + 84, true)),
|
|
32970
|
+
r
|
|
32971
|
+
);
|
|
32972
|
+
return;
|
|
32973
|
+
}
|
|
32637
32974
|
const left = Math.round(a[0] / 16) + (b[0] < a[0] ? 1 - W : 0);
|
|
32638
32975
|
const top = Math.round(a[1] / 16) + (q[1] < a[1] ? 1 - H : 0);
|
|
32639
32976
|
const aw = Math.abs(r.sw);
|
|
@@ -32654,6 +32991,9 @@ function handlePlgBlt(rCtx, offset, dataOff, recSize) {
|
|
|
32654
32991
|
});
|
|
32655
32992
|
return;
|
|
32656
32993
|
}
|
|
32994
|
+
if (rCtx.state.stretchBltMode === HALFTONE && rCtx.halftoneRotatedAdjusts === void 0) {
|
|
32995
|
+
rCtx.halftoneRotatedAdjusts = false;
|
|
32996
|
+
}
|
|
32657
32997
|
paintParallelogram(rCtx, a, b, q, r.sw, r.sh, (ix, iy) => texel(ix, iy));
|
|
32658
32998
|
}
|
|
32659
32999
|
function readBand(rCtx, offset, offBmi, cbBmi, offBits, cbBits, usage, scans) {
|
|
@@ -34782,6 +35122,7 @@ function flattenBracketPath(rCtx) {
|
|
|
34782
35122
|
}
|
|
34783
35123
|
for (const f of rCtx.rasterPath.figures) {
|
|
34784
35124
|
delete f.tangents;
|
|
35125
|
+
delete f.curveSegs;
|
|
34785
35126
|
delete f.roundWiden;
|
|
34786
35127
|
}
|
|
34787
35128
|
syncPathCmds(rCtx);
|
|
@@ -38873,7 +39214,7 @@ function wmfRectangle(p, l, t, r, b) {
|
|
|
38873
39214
|
axisRect: { interior: rectInterior(p, box) }
|
|
38874
39215
|
});
|
|
38875
39216
|
}
|
|
38876
|
-
function compatCorner(p, w, h, box) {
|
|
39217
|
+
function compatCorner(p, w, h, box, logical) {
|
|
38877
39218
|
const m = gdiDeviceMatrix(p.rCtx);
|
|
38878
39219
|
const cw = Math.round(Math.abs(w * m[0]) * 16);
|
|
38879
39220
|
const ch = Math.round(Math.abs(h * m[3]) * 16);
|
|
@@ -38881,24 +39222,21 @@ function compatCorner(p, w, h, box) {
|
|
|
38881
39222
|
const uy = 16 * p.ky;
|
|
38882
39223
|
if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME && !penIsCosmetic(p.rCtx)) {
|
|
38883
39224
|
const penWidth = p.rCtx.state.penWidth * Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2])) * 16;
|
|
38884
|
-
const
|
|
38885
|
-
return [Math.floor(Math.min(cw,
|
|
39225
|
+
const width2 = box.x1 - box.x0, height2 = box.y1 - box.y0;
|
|
39226
|
+
return [Math.floor(Math.min(cw, width2 + penWidth) * width2 / (width2 + penWidth)), Math.floor(Math.min(ch, height2 + penWidth) * height2 / (height2 + penWidth))];
|
|
38886
39227
|
}
|
|
38887
|
-
|
|
38888
|
-
|
|
38889
|
-
|
|
38890
|
-
|
|
38891
|
-
|
|
38892
|
-
return [Math.round(Math.floor(cw / (2 * ux)) * 2 * ux), Math.round(Math.floor(ch / (2 * uy)) * 2 * uy)];
|
|
38893
|
-
}
|
|
38894
|
-
return [Math.round(Math.floor(Math.round(cw / ux) / 2) * 2 * ux), Math.round(Math.floor(Math.round(ch / uy) / 2) * 2 * uy)];
|
|
39228
|
+
const width = box.x1 - box.x0, height = box.y1 - box.y0;
|
|
39229
|
+
const fullW = Math.abs((logical[2] - logical[0]) * m[0]) * 16 || width + ux;
|
|
39230
|
+
const fullH = Math.abs((logical[3] - logical[1]) * m[3]) * 16 || height + uy;
|
|
39231
|
+
const scaled2 = [Math.min(Math.abs(w * m[0]) * 16, fullW) * width / fullW, Math.min(Math.abs(h * m[3]) * 16, fullH) * height / fullH];
|
|
39232
|
+
return penIsCosmetic(p.rCtx) && !penIsNull(p) ? scaled2 : [Math.floor(scaled2[0]), Math.floor(scaled2[1])];
|
|
38895
39233
|
}
|
|
38896
39234
|
function wmfRoundRect(p, l, t, r, b, w, h) {
|
|
38897
39235
|
const box = compatBox(p, l, t, r, b, { curved: true });
|
|
38898
39236
|
if (box.x1 < box.x0 || box.y1 < box.y0) {
|
|
38899
39237
|
return;
|
|
38900
39238
|
}
|
|
38901
|
-
const [cw, ch] = compatCorner(p, w, h, box);
|
|
39239
|
+
const [cw, ch] = compatCorner(p, w, h, box, [l, t, r, b]);
|
|
38902
39240
|
const cr = canvasRect(box);
|
|
38903
39241
|
paintGdiShape(p.rCtx, {
|
|
38904
39242
|
build: (c) => {
|
|
@@ -38951,10 +39289,14 @@ function compatArc(p, kind, l, t, r, b, xs, ys, xe, ye) {
|
|
|
38951
39289
|
if (box.x1 < box.x0 || box.y1 < box.y0) {
|
|
38952
39290
|
return null;
|
|
38953
39291
|
}
|
|
38954
|
-
const
|
|
39292
|
+
const m = gdiDeviceMatrix(p.rCtx);
|
|
39293
|
+
const deviceFix = (x, y) => [(m[0] * x + m[2] * y + m[4]) * 16, (m[1] * x + m[3] * y + m[5]) * 16];
|
|
39294
|
+
const [ax, ay] = deviceFix(l, t);
|
|
39295
|
+
const [bx, by] = deviceFix(r, b);
|
|
39296
|
+
const raw = { x0: Math.min(ax, bx), x1: Math.max(ax, bx), y0: Math.min(ay, by), y1: Math.max(ay, by) };
|
|
38955
39297
|
const onBox = (v, r0, r1, b0, b1) => (b0 + b1) / 2 + (r1 !== r0 ? (v - (r0 + r1) / 2) * (b1 - b0) / (r1 - r0) : v - (r0 + r1) / 2);
|
|
38956
39298
|
const radial = (x, y) => {
|
|
38957
|
-
const [fx, fy] =
|
|
39299
|
+
const [fx, fy] = deviceFix(x, y);
|
|
38958
39300
|
return [onBox(fx, raw.x0, raw.x1, box.x0, box.x1), onBox(fy, raw.y0, raw.y1, box.y0, box.y1)];
|
|
38959
39301
|
};
|
|
38960
39302
|
return { box, s: radial(xs, ys), e: radial(xe, ye) };
|