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