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