emf-converter 4.7.0 → 4.8.1
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 +669 -288
- package/dist/browser.mjs +669 -288
- package/dist/index.js +669 -288
- package/dist/index.mjs +669 -288
- package/package.json +1 -1
package/dist/browser.mjs
CHANGED
|
@@ -11773,19 +11773,73 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = fa
|
|
|
11773
11773
|
];
|
|
11774
11774
|
}
|
|
11775
11775
|
var TRIG_STEP = 2 * Math.PI / 128;
|
|
11776
|
-
|
|
11776
|
+
var TRIG_NODES = [
|
|
11777
|
+
1,
|
|
11778
|
+
0.99879566,
|
|
11779
|
+
0.99518639,
|
|
11780
|
+
0.98917961,
|
|
11781
|
+
0.98079146,
|
|
11782
|
+
0.97003981,
|
|
11783
|
+
0.95695228,
|
|
11784
|
+
0.94155978,
|
|
11785
|
+
0.92389844,
|
|
11786
|
+
0.90401145,
|
|
11787
|
+
0.88194619,
|
|
11788
|
+
0.85775575,
|
|
11789
|
+
0.83149879,
|
|
11790
|
+
0.80323775,
|
|
11791
|
+
0.77303903,
|
|
11792
|
+
0.74098864,
|
|
11793
|
+
0.70710648,
|
|
11794
|
+
0.67151859,
|
|
11795
|
+
0.63435836,
|
|
11796
|
+
0.59565849,
|
|
11797
|
+
0.55552672,
|
|
11798
|
+
0.51405765,
|
|
11799
|
+
0.47135039,
|
|
11800
|
+
0.42750875,
|
|
11801
|
+
0.38263811,
|
|
11802
|
+
0.33684632,
|
|
11803
|
+
0.29024443,
|
|
11804
|
+
0.24294646,
|
|
11805
|
+
0.19505974,
|
|
11806
|
+
0.14670808,
|
|
11807
|
+
0.0980012,
|
|
11808
|
+
0.04906089,
|
|
11809
|
+
0
|
|
11810
|
+
];
|
|
11811
|
+
var TRIG_TABLE = (() => {
|
|
11812
|
+
const cos = [];
|
|
11813
|
+
const sin = [];
|
|
11814
|
+
for (let k = 0; k <= 128; k++) {
|
|
11815
|
+
const q = k >> 5;
|
|
11816
|
+
const i = k & 31;
|
|
11817
|
+
const c = TRIG_NODES[i];
|
|
11818
|
+
const s = TRIG_NODES[32 - i];
|
|
11819
|
+
if (k === 128) {
|
|
11820
|
+
cos.push(1);
|
|
11821
|
+
sin.push(0);
|
|
11822
|
+
continue;
|
|
11823
|
+
}
|
|
11824
|
+
cos.push([c, -s, -c, s][q]);
|
|
11825
|
+
sin.push([s, c, -s, -c][q]);
|
|
11826
|
+
}
|
|
11827
|
+
return { cos, sin };
|
|
11828
|
+
})();
|
|
11829
|
+
function tableTrig(table) {
|
|
11777
11830
|
return (a) => {
|
|
11778
11831
|
let b = a % (2 * Math.PI);
|
|
11779
11832
|
if (b < 0) {
|
|
11780
11833
|
b += 2 * Math.PI;
|
|
11781
11834
|
}
|
|
11782
|
-
const
|
|
11783
|
-
const
|
|
11784
|
-
|
|
11835
|
+
const x = b / TRIG_STEP;
|
|
11836
|
+
const i = Math.min(127, Math.floor(x));
|
|
11837
|
+
const f = x - i;
|
|
11838
|
+
return table[i] * (1 - f) + table[i + 1] * f;
|
|
11785
11839
|
};
|
|
11786
11840
|
}
|
|
11787
|
-
var tableCos = tableTrig(
|
|
11788
|
-
var tableSin = tableTrig(
|
|
11841
|
+
var tableCos = tableTrig(TRIG_TABLE.cos);
|
|
11842
|
+
var tableSin = tableTrig(TRIG_TABLE.sin);
|
|
11789
11843
|
function angleArcPieces(startDeg, sweepDeg) {
|
|
11790
11844
|
const out = [];
|
|
11791
11845
|
const arc = (from, to) => {
|
|
@@ -11856,6 +11910,38 @@ function angleArcFix(box, startDeg, sweepDeg) {
|
|
|
11856
11910
|
}
|
|
11857
11911
|
return out;
|
|
11858
11912
|
}
|
|
11913
|
+
var SMALL_SWEEP = 3 * Math.PI / 180;
|
|
11914
|
+
function anchoredPiece(boundary, free, rx, ry, cx, cy, smallArc) {
|
|
11915
|
+
const sweep = Math.abs(free - boundary);
|
|
11916
|
+
const small = smallArc;
|
|
11917
|
+
const cos = small ? Math.cos : tableCos;
|
|
11918
|
+
const sin = small ? Math.sin : tableSin;
|
|
11919
|
+
const anchor = [Math.round(cx + rx * Math.cos(boundary)), Math.round(cy - ry * Math.sin(boundary))];
|
|
11920
|
+
const point = [cx + rx * cos(free), cy - ry * sin(free)];
|
|
11921
|
+
let t;
|
|
11922
|
+
let kappa;
|
|
11923
|
+
if (small) {
|
|
11924
|
+
t = Math.tan(sweep / 2);
|
|
11925
|
+
kappa = 2 / 3 * (1 - Math.tan(sweep / 4) ** 2);
|
|
11926
|
+
} else {
|
|
11927
|
+
const c = tableCos(sweep);
|
|
11928
|
+
const sn = tableSin(sweep);
|
|
11929
|
+
t = (1 - c) / sn;
|
|
11930
|
+
const q = t / (1 + Math.sqrt(1 + t * t));
|
|
11931
|
+
kappa = 2 / 3 * (1 - q * q);
|
|
11932
|
+
}
|
|
11933
|
+
const dir = free > boundary ? 1 : -1;
|
|
11934
|
+
const tx = -Math.round(Math.sin(boundary));
|
|
11935
|
+
const ty = -Math.round(Math.cos(boundary));
|
|
11936
|
+
const length = tx !== 0 ? rx : ry;
|
|
11937
|
+
const X = [anchor[0] + dir * tx * length * t, anchor[1] + dir * ty * length * t];
|
|
11938
|
+
return {
|
|
11939
|
+
anchor,
|
|
11940
|
+
free: point,
|
|
11941
|
+
cAnchor: [anchor[0] + kappa * (X[0] - anchor[0]), anchor[1] + kappa * (X[1] - anchor[1])],
|
|
11942
|
+
cFree: [point[0] + kappa * (X[0] - point[0]), point[1] + kappa * (X[1] - point[1])]
|
|
11943
|
+
};
|
|
11944
|
+
}
|
|
11859
11945
|
function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
|
|
11860
11946
|
const w = r - l;
|
|
11861
11947
|
const h = b - t;
|
|
@@ -11894,6 +11980,21 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
|
|
|
11894
11980
|
continue;
|
|
11895
11981
|
}
|
|
11896
11982
|
const e = s > 0 ? Math.min(next, a1) : Math.max(next, a1);
|
|
11983
|
+
const endOnBoundary = Math.abs(e / Q - Math.round(e / Q)) < 1e-9;
|
|
11984
|
+
if (onBoundary !== endOnBoundary) {
|
|
11985
|
+
const piece = anchoredPiece(onBoundary ? a : e, onBoundary ? e : a, rx, ry, cx, cy, Math.abs(a1 - a0) <= SMALL_SWEEP);
|
|
11986
|
+
if (onBoundary) {
|
|
11987
|
+
out.push(...[piece.cAnchor, piece.cFree, piece.free].flatMap((q) => [Math.round(q[0]), Math.round(q[1])]));
|
|
11988
|
+
} else {
|
|
11989
|
+
if (out.length === 2) {
|
|
11990
|
+
out[0] = Math.round(piece.free[0]);
|
|
11991
|
+
out[1] = Math.round(piece.free[1]);
|
|
11992
|
+
}
|
|
11993
|
+
out.push(...[piece.cFree, piece.cAnchor, piece.anchor].flatMap((q) => [Math.round(q[0]), Math.round(q[1])]));
|
|
11994
|
+
}
|
|
11995
|
+
a = e;
|
|
11996
|
+
continue;
|
|
11997
|
+
}
|
|
11897
11998
|
const k = 4 / 3 * Math.tan((e - a) / 4);
|
|
11898
11999
|
out.push(
|
|
11899
12000
|
Math.round(px(a) - k * rx * tableSin(a)),
|
|
@@ -11988,6 +12089,10 @@ var GdiRasterPath = class {
|
|
|
11988
12089
|
};
|
|
11989
12090
|
const t0 = tangent(x0, y0, c1x, c1y, c2x, c2y, x3, y3);
|
|
11990
12091
|
const t1 = tangent(c2x, c2y, x3, y3, x3, y3, x3, y3) ?? tangent(c1x, c1y, x3, y3, x3, y3, x3, y3) ?? tangent(x0, y0, x3, y3, x3, y3, x3, y3);
|
|
12092
|
+
f.curveSegs ?? (f.curveSegs = /* @__PURE__ */ new Set());
|
|
12093
|
+
for (let k = first; k <= last; k++) {
|
|
12094
|
+
f.curveSegs.add(k);
|
|
12095
|
+
}
|
|
11991
12096
|
f.tangents ?? (f.tangents = /* @__PURE__ */ new Map());
|
|
11992
12097
|
if (t0) f.tangents.set(first, t0);
|
|
11993
12098
|
if (t1) f.tangents.set(last, t1);
|
|
@@ -12021,7 +12126,7 @@ var GdiRasterPath = class {
|
|
|
12021
12126
|
/** Appends every figure of `other`. */
|
|
12022
12127
|
append(other) {
|
|
12023
12128
|
for (const f of other.figures) {
|
|
12024
|
-
this.figures.push({ pts: f.pts.slice(), closed: f.closed, tangents: f.tangents && new Map(f.tangents), roundWiden: f.roundWiden });
|
|
12129
|
+
this.figures.push({ pts: f.pts.slice(), closed: f.closed, tangents: f.tangents && new Map(f.tangents), curveSegs: f.curveSegs && new Set(f.curveSegs), roundWiden: f.roundWiden });
|
|
12025
12130
|
}
|
|
12026
12131
|
for (let i = 0; i < other.getPath.types.length; i++) {
|
|
12027
12132
|
this.log(other.getPath.pts[2 * i], other.getPath.pts[2 * i + 1], other.getPath.types[i]);
|
|
@@ -16296,8 +16401,8 @@ function midtoneGamma(t) {
|
|
|
16296
16401
|
low = high;
|
|
16297
16402
|
high = (high + 100) / 2;
|
|
16298
16403
|
}
|
|
16299
|
-
gamma = Math.abs(t) === 100 ? 10 : Math.min(10, gamma + (Math.abs(t) - low) / (high - low));
|
|
16300
|
-
return
|
|
16404
|
+
gamma = Math.abs(t) === 100 ? 10 : Math.min(10, truncF32(gamma + truncF32(truncF32(Math.abs(t) - low) / truncF32(high - low))));
|
|
16405
|
+
return t < 0 ? truncF32(gamma) : truncF32(1 / truncF32(gamma));
|
|
16301
16406
|
}
|
|
16302
16407
|
function brightnessContrastLut(brightness, contrast) {
|
|
16303
16408
|
const gain = contrast >= 100 ? 1e6 : contrast >= 0 ? 100 / (100 - contrast) : (100 + contrast) / 100;
|
|
@@ -16314,6 +16419,23 @@ function curveAdjustmentLut(adjustment, intensity) {
|
|
|
16314
16419
|
return nativeCurveLookup(adjustment, clamp(Math.trunc(intensity), min, max)).slice();
|
|
16315
16420
|
}
|
|
16316
16421
|
function levelsLut(highlight, midtone, shadow) {
|
|
16422
|
+
if (highlight !== shadow) {
|
|
16423
|
+
const forward = highlight > shadow;
|
|
16424
|
+
const lo = truncF32((forward ? shadow : highlight) * 255 / 100);
|
|
16425
|
+
const hi = truncF32((forward ? highlight : shadow) * 255 / 100);
|
|
16426
|
+
const scale = truncF32(1 / truncF32(hi - lo));
|
|
16427
|
+
const exponent2 = midtoneGamma(midtone);
|
|
16428
|
+
const lut = new Uint8Array(256);
|
|
16429
|
+
for (let v = 0; v < 256; v++) {
|
|
16430
|
+
let level = clamp(truncF32(truncF32(v - lo) * scale), 0, 1);
|
|
16431
|
+
if (midtone !== 0) {
|
|
16432
|
+
level = truncF32(level ** exponent2);
|
|
16433
|
+
}
|
|
16434
|
+
const out = forward ? truncF32(255 * level) : truncF32(255 - truncF32(255 * level));
|
|
16435
|
+
lut[v] = clamp(Math.floor(out + 0.5), 0, 255);
|
|
16436
|
+
}
|
|
16437
|
+
return lut;
|
|
16438
|
+
}
|
|
16317
16439
|
const base = shadow * 255 / 100 - (highlight === shadow && shadow < 50 ? 1 : 0);
|
|
16318
16440
|
const span = highlight === shadow ? 1 : (highlight - shadow) * 255 / 100;
|
|
16319
16441
|
const exponent = midtoneGamma(midtone);
|
|
@@ -16346,14 +16468,6 @@ function applyColorMatrix(src, m) {
|
|
|
16346
16468
|
}
|
|
16347
16469
|
return out;
|
|
16348
16470
|
}
|
|
16349
|
-
function hslToRgb(h, s, l) {
|
|
16350
|
-
const c = (1 - Math.abs(2 * l - 1)) * s;
|
|
16351
|
-
const hp = (h % 360 + 360) % 360 / 60;
|
|
16352
|
-
const x = c * (1 - Math.abs(hp % 2 - 1));
|
|
16353
|
-
const m = l - c / 2;
|
|
16354
|
-
const [r, g, b] = hp < 1 ? [c, x, 0] : hp < 2 ? [x, c, 0] : hp < 3 ? [0, c, x] : hp < 4 ? [0, x, c] : hp < 5 ? [x, 0, c] : [c, 0, x];
|
|
16355
|
-
return [r + m, g + m, b + m];
|
|
16356
|
-
}
|
|
16357
16471
|
var HUE_SEXTANT = 43;
|
|
16358
16472
|
var HUE_CIRCLE = 255;
|
|
16359
16473
|
function gdipHue(r, g, b) {
|
|
@@ -16376,29 +16490,30 @@ function gdipHue(r, g, b) {
|
|
|
16376
16490
|
function applyHueSaturationLightness(src, hue, saturation, lightness) {
|
|
16377
16491
|
const out = new Uint8ClampedArray(src);
|
|
16378
16492
|
const shift = Math.round(hue * HUE_CIRCLE / 360);
|
|
16379
|
-
const
|
|
16493
|
+
const satScale = 65536 + Math.floor(saturation * 65536 / 100);
|
|
16494
|
+
const lightOffset = Math.round(255 * Math.floor(lightness * 65536 / 100) / 65536);
|
|
16380
16495
|
for (let i = 0; i < src.length; i += 4) {
|
|
16381
16496
|
const r = src[i];
|
|
16382
16497
|
const g = src[i + 1];
|
|
16383
16498
|
const b = src[i + 2];
|
|
16384
16499
|
const max = Math.max(r, g, b);
|
|
16385
16500
|
const min = Math.min(r, g, b);
|
|
16386
|
-
const l = clamp(
|
|
16501
|
+
const l = clamp((max + min >> 1) + lightOffset, 0, 255);
|
|
16387
16502
|
if (max === min) {
|
|
16388
16503
|
out[i] = out[i + 1] = out[i + 2] = l;
|
|
16389
16504
|
continue;
|
|
16390
16505
|
}
|
|
16391
16506
|
const sum = max + min;
|
|
16392
|
-
const
|
|
16393
|
-
const hi = l <= 127 ? l * (
|
|
16394
|
-
const m1 =
|
|
16395
|
-
const m2 =
|
|
16507
|
+
const sat2 = clamp(Math.round(Math.floor((max - min) * 255 / (sum <= 255 ? sum : 510 - sum)) * satScale / 65536), 0, 255);
|
|
16508
|
+
const hi = l <= 127 ? Math.floor(l * (255 + sat2) / 255) : l + sat2 - Math.floor(l * sat2 / 255);
|
|
16509
|
+
const m1 = 2 * l - hi;
|
|
16510
|
+
const m2 = hi;
|
|
16396
16511
|
const index = ((gdipHue(r, g, b) + shift) % HUE_CIRCLE + HUE_CIRCLE) % HUE_CIRCLE;
|
|
16397
16512
|
const q = index + Math.floor((index + 41) / 85);
|
|
16398
16513
|
const sextant = Math.min(5, Math.floor(q / HUE_SEXTANT));
|
|
16399
|
-
const
|
|
16400
|
-
const up =
|
|
16401
|
-
const down =
|
|
16514
|
+
const position = q - sextant * HUE_SEXTANT;
|
|
16515
|
+
const up = m1 + Math.floor((m2 - m1) * position / HUE_SEXTANT);
|
|
16516
|
+
const down = m1 + Math.floor((m2 - m1) * (HUE_SEXTANT - position) / HUE_SEXTANT);
|
|
16402
16517
|
const [nr, ng, nb] = [
|
|
16403
16518
|
[m2, up, m1],
|
|
16404
16519
|
[down, m2, m1],
|
|
@@ -16413,48 +16528,278 @@ function applyHueSaturationLightness(src, hue, saturation, lightness) {
|
|
|
16413
16528
|
}
|
|
16414
16529
|
return out;
|
|
16415
16530
|
}
|
|
16416
|
-
var LUMA_709 = [0.2126, 0.7152, 0.0722];
|
|
16417
|
-
var TINT_CHROMA_SCALE = 0.985;
|
|
16418
16531
|
function applyTint(src, hue, amount) {
|
|
16419
16532
|
const index = (Math.round(hue * 255 / 360) + 256) % 256;
|
|
16420
16533
|
const q = (index + Math.floor((index + 41) / 85)) % 258;
|
|
16421
|
-
const
|
|
16422
|
-
const
|
|
16423
|
-
const
|
|
16424
|
-
const
|
|
16534
|
+
const sextant = Math.min(5, Math.floor(q / HUE_SEXTANT));
|
|
16535
|
+
const position = q - sextant * HUE_SEXTANT;
|
|
16536
|
+
const up = Math.floor(TINT_FULL * position / HUE_SEXTANT);
|
|
16537
|
+
const down = Math.floor(TINT_FULL * (HUE_SEXTANT - position) / HUE_SEXTANT);
|
|
16538
|
+
const [tr, tg, tb] = [
|
|
16539
|
+
[TINT_FULL, up, 0],
|
|
16540
|
+
[down, TINT_FULL, 0],
|
|
16541
|
+
[0, TINT_FULL, up],
|
|
16542
|
+
[0, down, TINT_FULL],
|
|
16543
|
+
[up, 0, TINT_FULL],
|
|
16544
|
+
[TINT_FULL, 0, down]
|
|
16545
|
+
][sextant];
|
|
16546
|
+
const weight = Math.sign(amount) * Math.floor((255 * Math.abs(amount) + 49) / 100);
|
|
16547
|
+
const original = 255 - weight;
|
|
16425
16548
|
const out = new Uint8ClampedArray(src);
|
|
16426
16549
|
for (let i = 0; i < src.length; i += 4) {
|
|
16427
16550
|
const r = src[i];
|
|
16428
16551
|
const g = src[i + 1];
|
|
16429
16552
|
const b = src[i + 2];
|
|
16430
|
-
const
|
|
16431
|
-
const
|
|
16432
|
-
|
|
16433
|
-
|
|
16434
|
-
|
|
16553
|
+
const u = weight * Math.max(r, g, b) >> 8;
|
|
16554
|
+
const x0 = original * r + tr * u;
|
|
16555
|
+
const x1 = original * g + tg * u;
|
|
16556
|
+
const x2 = original * b + tb * u;
|
|
16557
|
+
const base = 54 * r + 183 * g + 19 * b - (54 * (x0 >> 8) + 183 * (x1 >> 8) + 19 * (x2 >> 8));
|
|
16558
|
+
out[i] = base + x0 >> 8;
|
|
16559
|
+
out[i + 1] = base + x1 >> 8;
|
|
16560
|
+
out[i + 2] = base + x2 >> 8;
|
|
16435
16561
|
}
|
|
16436
16562
|
return out;
|
|
16437
16563
|
}
|
|
16564
|
+
var TINT_FULL = 254;
|
|
16438
16565
|
function applyRedEyeCorrection(src, width, height, areas) {
|
|
16439
16566
|
const out = new Uint8ClampedArray(src);
|
|
16440
16567
|
for (const a of areas) {
|
|
16441
|
-
|
|
16442
|
-
|
|
16443
|
-
|
|
16444
|
-
|
|
16445
|
-
|
|
16446
|
-
|
|
16447
|
-
|
|
16448
|
-
|
|
16449
|
-
|
|
16450
|
-
|
|
16451
|
-
|
|
16452
|
-
|
|
16568
|
+
correctRedEyeArea(out, width, clamp(a.left, 0, width), clamp(a.top, 0, height), clamp(a.right, 0, width), clamp(a.bottom, 0, height));
|
|
16569
|
+
}
|
|
16570
|
+
return out;
|
|
16571
|
+
}
|
|
16572
|
+
var RED_EYE_FALLOFF = new Float64Array(
|
|
16573
|
+
[
|
|
16574
|
+
24930,
|
|
16575
|
+
24570,
|
|
16576
|
+
24201,
|
|
16577
|
+
23836,
|
|
16578
|
+
23471,
|
|
16579
|
+
23107,
|
|
16580
|
+
22744,
|
|
16581
|
+
22367,
|
|
16582
|
+
21976,
|
|
16583
|
+
21587,
|
|
16584
|
+
21198,
|
|
16585
|
+
20824,
|
|
16586
|
+
20490,
|
|
16587
|
+
20165,
|
|
16588
|
+
19832,
|
|
16589
|
+
19499,
|
|
16590
|
+
19157,
|
|
16591
|
+
18817,
|
|
16592
|
+
18480,
|
|
16593
|
+
18151,
|
|
16594
|
+
17820,
|
|
16595
|
+
17490,
|
|
16596
|
+
17160,
|
|
16597
|
+
16831,
|
|
16598
|
+
16506,
|
|
16599
|
+
16189,
|
|
16600
|
+
15878,
|
|
16601
|
+
15569,
|
|
16602
|
+
15273,
|
|
16603
|
+
14973,
|
|
16604
|
+
14668,
|
|
16605
|
+
14362,
|
|
16606
|
+
14059,
|
|
16607
|
+
13768,
|
|
16608
|
+
13484,
|
|
16609
|
+
13203,
|
|
16610
|
+
12923,
|
|
16611
|
+
12642,
|
|
16612
|
+
12366,
|
|
16613
|
+
12094,
|
|
16614
|
+
11828,
|
|
16615
|
+
11564,
|
|
16616
|
+
11301,
|
|
16617
|
+
11034,
|
|
16618
|
+
10770,
|
|
16619
|
+
10507,
|
|
16620
|
+
10253,
|
|
16621
|
+
10011,
|
|
16622
|
+
9771,
|
|
16623
|
+
9530,
|
|
16624
|
+
9290,
|
|
16625
|
+
9053,
|
|
16626
|
+
8819,
|
|
16627
|
+
8588,
|
|
16628
|
+
8359,
|
|
16629
|
+
8134,
|
|
16630
|
+
7914,
|
|
16631
|
+
7697,
|
|
16632
|
+
7481,
|
|
16633
|
+
7267,
|
|
16634
|
+
7056,
|
|
16635
|
+
6851,
|
|
16636
|
+
6651,
|
|
16637
|
+
6453,
|
|
16638
|
+
6256,
|
|
16639
|
+
6061,
|
|
16640
|
+
5871,
|
|
16641
|
+
5684,
|
|
16642
|
+
5499,
|
|
16643
|
+
5317,
|
|
16644
|
+
5138,
|
|
16645
|
+
4962,
|
|
16646
|
+
4789,
|
|
16647
|
+
4619,
|
|
16648
|
+
4452,
|
|
16649
|
+
4289,
|
|
16650
|
+
4130,
|
|
16651
|
+
3974,
|
|
16652
|
+
3820,
|
|
16653
|
+
3669,
|
|
16654
|
+
3520,
|
|
16655
|
+
3375,
|
|
16656
|
+
3232,
|
|
16657
|
+
3093,
|
|
16658
|
+
2958,
|
|
16659
|
+
2825,
|
|
16660
|
+
2695,
|
|
16661
|
+
2568,
|
|
16662
|
+
2444,
|
|
16663
|
+
2325,
|
|
16664
|
+
2207,
|
|
16665
|
+
2092,
|
|
16666
|
+
1980,
|
|
16667
|
+
1872,
|
|
16668
|
+
1768,
|
|
16669
|
+
1666,
|
|
16670
|
+
1567,
|
|
16671
|
+
1470,
|
|
16672
|
+
1377,
|
|
16673
|
+
1287,
|
|
16674
|
+
1200,
|
|
16675
|
+
1116,
|
|
16676
|
+
1034,
|
|
16677
|
+
956,
|
|
16678
|
+
881,
|
|
16679
|
+
808,
|
|
16680
|
+
739,
|
|
16681
|
+
674,
|
|
16682
|
+
612,
|
|
16683
|
+
541,
|
|
16684
|
+
462,
|
|
16685
|
+
381,
|
|
16686
|
+
299,
|
|
16687
|
+
220,
|
|
16688
|
+
147,
|
|
16689
|
+
85,
|
|
16690
|
+
36,
|
|
16691
|
+
3,
|
|
16692
|
+
0
|
|
16693
|
+
].map((v) => v / 1e5)
|
|
16694
|
+
);
|
|
16695
|
+
function redEyeFalloff(u) {
|
|
16696
|
+
const t = u * 128;
|
|
16697
|
+
const i = Math.floor(t);
|
|
16698
|
+
if (i >= RED_EYE_FALLOFF.length - 1) {
|
|
16699
|
+
return 0;
|
|
16700
|
+
}
|
|
16701
|
+
return RED_EYE_FALLOFF[i] + (t - i) * (RED_EYE_FALLOFF[i + 1] - RED_EYE_FALLOFF[i]);
|
|
16702
|
+
}
|
|
16703
|
+
var RED_EYE_SECTORS = 60;
|
|
16704
|
+
var RED_EYE_BLUE_WEIGHT = 0.225;
|
|
16705
|
+
var RED_EYE_WEIGHT_CAP = 6;
|
|
16706
|
+
var RED_EYE_PURE_WEIGHT = RED_EYE_WEIGHT_CAP;
|
|
16707
|
+
var RED_EYE_DARK_STRENGTH = 0.49;
|
|
16708
|
+
var RED_EYE_DARK_RATIO = 0.6;
|
|
16709
|
+
var RED_EYE_GREEN_SHARE = 80 / 255;
|
|
16710
|
+
function correctRedEyeArea(out, stride, x0, y0, x1, y1) {
|
|
16711
|
+
const w = x1 - x0;
|
|
16712
|
+
const h = y1 - y0;
|
|
16713
|
+
const count = w * h;
|
|
16714
|
+
const redness = new Float64Array(count);
|
|
16715
|
+
const dark = new Float64Array(count);
|
|
16716
|
+
let sx = 0;
|
|
16717
|
+
let sy = 0;
|
|
16718
|
+
let sw = 0;
|
|
16719
|
+
for (let y = 0; y < h; y++) {
|
|
16720
|
+
for (let x = 0; x < w; x++) {
|
|
16721
|
+
const i = ((y0 + y) * stride + x0 + x) * 4;
|
|
16722
|
+
const r = out[i];
|
|
16723
|
+
const g = out[i + 1];
|
|
16724
|
+
const b = out[i + 2];
|
|
16725
|
+
const k = y * w + x;
|
|
16726
|
+
dark[k] = Math.min(g, b);
|
|
16727
|
+
const v = r - Math.max(g, b);
|
|
16728
|
+
if (v > 0) {
|
|
16729
|
+
redness[k] = v;
|
|
16730
|
+
const denominator = g + RED_EYE_BLUE_WEIGHT * b;
|
|
16731
|
+
{
|
|
16732
|
+
const weight = denominator >= 1 ? Math.min(RED_EYE_WEIGHT_CAP, v / denominator) : RED_EYE_PURE_WEIGHT;
|
|
16733
|
+
sx += weight * (x + 0.5);
|
|
16734
|
+
sy += weight * (y + 0.5);
|
|
16735
|
+
sw += weight;
|
|
16453
16736
|
}
|
|
16454
16737
|
}
|
|
16455
16738
|
}
|
|
16456
16739
|
}
|
|
16457
|
-
|
|
16740
|
+
if (sw === 0) {
|
|
16741
|
+
if (!redness.some((v) => v > 0)) {
|
|
16742
|
+
return;
|
|
16743
|
+
}
|
|
16744
|
+
sx = w / 2;
|
|
16745
|
+
sy = h / 2;
|
|
16746
|
+
sw = 1;
|
|
16747
|
+
}
|
|
16748
|
+
const cx = sx / sw;
|
|
16749
|
+
const cy = sy / sw;
|
|
16750
|
+
const radius = Math.min(cx, cy) - 0.5;
|
|
16751
|
+
if (!(radius > 0)) {
|
|
16752
|
+
return;
|
|
16753
|
+
}
|
|
16754
|
+
const sector = new Uint8Array(count);
|
|
16755
|
+
const distance = new Float64Array(count);
|
|
16756
|
+
const sectorSum = new Float64Array(RED_EYE_SECTORS);
|
|
16757
|
+
const sectorDark = new Float64Array(RED_EYE_SECTORS);
|
|
16758
|
+
const sectorCount = new Float64Array(RED_EYE_SECTORS);
|
|
16759
|
+
const degrees = 180 / Math.PI;
|
|
16760
|
+
for (let y = 0; y < h; y++) {
|
|
16761
|
+
for (let x = 0; x < w; x++) {
|
|
16762
|
+
const dx = x + 0.5 - cx;
|
|
16763
|
+
const dy = y + 0.5 - cy;
|
|
16764
|
+
const k = y * w + x;
|
|
16765
|
+
const d = Math.hypot(dx, dy);
|
|
16766
|
+
distance[k] = d;
|
|
16767
|
+
let angle = Math.atan2(dy, dx) * degrees;
|
|
16768
|
+
if (angle < 0) {
|
|
16769
|
+
angle += 360;
|
|
16770
|
+
}
|
|
16771
|
+
const s = Math.min(RED_EYE_SECTORS - 1, Math.floor(angle / 6));
|
|
16772
|
+
sector[k] = s;
|
|
16773
|
+
if (d < radius) {
|
|
16774
|
+
sectorSum[s] += redness[k];
|
|
16775
|
+
sectorDark[s] += dark[k];
|
|
16776
|
+
sectorCount[s]++;
|
|
16777
|
+
}
|
|
16778
|
+
}
|
|
16779
|
+
}
|
|
16780
|
+
for (let y = 0; y < h; y++) {
|
|
16781
|
+
for (let x = 0; x < w; x++) {
|
|
16782
|
+
const k = y * w + x;
|
|
16783
|
+
const v = redness[k];
|
|
16784
|
+
if (v <= 0 || distance[k] >= radius) {
|
|
16785
|
+
continue;
|
|
16786
|
+
}
|
|
16787
|
+
const s = sector[k];
|
|
16788
|
+
const mean = sectorSum[s] / sectorCount[s];
|
|
16789
|
+
const meanDark = sectorDark[s] / sectorCount[s];
|
|
16790
|
+
const ratio = meanDark > 0 ? dark[k] / meanDark : 1;
|
|
16791
|
+
const falloff = Math.max(redEyeFalloff(distance[k] / radius), RED_EYE_DARK_STRENGTH * Math.max(0, 1 - ratio / RED_EYE_DARK_RATIO));
|
|
16792
|
+
const rest = (1 - falloff) * mean;
|
|
16793
|
+
if (rest >= v) {
|
|
16794
|
+
continue;
|
|
16795
|
+
}
|
|
16796
|
+
const removed = v - rest;
|
|
16797
|
+
const i = ((y0 + y) * stride + x0 + x) * 4;
|
|
16798
|
+
out[i] = Math.round(out[i] - (1 - RED_EYE_GREEN_SHARE) * removed);
|
|
16799
|
+
out[i + 1] = Math.round(out[i + 1] + RED_EYE_GREEN_SHARE * removed);
|
|
16800
|
+
out[i + 2] = Math.round(out[i + 2] + RED_EYE_GREEN_SHARE * removed);
|
|
16801
|
+
}
|
|
16802
|
+
}
|
|
16458
16803
|
}
|
|
16459
16804
|
function blurKernel(radius) {
|
|
16460
16805
|
const taps = Math.ceil(radius);
|
|
@@ -16486,8 +16831,8 @@ function mirror(p, n) {
|
|
|
16486
16831
|
function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, verticalRows = Math.ceil(h / w)) {
|
|
16487
16832
|
const k = blurKernel(radius);
|
|
16488
16833
|
const taps = (k.length - 1) / 2;
|
|
16489
|
-
const horizontalIndex = taps >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
|
|
16490
|
-
const verticalIndex = taps >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
|
|
16834
|
+
const horizontalIndex = (taps | 1) >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
|
|
16835
|
+
const verticalIndex = (taps | 1) >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
|
|
16491
16836
|
const out = new Float64Array(w * h * 4);
|
|
16492
16837
|
for (let y = 0; y < h; y++) {
|
|
16493
16838
|
const row2 = y * w * 4;
|
|
@@ -16498,11 +16843,12 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, verticalRows
|
|
|
16498
16843
|
let s3 = 0;
|
|
16499
16844
|
for (let j = -taps; j <= taps; j++) {
|
|
16500
16845
|
const p = row2 + horizontalIndex(x + j) * 4;
|
|
16501
|
-
const kw = k[j + taps] * 256;
|
|
16502
|
-
|
|
16503
|
-
|
|
16504
|
-
|
|
16505
|
-
|
|
16846
|
+
const kw = j === 0 ? k[taps] * 128 : k[j + taps] * 256;
|
|
16847
|
+
const times = j === 0 ? 2 : 1;
|
|
16848
|
+
s0 += times * Math.round(kw * src[p]);
|
|
16849
|
+
s1 += times * Math.round(kw * src[p + 1]);
|
|
16850
|
+
s2 += times * Math.round(kw * src[p + 2]);
|
|
16851
|
+
s3 += times * Math.round(kw * src[p + 3]);
|
|
16506
16852
|
}
|
|
16507
16853
|
const o = row2 + x * 4;
|
|
16508
16854
|
out[o] = Math.floor((s0 + 128) / 256);
|
|
@@ -16522,8 +16868,10 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, verticalRows
|
|
|
16522
16868
|
continue;
|
|
16523
16869
|
}
|
|
16524
16870
|
const base = verticalIndex(yy) * w * 4;
|
|
16871
|
+
const kw = j === 0 ? k[taps] * 128 : k[j + taps] * 256;
|
|
16872
|
+
const times = j === 0 ? 2 : 1;
|
|
16525
16873
|
for (let i = 0; i < w * 4; i++) {
|
|
16526
|
-
col[i] += Math.round(
|
|
16874
|
+
col[i] += times * Math.round(kw * horizontal[base + i]) / 256;
|
|
16527
16875
|
}
|
|
16528
16876
|
}
|
|
16529
16877
|
out.set(col, row2 * w * 4);
|
|
@@ -16538,10 +16886,12 @@ function blurAxis(length, lanes, factor, k, edgeLength, get, put, span = { start
|
|
|
16538
16886
|
const inner = Math.ceil(span.size / factor);
|
|
16539
16887
|
const n = inner + 2 * span.pad;
|
|
16540
16888
|
const taps = (k.length - 1) / 2;
|
|
16541
|
-
const index = taps >= edgeLength ? (i) => clamp(i, 0, n - 1) : (i) => mirror(i, n);
|
|
16889
|
+
const index = (taps | 1) >= edgeLength ? (i) => clamp(i, 0, n - 1) : (i) => mirror(i, n);
|
|
16542
16890
|
const reduced = new Float64Array(n);
|
|
16543
16891
|
const filtered = new Float64Array(n);
|
|
16544
16892
|
const k256 = k.map((w) => w * 256);
|
|
16893
|
+
const half = k256[taps] / 2;
|
|
16894
|
+
k256[taps] = 0;
|
|
16545
16895
|
for (let lane = 0; lane < lanes; lane++) for (let c = 0; c < 4; c++) {
|
|
16546
16896
|
for (let b = span.pad; b < span.pad + inner; b++) {
|
|
16547
16897
|
const from = span.start + (b - span.pad) * factor;
|
|
@@ -16555,33 +16905,48 @@ function blurAxis(length, lanes, factor, k, edgeLength, get, put, span = { start
|
|
|
16555
16905
|
if (b >= taps && b + taps < n) {
|
|
16556
16906
|
for (let j = 0; j < k256.length; j++) sum += Math.round(k256[j] * reduced[b - taps + j]);
|
|
16557
16907
|
} else {
|
|
16558
|
-
for (let j = 0; j < k256.length; j++)
|
|
16908
|
+
for (let j = 0; j < k256.length; j++) {
|
|
16909
|
+
const at = b - taps + j;
|
|
16910
|
+
sum += Math.round(k256[j] * (span.zeroOutside && (at < 0 || at >= n) ? 0 : reduced[index(at)]));
|
|
16911
|
+
}
|
|
16559
16912
|
}
|
|
16913
|
+
sum += 2 * Math.round(half * reduced[b]);
|
|
16560
16914
|
filtered[b] = Math.floor((sum + 128) / 256);
|
|
16561
16915
|
}
|
|
16916
|
+
const lone = inner === 1 && span.pad > 0;
|
|
16917
|
+
const skipped2 = inner === 1 && span.size - Math.ceil(factor / 2) === 1 ? span.start + span.size - 1 : -1;
|
|
16562
16918
|
for (let i = 0; i < length; i++) {
|
|
16563
|
-
|
|
16564
|
-
|
|
16919
|
+
if (i === skipped2) {
|
|
16920
|
+
if (span.pad > 0) put(i, lane, c, 0);
|
|
16921
|
+
continue;
|
|
16922
|
+
}
|
|
16923
|
+
const p = (i - span.start + 0.5) / factor - 0.5;
|
|
16924
|
+
if (lone) {
|
|
16925
|
+
const distance = Math.abs(i - span.start - (Math.min(span.size, factor / 2) - 0.5)) / factor;
|
|
16926
|
+
put(i, lane, c, clamp(Math.floor((1 + distance) * filtered[span.pad] + 1e-9), 0, 255));
|
|
16927
|
+
continue;
|
|
16928
|
+
}
|
|
16929
|
+
const a = clamp(Math.floor(p), 0, Math.max(0, inner - 2));
|
|
16565
16930
|
const t = p - a;
|
|
16566
|
-
put(i, lane, c, clamp(Math.floor((1 - t) * filtered[a] + t * filtered[Math.min(
|
|
16931
|
+
put(i, lane, c, clamp(Math.floor((1 - t) * filtered[span.pad + a] + t * filtered[span.pad + Math.min(inner - 1, a + 1)] + 1e-9), 0, 255));
|
|
16567
16932
|
}
|
|
16568
16933
|
}
|
|
16569
16934
|
}
|
|
16570
|
-
function effectBlur(src, width, height, radius, region) {
|
|
16935
|
+
function effectBlur(src, width, height, radius, region, expanded = false) {
|
|
16571
16936
|
const factor = blurReduction(radius);
|
|
16572
16937
|
if (factor === 1) {
|
|
16573
16938
|
return gdipBlur(src, width, height, radius);
|
|
16574
16939
|
}
|
|
16575
16940
|
const k = blurKernel(radius / factor);
|
|
16576
16941
|
const pad = region ? Math.ceil(Math.ceil(radius) / factor) : 0;
|
|
16577
|
-
const spanX = region ? { start: region.x, size: region.w, pad } : void 0;
|
|
16578
|
-
const spanY = region ? { start: region.y, size: region.h, pad } : void 0;
|
|
16579
|
-
const rows = new Uint8Array(src
|
|
16580
|
-
blurAxis(width, height, factor, k, Math.
|
|
16942
|
+
const spanX = region ? { start: region.x, size: region.w, pad, zeroOutside: true } : expanded ? { start: 0, size: width, pad: 0, zeroOutside: true } : void 0;
|
|
16943
|
+
const spanY = region ? { start: region.y, size: region.h, pad, zeroOutside: true } : expanded ? { start: 0, size: height, pad: 0, zeroOutside: true } : void 0;
|
|
16944
|
+
const rows = new Uint8Array(src);
|
|
16945
|
+
blurAxis(width, height, factor, k, Math.ceil(width / factor), (i, lane, c) => src[(lane * width + i) * 4 + c], (i, lane, c, v) => {
|
|
16581
16946
|
rows[(lane * width + i) * 4 + c] = v;
|
|
16582
16947
|
}, spanX);
|
|
16583
|
-
const out =
|
|
16584
|
-
blurAxis(height, width, factor, k, Math.
|
|
16948
|
+
const out = Float64Array.from(rows);
|
|
16949
|
+
blurAxis(height, width, factor, k, Math.ceil(height / factor), (i, lane, c) => rows[(i * width + lane) * 4 + c], (i, lane, c, v) => {
|
|
16585
16950
|
out[(i * width + lane) * 4 + c] = v;
|
|
16586
16951
|
}, spanY);
|
|
16587
16952
|
return out;
|
|
@@ -16669,7 +17034,7 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
|
|
|
16669
17034
|
const gy1 = Math.min(height, y1 + r);
|
|
16670
17035
|
copyBlock(rgba, width, gx0, gy0, gx1 - gx0, gy1 - gy0, buf, bw, gx0 - (x0 - r), gy0 - (y0 - r));
|
|
16671
17036
|
}
|
|
16672
|
-
const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, cropped ? { x: r, y: r, w: x1 - x0, h: y1 - y0 } : void 0) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, Math.ceil((y1 - y0) / (x1 - x0)));
|
|
17037
|
+
const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, cropped ? { x: r, y: r, w: x1 - x0, h: y1 - y0 } : void 0, true) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, Math.ceil((y1 - y0) / (x1 - x0)));
|
|
16673
17038
|
const w = x1 - x0;
|
|
16674
17039
|
const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
|
|
16675
17040
|
for (let y = 0; y < y1 - y0; y++) {
|
|
@@ -20196,8 +20561,7 @@ function resampleImage(rgba, width, height, spec, surface) {
|
|
|
20196
20561
|
const axisAligned = m[1] === 0 && m[2] === 0;
|
|
20197
20562
|
if (hq && axisAligned) {
|
|
20198
20563
|
const ox = m[0] * spec.srcX + m[4];
|
|
20199
|
-
|
|
20200
|
-
m = [m[0], 0, 0, m[3], m[4] + mirroredOrigin(ox) - ox, m[5] + mirroredOrigin(oy) - oy];
|
|
20564
|
+
m = [m[0], 0, 0, m[3], m[4] + mirroredOrigin(ox) - ox, m[5]];
|
|
20201
20565
|
}
|
|
20202
20566
|
const inv2 = invert2(m);
|
|
20203
20567
|
if (!inv2) {
|
|
@@ -23010,6 +23374,21 @@ var nestedReplayer = null;
|
|
|
23010
23374
|
function registerNestedMetafileReplayer(fn) {
|
|
23011
23375
|
nestedReplayer = fn;
|
|
23012
23376
|
}
|
|
23377
|
+
function inclusiveNestedMapping(toDevice, srcX, srcY, srcW, srcH) {
|
|
23378
|
+
const [a, b, c, d, e, f] = toDevice;
|
|
23379
|
+
const lengthU = Math.hypot(a, b) * srcW;
|
|
23380
|
+
const lengthV = Math.hypot(c, d) * srcH;
|
|
23381
|
+
if (!(srcW > 1 && srcH > 1 && lengthU > 1 && lengthV > 1)) {
|
|
23382
|
+
return toDevice;
|
|
23383
|
+
}
|
|
23384
|
+
const ku = (lengthU - 1) / lengthU * (srcW / (srcW - 1));
|
|
23385
|
+
const kv = (lengthV - 1) / lengthV * (srcH / (srcH - 1));
|
|
23386
|
+
const na = a * ku;
|
|
23387
|
+
const nb = b * ku;
|
|
23388
|
+
const nc = c * kv;
|
|
23389
|
+
const nd = d * kv;
|
|
23390
|
+
return [na, nb, nc, nd, e + (a - na) * srcX + (c - nc) * srcY, f + (b - nb) * srcX + (d - nd) * srcY];
|
|
23391
|
+
}
|
|
23013
23392
|
function drawNestedMetafile(rCtx, img, cached, source) {
|
|
23014
23393
|
const depth = rCtx.nestingDepth ?? 0;
|
|
23015
23394
|
if (!nestedReplayer || !source || !img.data || source.unit !== UNIT_PIXEL || depth >= MAX_NESTED_METAFILE_DEPTH) {
|
|
@@ -23023,9 +23402,12 @@ function drawNestedMetafile(rCtx, img, cached, source) {
|
|
|
23023
23402
|
if (!size) {
|
|
23024
23403
|
return false;
|
|
23025
23404
|
}
|
|
23026
|
-
const toCanvas =
|
|
23027
|
-
|
|
23028
|
-
|
|
23405
|
+
const toCanvas = inclusiveNestedMapping(
|
|
23406
|
+
mulMatrix(plusWorldMatrix(rCtx), source.toWorld(srcX, srcY, srcW, srcH)),
|
|
23407
|
+
srcX,
|
|
23408
|
+
srcY,
|
|
23409
|
+
srcW,
|
|
23410
|
+
srcH
|
|
23029
23411
|
);
|
|
23030
23412
|
const bytes = img.data.slice(0);
|
|
23031
23413
|
const caches = cached && cached.kind === "metafile" ? cached.caches : void 0;
|
|
@@ -28734,118 +29116,19 @@ var HOBBY = [
|
|
|
28734
29116
|
[[8, -48], [-8, -48], [-24, -40], [-40, -24], [-48, -8], [-48, 8], [-40, 24], [-24, 40], [-8, 48], [8, 48], [24, 40], [40, 24], [48, 8], [48, -8], [40, -24], [24, -40]]
|
|
28735
29117
|
];
|
|
28736
29118
|
var HOBBY_LIMIT = 104;
|
|
28737
|
-
|
|
28738
|
-
|
|
28739
|
-
8: [9, "dFee", "ededededbdbdbd"],
|
|
28740
|
-
9: [9, "df..", "ddddddddbDbdbd"],
|
|
28741
|
-
10: [9, "de..", "dededeDebEbebE"],
|
|
28742
|
-
11: [9, "ce..", "eeeeeeEececece"],
|
|
28743
|
-
12: [13, "ce..", "eeeeeeeeeeeececEcecece"],
|
|
28744
|
-
13: [17, "ce..", "eeeeededdddddeDebebebdbdcdcdce"],
|
|
28745
|
-
14: [17, "df..", "ddedeeeededeeeedcDcebebecececd"],
|
|
28746
|
-
15: [17, "dF..", "ddedeeeeeeeedeDdbdbecececececd"],
|
|
28747
|
-
16: [17, "ce..", "eeeededededeeeeececebebebebece"],
|
|
28748
|
-
17: [17, "df..", "ddedededededdeddbdbebdbdbdbdcd"],
|
|
28749
|
-
18: [17, "de..", "deeededeededeeEdcDcecdcdbebece"],
|
|
28750
|
-
19: [17, "cf..", "ededeeeedddddeDebEbecdcdbebecd"],
|
|
28751
|
-
20: [17, "ce..", "eeeeddddeeeeddDdbdbdcecebdbdce"],
|
|
28752
|
-
21: [17, "dF..", "ddddededededddDdbdbdcdcdcdcdbd"],
|
|
28753
|
-
22: [17, "ce..", "eeeededeeeeedeDebebececebebece"],
|
|
28754
|
-
23: [17, "cf..", "edededededededEdcDcdcdcdcdcdcD"],
|
|
28755
|
-
24: [17, "dF..", "ddddddddddddddDdbdbdbdbdbdbdbd"],
|
|
28756
|
-
25: [17, "cE..", "eeeeededededeeEecEcecdcdcdcdce"],
|
|
28757
|
-
26: [17, "cf..", "ededdedeededdedebEbecdcdbebecd"],
|
|
28758
|
-
27: [17, "de..", "dedeededdedeededcDcdbebecdcdbe"],
|
|
28759
|
-
28: [17, "cf..", "ededddddeeeedeDebEbebebecdcdcd"],
|
|
28760
|
-
29: [17, "ce..", "eeeeeeeededededebebebebececece"],
|
|
28761
|
-
30: [17, "dF..", "dddddedeeeeeedEdcdcdcecebebebd"],
|
|
28762
|
-
31: [17, "de..", "dedeededededdeDebebecdcdcdcdbe"],
|
|
28763
|
-
32: [17, "cf..", "ededdededdddeeeecEcebdbdbebecd"],
|
|
28764
|
-
33: [17, "de..", "dedeeeeeededddDdbdbdcdcdcecebe"],
|
|
28765
|
-
34: [17, "de..", "dedeeeeeddddedEdcdcdbdbdcecebe"],
|
|
28766
|
-
35: [17, "cf..", "ededededdededeDebebebebecdcdcd"],
|
|
28767
|
-
36: [17, "deee", "eeeeeeeeddddddDdcdcdcdcDbebebe"],
|
|
28768
|
-
37: [17, "dF..", "dddddededededdDdbdbdcecececebd"],
|
|
28769
|
-
38: [17, "ce..", "eeeeddddddddeeEececebdbdbdbdce"],
|
|
28770
|
-
39: [17, "cF..", "ededddddddddededcdcdbdbDbdbdcd"],
|
|
28771
|
-
40: [17, "de..", "dededededdddddddbdbdbdbdbebebe"],
|
|
28772
|
-
41: [17, "ce..", "eeeeeeeeeeeeeeEececececececece"],
|
|
28773
|
-
42: [17, "cf..", "ededeeeedddddedebebebdbdcececd"],
|
|
28774
|
-
43: [17, "df..", "ddddeeeededeedEdcdcdbebececebd"],
|
|
28775
|
-
44: [17, "cF..", "ededdedeededdeDebebecdcdbebecd"],
|
|
28776
|
-
45: [17, "ce..", "eeeededededeeeeecEcebebebebece"],
|
|
28777
|
-
46: [17, "dF..", "ddddededddddedEdcDcdcdcdbdbdbd"],
|
|
28778
|
-
47: [17, "ce..", "dedededededededececececececece"],
|
|
28779
|
-
48: [25, "cf..", "ededeeeeeeeeededeeeeeeEecececececdcdcececececd"],
|
|
28780
|
-
49: [25, "cF..", "ededddddededeeeeededdeDebebecdcdcececdcdbdbdcd"],
|
|
28781
|
-
50: [25, "ce..", "eeeeddddededdededededeDebebebebebEbecdcdbdbdce"],
|
|
28782
|
-
51: [25, "ce..", "eeeeededddddeeeededeeeEececebebececebdbdcdcdce"],
|
|
28783
|
-
52: [25, "ce..", "eeeededededeededededeeEecececdcdcdcdbebebebece"],
|
|
28784
|
-
53: [25, "dF..", "ddedeeeedddddddddedeeeEdcdcebebebdbDbdbdcececd"],
|
|
28785
|
-
54: [25, "dF..", "ddedddddededededdddddEDdbdbebdbdcdcdcdcdbdbdcd"],
|
|
28786
|
-
55: [25, "dF..", "ddeddedeeeeeeeeedededeDdbdbebebebebebebebebecd"],
|
|
28787
|
-
56: [25, "dE..", "deeeeeeeededeeeededeeEedcdcebebecececdcdcecece"],
|
|
28788
|
-
57: [25, "de..", "deeedddddddddedeededeeEdcDcecDcdcececdcdbdbDce"],
|
|
28789
|
-
58: [25, "dF..", "ddedddddeeeedddddedeeeEdcdcebebebdbdcecebdbdcd"],
|
|
28790
|
-
59: [33, "cF..", "ededdedeededddddeeeeeeeedddddeDebebebdbdcecececebdbdcdcdbebecd"],
|
|
28791
|
-
60: [33, "cf..", "ededeeeeededededddddeeeeeeeedeDebebececececebdbdcdcdcdcdcececd"],
|
|
28792
|
-
61: [33, "ce..", "eeeeeeeeddddeeeeeeeeddddeeeeeeeececececebdbdcecececebdbdcecece"],
|
|
28793
|
-
62: [33, "ce..", "eeeeddddeeeeededededeeeeddddeeEecEcebdbdcececdcdcdcdcecebdbdce"],
|
|
28794
|
-
63: [33, "cf..", "ededededeeeededededeeeeeeeeeeeEececececececebebEbebecececdcdcd"],
|
|
28795
|
-
64: [33, "cF..", "ededeeeedddddedeeeeededeeeeedeDebebececebebececebebebdbdcececd"],
|
|
28796
|
-
65: [33, "df..", "ddedededededddddddddeeeeeeeedeDdbdbececececebdbdbdbdcdcdcdcdcd"],
|
|
28797
|
-
66: [33, "de..", "deeeededdedeeeeedddddededddddeDdbdbebdbdbebecdcdbebebebecdcdce"],
|
|
28798
|
-
67: [33, "de..", "deeeddddddddededdddddededdddeeEdcDcebdbdbebebdbdcdcdbdbdbdbdce"],
|
|
28799
|
-
68: [33, "dE..", "deeeeeeeeeeeeeeeddddeeeeeeeeeeEdcdcececececebdbdcecececececece"],
|
|
28800
|
-
69: [33, "df..", "ddedededdedeeeeeddddededededdeDdbdbecdcdcdcdbdbdcecebebecdcdcd"],
|
|
28801
|
-
70: [33, "dF..", "ddeddddddddddddddededededddddeDdbdbebdbdbebebebebdbdbdbdbdbDcd"],
|
|
28802
|
-
71: [33, "ce..", "eeeeddddeeeededeeeeededeededdeDebebecdcdbebececebebececebdbdce"],
|
|
28803
|
-
72: [33, "ce..", "eeeededededeededededddddddddeeEececebdbdbdbdcdcdcdcdbebebebece"],
|
|
28804
|
-
73: [33, "ce..", "eeeeededededddddededdedeeeeeeeEececececebebecdcdbdbdcdcDcdcdce"],
|
|
28805
|
-
74: [33, "cf..", "ededddddededededededdededddddeDebebebdbdbebecdcDcdcdcdcdbdbdcd"],
|
|
28806
|
-
75: [33, "cF..", "ededdededededdddddddeeeedddddeDebebebdbdcececdcdcdcdbebebebecd"],
|
|
28807
|
-
76: [33, "ce..", "eeeeeeeeeeeeeeeeeeeededeeeeedeDebebececebebecececececececececE"],
|
|
28808
|
-
77: [33, "ce..", "eeeeeeeedededddddededdddedededEdcDcdcdcdbdbdbebebdbdbebececece"],
|
|
28809
|
-
78: [33, "de..", "dedeededdedededeeeeeeeeededeedEdcdcdbebececececebebebebecdcdbe"],
|
|
28810
|
-
79: [33, "dF..", "ddddddddededdededdddeeeeedededEdcDcdcdcdcecebdbdbebecdcdbdbdbd"],
|
|
28811
|
-
80: [33, "dF..", "dddddededdddeeeeddddddddededddDdbdbdcdcdbdbdbdbDcecebdbdbebEbd"],
|
|
28812
|
-
81: [33, "de..", "dedeeeeeeeeededeededeeeedededdDdbdbdbebecececdcdbebececececebe"],
|
|
28813
|
-
82: [33, "de..", "dedeededdedeededdedededeedededEdcdcdcdcdbebebebecdcdbebecdcDbe"],
|
|
28814
|
-
83: [33, "de..", "dededededddddededdddeeeededeeeEececebebececebdbdbebebdbdbebebe"],
|
|
28815
|
-
84: [33, "cF..", "ededddddeeeeddddeeeeeeeeededeeEecececdcdcecebebecdcdcecebdbdcd"],
|
|
28816
|
-
85: [33, "cf..", "ededdddddededddddddddedeeeeedeDebebececebebebdbdbdbdbebebdbdcd"],
|
|
28817
|
-
86: [33, "ce..", "eeeeededddddeeeeeeeedededededeDebebebebebebebebebebebdbdcdcdce"],
|
|
28818
|
-
87: [33, "ce..", "eeeeddddeeeeddddddddeeeeddddeeeececebdbdcecebdbDbdbdcecebdbdce"],
|
|
28819
|
-
88: [33, "ce..", "eeeedededdddeeeeededededededeeeecececdcdcdcdcdcdcecebdbdbebece"],
|
|
28820
|
-
89: [33, "cF..", "ededeeeeddddddddededdedededeeeEecEcebebEbebecdcdbdbdbdbdcececd"],
|
|
28821
|
-
90: [33, "dF..", "ddddededeeeeededeeeedededededdDdbdbdbebebEbecececdcdcececdcdbd"],
|
|
28822
|
-
91: [33, "df..", "ddddeeeededededeededdddddededdDdbdbdbebebdbdcdcdbebebebececebd"],
|
|
28823
|
-
92: [33, "de..", "dedededeededdddddededededdddedEdcdcdbdbdbebebebebdbdcdcdbebebe"],
|
|
28824
|
-
93: [33, "de..", "dededddddddddedeededeeeeeeeeededcdcdcececececdcdbebebdbdbdbdbe"],
|
|
28825
|
-
94: [33, "dF..", "ddddeeeeddddeeeeddddeeeededeedEdcDcdbebececebdbDcecebdbdcecebd"],
|
|
28826
|
-
95: [33, "df..", "ddddddddededeeeedddddededdddddDdbdbDbdbdbebecdcdbebecdcdbdbdbd"],
|
|
28827
|
-
96: [33, "cf..", "ededeeeededeeeeedededdddeeeedeDebebececebdbdbebececebebecececd"],
|
|
28828
|
-
97: [33, "ce..", "eeeedededededededdddeeeedddddeDebebebdbdcEcebdbdbebebEbebebece"],
|
|
28829
|
-
98: [33, "ce..", "eeeeededededeeeeeeeededededeeeEececebebebebecececececdcdcdcdce"],
|
|
28830
|
-
99: [33, "cf..", "ededededddddddddddddededdedeeeEececebebecdcdbdbdbdbdbdbdcdcdcd"],
|
|
28831
|
-
100: [33, "cf..", "ededdedeeeeededededeeeeeededdeDebebecdcdcecebebebebececebebecd"]
|
|
28832
|
-
};
|
|
28833
|
-
function sectorBias(code) {
|
|
28834
|
-
return code >= 97 ? (code - 97) / 2 - 1.5 : (code - 65) / 2 - 1.5 - 1 / 64;
|
|
29119
|
+
function oddEdgeAdjustment(odd, firstEdge) {
|
|
29120
|
+
return odd ? firstEdge ? 0.5 : -0.5 : 0;
|
|
28835
29121
|
}
|
|
28836
|
-
|
|
28837
|
-
|
|
28838
|
-
|
|
28839
|
-
if (width < HOBBY_LIMIT || width > 1400) {
|
|
28840
|
-
return void 0;
|
|
29122
|
+
function floorDivision(a, b) {
|
|
29123
|
+
if (Number.isSafeInteger(a) && Number.isSafeInteger(b)) {
|
|
29124
|
+
return Math.floor(a / b);
|
|
28841
29125
|
}
|
|
28842
|
-
|
|
28843
|
-
|
|
28844
|
-
|
|
28845
|
-
|
|
28846
|
-
}
|
|
29126
|
+
const A = BigInt(Math.round(a)), B = BigInt(Math.round(b));
|
|
29127
|
+
let q = A / B;
|
|
29128
|
+
if (A % B !== 0n && A < 0n !== B < 0n) {
|
|
29129
|
+
q -= 1n;
|
|
28847
29130
|
}
|
|
28848
|
-
return
|
|
29131
|
+
return Number(q);
|
|
28849
29132
|
}
|
|
28850
29133
|
var penCache = /* @__PURE__ */ new Map();
|
|
28851
29134
|
function penPolygon(width) {
|
|
@@ -28917,6 +29200,9 @@ function perpendicularVectors(width, dx0, dy0) {
|
|
|
28917
29200
|
best = i;
|
|
28918
29201
|
}
|
|
28919
29202
|
}
|
|
29203
|
+
if (flip && best === 0 && nx * pen[n - 1][0] + ny * pen[n - 1][1] === bh) {
|
|
29204
|
+
best = n - 1;
|
|
29205
|
+
}
|
|
28920
29206
|
const P = pen[(best + n - 1) % n];
|
|
28921
29207
|
const N = pen[(best + 1) % n];
|
|
28922
29208
|
const D = pen[best];
|
|
@@ -28925,20 +29211,19 @@ function perpendicularVectors(width, dx0, dy0) {
|
|
|
28925
29211
|
const [B, hB, hS] = hP >= hN ? [P, hP, hN] : [N, hN, hP];
|
|
28926
29212
|
const den = 2 * (bh - hB + (bh - hS));
|
|
28927
29213
|
const w = den === 0 ? 0 : (hB - hS) / den;
|
|
28928
|
-
const r = (v) => 8 * Math.floor((v + 4) / 8);
|
|
28929
29214
|
const x = D[0] + (B[0] - D[0]) * w, y = D[1] + (B[1] - D[1]) * w;
|
|
28930
|
-
|
|
28931
|
-
const
|
|
28932
|
-
|
|
28933
|
-
|
|
28934
|
-
const
|
|
28935
|
-
if (
|
|
28936
|
-
|
|
28937
|
-
|
|
28938
|
-
|
|
28939
|
-
|
|
28940
|
-
|
|
28941
|
-
const vx =
|
|
29215
|
+
const signs = [dx === 0 ? 0 : Math.sign(dy), Math.sign(dx)];
|
|
29216
|
+
const firstEdge = best === 0 && hP >= hN;
|
|
29217
|
+
const num = hB - hS;
|
|
29218
|
+
const rounded = [0, 1].map((c) => {
|
|
29219
|
+
const bias2 = signs[c] + 2 * oddEdgeAdjustment(Math.abs(B[c] - D[c]) % 2 === 1, firstEdge);
|
|
29220
|
+
if (den === 0) {
|
|
29221
|
+
return 8 * (c === 1 && dy < 0 ? Math.ceil((D[c] + bias2 / 2 + 4) / 8) - 1 : Math.floor((D[c] + bias2 / 2 + 4) / 8));
|
|
29222
|
+
}
|
|
29223
|
+
const top = D[c] * den + (B[c] - D[c]) * num;
|
|
29224
|
+
return 8 * floorDivision(2 * top + den * (bias2 + 8) - (c === 1 && dy < 0 ? 1 : 0), 16 * den);
|
|
29225
|
+
});
|
|
29226
|
+
const vx = rounded[0], vy = rounded[1];
|
|
28942
29227
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
28943
29228
|
}
|
|
28944
29229
|
function squareExtension(width, dx, dy) {
|
|
@@ -28968,7 +29253,6 @@ var Outliner = class {
|
|
|
28968
29253
|
this.n = this.pen.length;
|
|
28969
29254
|
this.rr = opts.cap === "round" && opts.join === "round";
|
|
28970
29255
|
this.originalRoundJoinSides = opts.join === "round" && opts.cap !== "flat";
|
|
28971
|
-
this.roundJoinSides = !!opts.roundCurveJoins || this.originalRoundJoinSides;
|
|
28972
29256
|
this.maxX = Math.max(...this.pen.map((q) => Math.abs(q[0])));
|
|
28973
29257
|
}
|
|
28974
29258
|
/**
|
|
@@ -28976,14 +29260,14 @@ var Outliner = class {
|
|
|
28976
29260
|
* `drawDir` (a curve's end tangent) only picks the draw vertices, the
|
|
28977
29261
|
* perpendicular following the chord (measured on Bezier ends).
|
|
28978
29262
|
*/
|
|
28979
|
-
seg(a, b, dir, drawDir) {
|
|
29263
|
+
seg(a, b, dir, drawDir, curve = false) {
|
|
28980
29264
|
const dx = dir ? dir[0] : b[0] - a[0];
|
|
28981
29265
|
const dy = dir ? dir[1] : b[1] - a[1];
|
|
28982
29266
|
const d = drawDir ?? [dx, dy];
|
|
28983
29267
|
const [L, R] = drawVertices(this.pen, d[0], d[1]);
|
|
28984
|
-
const perpendicular =
|
|
29268
|
+
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
28985
29269
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
|
|
28986
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width,
|
|
29270
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
28987
29271
|
}
|
|
28988
29272
|
push(p, v) {
|
|
28989
29273
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29018,7 +29302,7 @@ var Outliner = class {
|
|
|
29018
29302
|
* vertex exactly on `A`'s ray is included when `startIncl`, one on `B`'s
|
|
29019
29303
|
* ray when `endIncl`.
|
|
29020
29304
|
*/
|
|
29021
|
-
wedge(p, A, B, startIncl, endIncl) {
|
|
29305
|
+
wedge(p, A, B, startIncl, endIncl, tail = -1) {
|
|
29022
29306
|
const TWO = Math.PI * 2;
|
|
29023
29307
|
const aA = Math.atan2(A[1], A[0]);
|
|
29024
29308
|
const angleOf = (Q) => {
|
|
@@ -29049,13 +29333,21 @@ var Outliner = class {
|
|
|
29049
29333
|
}
|
|
29050
29334
|
}
|
|
29051
29335
|
list.sort((x, y) => x[0] - y[0]);
|
|
29336
|
+
if (tail >= 0 && !list.some(([, k]) => k === tail)) {
|
|
29337
|
+
list.push([Infinity, tail]);
|
|
29338
|
+
}
|
|
29052
29339
|
for (const [, k] of list) {
|
|
29053
29340
|
this.penAt(p, k);
|
|
29054
29341
|
}
|
|
29055
29342
|
}
|
|
29343
|
+
/** The pen's extreme-x vertex `k` that a steep segment `s` rests on, or -1 when the rule does not apply. */
|
|
29344
|
+
extremeTail(applies, k, s) {
|
|
29345
|
+
const q = this.pen[k];
|
|
29346
|
+
return applies && Math.abs(s.dy) > Math.abs(s.dx) && Math.abs(q[0]) === this.maxX && q[1] === 0 ? k : -1;
|
|
29347
|
+
}
|
|
29056
29348
|
/** Side offset of segment `s` at a join. */
|
|
29057
29349
|
joinSide(s, side) {
|
|
29058
|
-
if (this.
|
|
29350
|
+
if (this.originalRoundJoinSides || s.curve) {
|
|
29059
29351
|
const q = this.pen[side === "L" ? s.L : s.R];
|
|
29060
29352
|
return [halfPixel(q[0]), halfPixel(q[1])];
|
|
29061
29353
|
}
|
|
@@ -29103,32 +29395,36 @@ var Outliner = class {
|
|
|
29103
29395
|
*/
|
|
29104
29396
|
join(p, a, b, side, outer) {
|
|
29105
29397
|
const { cap, width, miterLimit } = this.opts;
|
|
29106
|
-
const
|
|
29398
|
+
const curveJoin = a.curve && b.curve;
|
|
29399
|
+
const join = curveJoin ? "round" : this.opts.join;
|
|
29400
|
+
const roundSides = this.originalRoundJoinSides || curveJoin;
|
|
29107
29401
|
let sa = this.joinSide(a, side);
|
|
29108
29402
|
let sb = this.joinSide(b, side);
|
|
29109
29403
|
const rayA = side === "R" ? a.vRaw : [-a.vRaw[0], -a.vRaw[1]];
|
|
29110
29404
|
const rayB = side === "R" ? b.vRaw : [-b.vRaw[0], -b.vRaw[1]];
|
|
29111
|
-
if (
|
|
29112
|
-
|
|
29113
|
-
sb = side === "R" ?
|
|
29405
|
+
if (curveJoin && !this.originalRoundJoinSides && a.curveEnd && b.curveEnd) {
|
|
29406
|
+
const t = a.tangentLength >= b.tangentLength ? a : b;
|
|
29407
|
+
sa = sb = side === "R" ? t.v : [-t.v[0], -t.v[1]];
|
|
29114
29408
|
}
|
|
29115
29409
|
const Da = side === "R" ? a.R : a.L;
|
|
29116
29410
|
const Db = side === "R" ? b.R : b.L;
|
|
29117
|
-
if (
|
|
29411
|
+
if (roundSides && (Da === Db || curveJoin && sa[0] === sb[0] && sa[1] === sb[1])) {
|
|
29118
29412
|
this.push(p, sa);
|
|
29119
29413
|
return;
|
|
29120
29414
|
}
|
|
29121
29415
|
this.push(p, sa);
|
|
29122
29416
|
if (outer) {
|
|
29123
29417
|
if (join === "round") {
|
|
29124
|
-
if (
|
|
29418
|
+
if (roundSides) {
|
|
29125
29419
|
const q = this.pen[Db];
|
|
29126
29420
|
const steep = Math.abs(b.dy) > Math.abs(b.dx);
|
|
29127
29421
|
const incl = side === "L" && steep && Math.abs(q[0]) === this.maxX && q[0] * q[1] <= 0;
|
|
29128
29422
|
this.walk(p, Da, Db, false, incl);
|
|
29129
29423
|
} else {
|
|
29130
29424
|
const anti = sa[0] === -sb[0] && sa[1] === -sb[1];
|
|
29131
|
-
|
|
29425
|
+
if (Da !== Db || anti) {
|
|
29426
|
+
this.wedge(p, rayA, rayB, !anti, false, this.extremeTail(side === "L" && !anti, Db, b));
|
|
29427
|
+
}
|
|
29132
29428
|
}
|
|
29133
29429
|
} else if (join === "miter") {
|
|
29134
29430
|
const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit, side);
|
|
@@ -29138,14 +29434,16 @@ var Outliner = class {
|
|
|
29138
29434
|
}
|
|
29139
29435
|
} else {
|
|
29140
29436
|
this.pts.push([p[0], p[1]]);
|
|
29141
|
-
if (
|
|
29437
|
+
if (curveJoin && !this.originalRoundJoinSides) {
|
|
29142
29438
|
this.push(p, sb);
|
|
29143
29439
|
this.push(p, sa);
|
|
29144
29440
|
this.pts.push([p[0], p[1]]);
|
|
29145
29441
|
}
|
|
29146
|
-
if (join === "round" && cap === "flat" && !
|
|
29442
|
+
if (join === "round" && cap === "flat" && !curveJoin) {
|
|
29147
29443
|
this.push(p, sb);
|
|
29148
|
-
|
|
29444
|
+
if (Da !== Db) {
|
|
29445
|
+
this.wedge(p, rayB, rayA, false, false, this.extremeTail(side === "L", Da, a));
|
|
29446
|
+
}
|
|
29149
29447
|
this.push(p, sa);
|
|
29150
29448
|
this.pts.push([p[0], p[1]]);
|
|
29151
29449
|
}
|
|
@@ -29178,17 +29476,17 @@ var Outliner = class {
|
|
|
29178
29476
|
* lets a single point stand for a zero-length dash along `dirs[0]`;
|
|
29179
29477
|
* `draws` (curve end tangents) picks draw vertices only.
|
|
29180
29478
|
*/
|
|
29181
|
-
open(P, dirs, draws) {
|
|
29479
|
+
open(P, dirs, draws, curves) {
|
|
29182
29480
|
if (P.length < 2 && !dirs?.[0]) {
|
|
29183
29481
|
this.dot(P[0]);
|
|
29184
29482
|
return;
|
|
29185
29483
|
}
|
|
29186
29484
|
const segs2 = [];
|
|
29187
29485
|
for (let i = 0; i + 1 < P.length; i++) {
|
|
29188
|
-
segs2.push(this.seg(P[i], P[i + 1], dirs?.[i], draws?.[i]));
|
|
29486
|
+
segs2.push(this.seg(P[i], P[i + 1], dirs?.[i], draws?.[i], curves?.[i]));
|
|
29189
29487
|
}
|
|
29190
29488
|
if (segs2.length === 0) {
|
|
29191
|
-
const s = this.seg(P[0], P[0], dirs?.[0], draws?.[0]);
|
|
29489
|
+
const s = this.seg(P[0], P[0], dirs?.[0], draws?.[0], curves?.[0]);
|
|
29192
29490
|
this.cap(P[0], s, true);
|
|
29193
29491
|
this.cap(P[0], s, false);
|
|
29194
29492
|
this.flush();
|
|
@@ -29219,11 +29517,11 @@ var Outliner = class {
|
|
|
29219
29517
|
this.flush();
|
|
29220
29518
|
}
|
|
29221
29519
|
/** Outlines a closed polygon (distinct consecutive points, not repeating the first). */
|
|
29222
|
-
closed(P, draws) {
|
|
29520
|
+
closed(P, draws, curves) {
|
|
29223
29521
|
const m = P.length;
|
|
29224
29522
|
const segs2 = [];
|
|
29225
29523
|
for (let i = 0; i < m; i++) {
|
|
29226
|
-
segs2.push(this.seg(P[i], P[(i + 1) % m], void 0, draws?.[i]));
|
|
29524
|
+
segs2.push(this.seg(P[i], P[(i + 1) % m], void 0, draws?.[i], curves?.[i]));
|
|
29227
29525
|
}
|
|
29228
29526
|
for (let j = 1; j <= m; j++) {
|
|
29229
29527
|
const i = j % m;
|
|
@@ -29315,9 +29613,10 @@ function widenPath(path, opts) {
|
|
|
29315
29613
|
const out = [];
|
|
29316
29614
|
const dashed = !!opts.dashes && opts.dashes.length > 0;
|
|
29317
29615
|
for (const fig of path.figures) {
|
|
29318
|
-
const outliner = new Outliner(
|
|
29616
|
+
const outliner = new Outliner(opts, out);
|
|
29319
29617
|
let P = [];
|
|
29320
29618
|
const dirs = [];
|
|
29619
|
+
const curves = [];
|
|
29321
29620
|
for (let i = 0; i + 1 < fig.pts.length; i += 2) {
|
|
29322
29621
|
const q = [fig.pts[i], fig.pts[i + 1]];
|
|
29323
29622
|
const last = P[P.length - 1];
|
|
@@ -29326,6 +29625,7 @@ function widenPath(path, opts) {
|
|
|
29326
29625
|
}
|
|
29327
29626
|
if (last) {
|
|
29328
29627
|
dirs.push(fig.tangents?.get(i / 2 - 1));
|
|
29628
|
+
curves.push(!!fig.roundWiden || !!fig.curveSegs?.has(i / 2 - 1));
|
|
29329
29629
|
}
|
|
29330
29630
|
P.push(q);
|
|
29331
29631
|
}
|
|
@@ -29352,14 +29652,14 @@ function widenPath(path, opts) {
|
|
|
29352
29652
|
pdraws.push(piece.draws[i - 1]);
|
|
29353
29653
|
}
|
|
29354
29654
|
}
|
|
29355
|
-
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]]);
|
|
29655
|
+
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]], pts.map(() => !!fig.roundWiden));
|
|
29356
29656
|
}
|
|
29357
29657
|
} else if (closed && P.length >= 3) {
|
|
29358
|
-
outliner.closed(P, dirs);
|
|
29658
|
+
outliner.closed(P, dirs, curves);
|
|
29359
29659
|
} else if (closed && P.length === 2) {
|
|
29360
29660
|
outliner.open([P[0], P[1], P[0]]);
|
|
29361
29661
|
} else {
|
|
29362
|
-
outliner.open(P, void 0, dirs);
|
|
29662
|
+
outliner.open(P, void 0, dirs, curves);
|
|
29363
29663
|
}
|
|
29364
29664
|
}
|
|
29365
29665
|
return out;
|
|
@@ -31104,6 +31404,10 @@ function hasIlluminant(ca) {
|
|
|
31104
31404
|
return illuminantCube(ca.illuminant) !== null;
|
|
31105
31405
|
}
|
|
31106
31406
|
var PALETTE = Array.from({ length: 32 }, (_, n) => Math.round(n * 255 / 31));
|
|
31407
|
+
function exactPaletteLevel(v) {
|
|
31408
|
+
const n = Math.round(v * 31 / 255);
|
|
31409
|
+
return PALETTE[n] === v ? 255 * n / 31 : v;
|
|
31410
|
+
}
|
|
31107
31411
|
function paletteIndex(v) {
|
|
31108
31412
|
const x = clamp012(v) * 255;
|
|
31109
31413
|
let n = Math.min(30, Math.floor(x * 31 / 255));
|
|
@@ -31189,6 +31493,7 @@ function invert3(m) {
|
|
|
31189
31493
|
}
|
|
31190
31494
|
var clamp012 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
31191
31495
|
var clamp255 = (v) => v < 0 ? 0 : v > 255 ? 255 : v;
|
|
31496
|
+
var roundHalfUp = (v) => Math.floor(v + 0.5 + 1e-7);
|
|
31192
31497
|
function adjustChroma(r, g, b, scale, angle) {
|
|
31193
31498
|
const x = RGB_TO_XYZ[0][0] * r + RGB_TO_XYZ[0][1] * g + RGB_TO_XYZ[0][2] * b;
|
|
31194
31499
|
const y = RGB_TO_XYZ[1][0] * r + RGB_TO_XYZ[1][1] * g + RGB_TO_XYZ[1][2] * b;
|
|
@@ -31240,7 +31545,7 @@ function colorAdjustmentMapper(ca) {
|
|
|
31240
31545
|
if (negative) {
|
|
31241
31546
|
v = 255 - clamp255(v);
|
|
31242
31547
|
}
|
|
31243
|
-
return
|
|
31548
|
+
return roundHalfUp(clamp255(v));
|
|
31244
31549
|
};
|
|
31245
31550
|
if (!illuminant && !chroma) {
|
|
31246
31551
|
const tables = [0, 1, 2].map((channel) => Uint8Array.from({ length: 256 }, (_, i) => curve(i, channel)));
|
|
@@ -31253,7 +31558,11 @@ function colorAdjustmentMapper(ca) {
|
|
|
31253
31558
|
c = [mapped[0] * 255, mapped[1] * 255, mapped[2] * 255];
|
|
31254
31559
|
}
|
|
31255
31560
|
if (chroma) {
|
|
31561
|
+
if (!illuminant) {
|
|
31562
|
+
c = c.map(exactPaletteLevel);
|
|
31563
|
+
}
|
|
31256
31564
|
c = adjustChroma(clamp255(c[0]), clamp255(c[1]), clamp255(c[2]), scale, angle);
|
|
31565
|
+
c = c.map(roundHalfUp);
|
|
31257
31566
|
}
|
|
31258
31567
|
return curve(c[0], 0) << 16 | curve(c[1], 1) << 8 | curve(c[2], 2);
|
|
31259
31568
|
};
|
|
@@ -31287,27 +31596,6 @@ function colorAdjustRgb(rgbs, ca) {
|
|
|
31287
31596
|
rgbs[i + 2] = v & 255;
|
|
31288
31597
|
}
|
|
31289
31598
|
}
|
|
31290
|
-
function applyColorAdjustment(pixels, ca) {
|
|
31291
|
-
if (!ca || isIdentityColorAdjustment(ca)) {
|
|
31292
|
-
return;
|
|
31293
|
-
}
|
|
31294
|
-
const map = colorAdjustmentMapper(ca);
|
|
31295
|
-
const d = pixels.data;
|
|
31296
|
-
const cache2 = /* @__PURE__ */ new Map();
|
|
31297
|
-
for (let i = 0; i + 3 < d.length; i += 4) {
|
|
31298
|
-
const rgb2 = d[i] << 16 | d[i + 1] << 8 | d[i + 2];
|
|
31299
|
-
let v = cache2.get(rgb2);
|
|
31300
|
-
if (v === void 0) {
|
|
31301
|
-
v = map(rgb2);
|
|
31302
|
-
if (cache2.size < 65536) {
|
|
31303
|
-
cache2.set(rgb2, v);
|
|
31304
|
-
}
|
|
31305
|
-
}
|
|
31306
|
-
d[i] = v >> 16 & 255;
|
|
31307
|
-
d[i + 1] = v >> 8 & 255;
|
|
31308
|
-
d[i + 2] = v & 255;
|
|
31309
|
-
}
|
|
31310
|
-
}
|
|
31311
31599
|
|
|
31312
31600
|
// src/emf-gdi-halftone-dither.ts
|
|
31313
31601
|
var THRESHOLDS = [
|
|
@@ -31466,22 +31754,22 @@ function halftoneAxis(start, srcLen, dstLen, reverse) {
|
|
|
31466
31754
|
if (reverse) taps.reverse();
|
|
31467
31755
|
return taps;
|
|
31468
31756
|
}
|
|
31757
|
+
var REDUCE_BITS = 13;
|
|
31469
31758
|
function halftoneReduceTaps(srcLen, dstLen, reverse) {
|
|
31470
31759
|
if (dstLen >= srcLen) return halftoneAxis(0, srcLen, dstLen, reverse);
|
|
31760
|
+
const shares = 2 ** REDUCE_BITS;
|
|
31761
|
+
const scale = FIX / shares;
|
|
31471
31762
|
const taps = [];
|
|
31472
31763
|
for (let i = 0; i < dstLen; i++) {
|
|
31473
31764
|
const from = i * srcLen;
|
|
31474
31765
|
const to = (i + 1) * srcLen;
|
|
31475
31766
|
const run = [];
|
|
31476
|
-
let rest = 0;
|
|
31477
31767
|
for (let k = Math.floor(from / dstLen); k * dstLen < to; k++) {
|
|
31478
|
-
const
|
|
31479
|
-
|
|
31480
|
-
|
|
31481
|
-
run.push([k,
|
|
31482
|
-
if (run.length > 1) rest += w;
|
|
31768
|
+
const lo = Math.max(from, k * dstLen) - from;
|
|
31769
|
+
const hi = Math.min(to, (k + 1) * dstLen) - from;
|
|
31770
|
+
if (hi <= lo) continue;
|
|
31771
|
+
run.push([k, (Math.floor(hi * shares / srcLen) - Math.floor(lo * shares / srcLen)) * scale]);
|
|
31483
31772
|
}
|
|
31484
|
-
if (run.length > 1) run[0][1] = FIX - rest;
|
|
31485
31773
|
taps.push(run);
|
|
31486
31774
|
}
|
|
31487
31775
|
if (reverse) taps.reverse();
|
|
@@ -31555,7 +31843,7 @@ function halftoneEnlargeTaps(src, dst) {
|
|
|
31555
31843
|
}
|
|
31556
31844
|
function ditherPixels(px, w, h, dither, flipX, flipY, phaseX, phaseY) {
|
|
31557
31845
|
for (let y = 0; y < h; y++) {
|
|
31558
|
-
const yy = phaseY ? phaseY[y] :
|
|
31846
|
+
const yy = phaseY ? phaseY[y] : y;
|
|
31559
31847
|
for (let x = 0; x < w; x++) {
|
|
31560
31848
|
const xx = phaseX ? phaseX[x] : x;
|
|
31561
31849
|
const threshold = ditherThreshold(dither.startX, dither.startY, xx, yy);
|
|
@@ -31642,11 +31930,33 @@ function halftoneSharpen(px, w, h) {
|
|
|
31642
31930
|
}
|
|
31643
31931
|
}
|
|
31644
31932
|
}
|
|
31933
|
+
function halftonePairDespeckle(px, w, h, rows) {
|
|
31934
|
+
const n = rows ? w : h;
|
|
31935
|
+
const at = (k, side) => (rows ? side * w + k : k * w + side) * 3;
|
|
31936
|
+
const same = (i, j) => px[i] === px[j] && px[i + 1] === px[j + 1] && px[i + 2] === px[j + 2];
|
|
31937
|
+
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));
|
|
31938
|
+
const mean = Array.from({ length: n }, (_, k) => checker(k - 1) || checker(k));
|
|
31939
|
+
for (let k = 0; k < n; k++) {
|
|
31940
|
+
if (!mean[k]) continue;
|
|
31941
|
+
const first = at(k, 0);
|
|
31942
|
+
const last = at(k, 1);
|
|
31943
|
+
for (let c = 0; c < 3; c++) px[first + c] = px[last + c] = px[first + c] + px[last + c] + 1 >> 1;
|
|
31944
|
+
}
|
|
31945
|
+
}
|
|
31946
|
+
function halftoneKeepLast(px, w, h, rows) {
|
|
31947
|
+
const n = rows ? w : h;
|
|
31948
|
+
const out = new Int32Array(n * 3);
|
|
31949
|
+
for (let k = 0; k < n; k++) {
|
|
31950
|
+
const last = (rows ? w + k : k * w + 1) * 3;
|
|
31951
|
+
for (let c = 0; c < 3; c++) out[k * 3 + c] = px[last + c];
|
|
31952
|
+
}
|
|
31953
|
+
return out;
|
|
31954
|
+
}
|
|
31645
31955
|
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSampling = false, directDib = false, dither, curves) {
|
|
31646
31956
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
31647
31957
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
31648
|
-
|
|
31649
|
-
|
|
31958
|
+
let SW = Math.round(Math.abs(sw));
|
|
31959
|
+
let SH = Math.round(Math.abs(sh));
|
|
31650
31960
|
const x0 = Math.round(Math.min(sx, sx + sw));
|
|
31651
31961
|
const y0 = Math.round(Math.min(sy, sy + sh));
|
|
31652
31962
|
const flipX = dw < 0 !== sw < 0;
|
|
@@ -31655,7 +31965,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31655
31965
|
if (W === 0 || H === 0 || SW === 0 || SH === 0) {
|
|
31656
31966
|
return { width: W, height: H, data };
|
|
31657
31967
|
}
|
|
31658
|
-
|
|
31968
|
+
let rect = new Int32Array(SW * SH * 3);
|
|
31659
31969
|
for (let y = 0; y < SH; y++) {
|
|
31660
31970
|
const yy = y0 + y;
|
|
31661
31971
|
for (let x = 0; x < SW; x++) {
|
|
@@ -31670,19 +31980,40 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31670
31980
|
rect[o + 2] = src.data[i + 2];
|
|
31671
31981
|
}
|
|
31672
31982
|
}
|
|
31983
|
+
const pairRows = SH === 2 && H === 1 && W > SW && (!adjust || adjustAfterSampling || !!dither);
|
|
31984
|
+
const pairColumns = SW === 2 && W === 1 && H > SH && (!adjust || adjustAfterSampling || !!dither);
|
|
31985
|
+
if (pairRows || pairColumns) {
|
|
31986
|
+
if (!directDib) halftonePairDespeckle(rect, SW, SH, pairRows);
|
|
31987
|
+
if (pairRows && W >= 2 * SW) {
|
|
31988
|
+
rect = halftoneKeepLast(rect, SW, SH, true);
|
|
31989
|
+
SH = 1;
|
|
31990
|
+
} else if (pairColumns && H >= 2 * SH) {
|
|
31991
|
+
rect = halftoneKeepLast(rect, SW, SH, false);
|
|
31992
|
+
SW = 1;
|
|
31993
|
+
}
|
|
31994
|
+
}
|
|
31673
31995
|
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
31674
31996
|
const reducing = W < SW && H < SH;
|
|
31675
31997
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
31676
31998
|
const dithered = !!dither && !!adjust && !adjustAfterSampling;
|
|
31677
31999
|
const nearestMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
31678
32000
|
const nativeMixed = mixed && (!adjust || adjustAfterSampling || dithered) && (W > SW && H * 2 <= SH || H > SH && W * 2 <= SW);
|
|
31679
|
-
if ((enlarging || nearestMixed) && !directDib) {
|
|
32001
|
+
if ((enlarging || nearestMixed) && !directDib && !pairRows && !pairColumns) {
|
|
31680
32002
|
halftoneDespeckle(rect, SW, SH);
|
|
31681
32003
|
}
|
|
31682
32004
|
const reducedEven = W < SW ? SW % 2 === 0 && H % SH === 0 : SH % 2 === 0 && W % SW === 0;
|
|
31683
32005
|
const ditherAtSource = dithered && (W >= SW && H >= SH || nativeMixed && reducedEven);
|
|
31684
32006
|
if (ditherAtSource) {
|
|
31685
|
-
ditherPixels(
|
|
32007
|
+
ditherPixels(
|
|
32008
|
+
rect,
|
|
32009
|
+
SW,
|
|
32010
|
+
SH,
|
|
32011
|
+
dither,
|
|
32012
|
+
false,
|
|
32013
|
+
false,
|
|
32014
|
+
void 0,
|
|
32015
|
+
flipY ? Int32Array.from({ length: SH }, (_, j) => H - 1 - j) : void 0
|
|
32016
|
+
);
|
|
31686
32017
|
}
|
|
31687
32018
|
if (adjust && !adjustAfterSampling && (!dithered || ditherAtSource)) {
|
|
31688
32019
|
adjust(rect);
|
|
@@ -31798,17 +32129,13 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
31798
32129
|
}
|
|
31799
32130
|
}
|
|
31800
32131
|
if (dithered && !ditherAtSource) {
|
|
31801
|
-
const phase = (n, src2, dst, selectSource) => Int32Array.from({ length: n }, (_, i) => dst > src2 ? Math.
|
|
31802
|
-
|
|
31803
|
-
|
|
31804
|
-
|
|
31805
|
-
|
|
31806
|
-
|
|
31807
|
-
|
|
31808
|
-
false,
|
|
31809
|
-
nearestMixed ? phase(W, SW, W, true) : void 0,
|
|
31810
|
-
nearestMixed ? phase(H, SH, H, false) : void 0
|
|
31811
|
-
);
|
|
32132
|
+
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);
|
|
32133
|
+
const sourcePhase = nearestMixed && W * H > SW * SH;
|
|
32134
|
+
let phaseX = sourcePhase ? phase(W, SW, W, true) : void 0;
|
|
32135
|
+
let phaseY = sourcePhase ? phase(H, SH, H, false) : void 0;
|
|
32136
|
+
if (phaseX && flipX) phaseX = phaseX.slice().reverse();
|
|
32137
|
+
if (phaseY && flipY && H > SH) phaseY = phaseY.slice().reverse().map((v) => H - 1 - v);
|
|
32138
|
+
ditherPixels(out, W, H, dither, false, false, phaseX, phaseY);
|
|
31812
32139
|
adjust(out);
|
|
31813
32140
|
}
|
|
31814
32141
|
if (adjust && adjustAfterSampling) adjust(out);
|
|
@@ -31871,7 +32198,7 @@ function drawSourceMapped(target, decoded, req, offsetX, offsetY, mode, brushOrg
|
|
|
31871
32198
|
canvasDrawImage(target, tile.canvas, Math.round(dLeft), Math.round(dTop), px.width, px.height);
|
|
31872
32199
|
target.restore();
|
|
31873
32200
|
}
|
|
31874
|
-
function decodeSource(rCtx, req) {
|
|
32201
|
+
function decodeSource(rCtx, req, rotated = false) {
|
|
31875
32202
|
if (!req.source) {
|
|
31876
32203
|
return null;
|
|
31877
32204
|
}
|
|
@@ -31886,6 +32213,9 @@ function decodeSource(rCtx, req) {
|
|
|
31886
32213
|
return null;
|
|
31887
32214
|
}
|
|
31888
32215
|
const ca = rCtx.state.colorAdjustment;
|
|
32216
|
+
if (req.stretch && rCtx.state.stretchBltMode === HALFTONE && rCtx.halftoneRotatedAdjusts === void 0) {
|
|
32217
|
+
rCtx.halftoneRotatedAdjusts = !rotated && !!ca;
|
|
32218
|
+
}
|
|
31889
32219
|
const halftone = req.stretch && rCtx.state.stretchBltMode === HALFTONE && ca;
|
|
31890
32220
|
const channelOnly = isChannelOnlyColorAdjustment(ca);
|
|
31891
32221
|
const split = halftone && !channelOnly ? splitColorAdjustment(ca) : void 0;
|
|
@@ -32033,6 +32363,7 @@ function executeRotatedBlit(rCtx, logDx, logDy, logDw, logDh, rop, source, sx, s
|
|
|
32033
32363
|
let src = null;
|
|
32034
32364
|
let srcX = sx;
|
|
32035
32365
|
let srcY = sy;
|
|
32366
|
+
let adjustTexel;
|
|
32036
32367
|
if (operands.usesS) {
|
|
32037
32368
|
const decoded = decodeSource(rCtx, {
|
|
32038
32369
|
plan: { kind: "ternary", index, operands },
|
|
@@ -32047,13 +32378,30 @@ function executeRotatedBlit(rCtx, logDx, logDy, logDw, logDh, rop, source, sx, s
|
|
|
32047
32378
|
sh,
|
|
32048
32379
|
dibOrigin,
|
|
32049
32380
|
stretch
|
|
32050
|
-
});
|
|
32381
|
+
}, true);
|
|
32051
32382
|
if (!decoded) {
|
|
32052
32383
|
return;
|
|
32053
32384
|
}
|
|
32054
32385
|
src = decoded.decoded.pixels;
|
|
32055
|
-
if (decoded.decoded.adjust) {
|
|
32056
|
-
|
|
32386
|
+
if (decoded.decoded.adjust && rCtx.halftoneRotatedAdjusts) {
|
|
32387
|
+
const { adjust, adjustAfterSampling, curves } = decoded.decoded;
|
|
32388
|
+
const startX = ditherStartX(0, rCtx.state.brushOrgX);
|
|
32389
|
+
const startY = ditherStartY(0, rCtx.state.brushOrgY);
|
|
32390
|
+
const triple = new Int32Array(3);
|
|
32391
|
+
adjustTexel = (rgb2, x, y) => {
|
|
32392
|
+
triple[0] = rgb2 >> 16 & 255;
|
|
32393
|
+
triple[1] = rgb2 >> 8 & 255;
|
|
32394
|
+
triple[2] = rgb2 & 255;
|
|
32395
|
+
if (!adjustAfterSampling) {
|
|
32396
|
+
const t = ditherThreshold(startX, startY, x, y);
|
|
32397
|
+
for (let c = 0; c < 3; c++) {
|
|
32398
|
+
triple[c] = ditherQuantize(triple[c], t);
|
|
32399
|
+
}
|
|
32400
|
+
}
|
|
32401
|
+
adjust(triple);
|
|
32402
|
+
curves?.(triple);
|
|
32403
|
+
return triple[0] << 16 | triple[1] << 8 | triple[2];
|
|
32404
|
+
};
|
|
32057
32405
|
}
|
|
32058
32406
|
srcX = decoded.req.sx;
|
|
32059
32407
|
srcY = decoded.req.sy;
|
|
@@ -32077,7 +32425,10 @@ function executeRotatedBlit(rCtx, logDx, logDy, logDw, logDh, rop, source, sx, s
|
|
|
32077
32425
|
sw,
|
|
32078
32426
|
sh,
|
|
32079
32427
|
(ix, iy, x, y, d) => {
|
|
32080
|
-
|
|
32428
|
+
let s = operands.usesS ? texel(ix, iy) : 0;
|
|
32429
|
+
if (adjustTexel && operands.usesS) {
|
|
32430
|
+
s = adjustTexel(s, x, y);
|
|
32431
|
+
}
|
|
32081
32432
|
const p = typeof pattern === "function" ? pattern(x, y) : pattern;
|
|
32082
32433
|
return evalRop3(index, p, s, d);
|
|
32083
32434
|
}
|
|
@@ -32132,6 +32483,19 @@ function alignMirroredDest(rCtx, req) {
|
|
|
32132
32483
|
dy: req.dh < 0 ? req.dy + pxY : req.dy
|
|
32133
32484
|
};
|
|
32134
32485
|
}
|
|
32486
|
+
function executePlgBltAsStretch(rCtx, dx, dy, dw, dh, source, r) {
|
|
32487
|
+
executeBlit(rCtx, {
|
|
32488
|
+
plan: classifyRop3(13369376),
|
|
32489
|
+
dx,
|
|
32490
|
+
dy,
|
|
32491
|
+
dw,
|
|
32492
|
+
dh,
|
|
32493
|
+
source,
|
|
32494
|
+
...r,
|
|
32495
|
+
dibOrigin: "top-left",
|
|
32496
|
+
stretch: true
|
|
32497
|
+
});
|
|
32498
|
+
}
|
|
32135
32499
|
function executeBlit(rCtx, request) {
|
|
32136
32500
|
const { ctx } = rCtx;
|
|
32137
32501
|
const req = alignMirroredDest(rCtx, request);
|
|
@@ -32634,6 +32998,18 @@ function handlePlgBlt(rCtx, offset, dataOff, recSize) {
|
|
|
32634
32998
|
if (b[1] === a[1] && q[0] === a[0]) {
|
|
32635
32999
|
const W = Math.round(Math.abs(b[0] - a[0]) / 16);
|
|
32636
33000
|
const H = Math.round(Math.abs(q[1] - a[1]) / 16);
|
|
33001
|
+
if (!mask && rCtx.state.stretchBltMode === HALFTONE && W > 0 && H > 0) {
|
|
33002
|
+
executePlgBltAsStretch(
|
|
33003
|
+
rCtx,
|
|
33004
|
+
Math.round(a[0] / 16),
|
|
33005
|
+
Math.round(a[1] / 16),
|
|
33006
|
+
b[0] < a[0] ? -W : W,
|
|
33007
|
+
q[1] < a[1] ? -H : H,
|
|
33008
|
+
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)),
|
|
33009
|
+
r
|
|
33010
|
+
);
|
|
33011
|
+
return;
|
|
33012
|
+
}
|
|
32637
33013
|
const left = Math.round(a[0] / 16) + (b[0] < a[0] ? 1 - W : 0);
|
|
32638
33014
|
const top = Math.round(a[1] / 16) + (q[1] < a[1] ? 1 - H : 0);
|
|
32639
33015
|
const aw = Math.abs(r.sw);
|
|
@@ -32654,6 +33030,9 @@ function handlePlgBlt(rCtx, offset, dataOff, recSize) {
|
|
|
32654
33030
|
});
|
|
32655
33031
|
return;
|
|
32656
33032
|
}
|
|
33033
|
+
if (rCtx.state.stretchBltMode === HALFTONE && rCtx.halftoneRotatedAdjusts === void 0) {
|
|
33034
|
+
rCtx.halftoneRotatedAdjusts = false;
|
|
33035
|
+
}
|
|
32657
33036
|
paintParallelogram(rCtx, a, b, q, r.sw, r.sh, (ix, iy) => texel(ix, iy));
|
|
32658
33037
|
}
|
|
32659
33038
|
function readBand(rCtx, offset, offBmi, cbBmi, offBits, cbBits, usage, scans) {
|
|
@@ -34782,6 +35161,7 @@ function flattenBracketPath(rCtx) {
|
|
|
34782
35161
|
}
|
|
34783
35162
|
for (const f of rCtx.rasterPath.figures) {
|
|
34784
35163
|
delete f.tangents;
|
|
35164
|
+
delete f.curveSegs;
|
|
34785
35165
|
delete f.roundWiden;
|
|
34786
35166
|
}
|
|
34787
35167
|
syncPathCmds(rCtx);
|
|
@@ -38873,7 +39253,7 @@ function wmfRectangle(p, l, t, r, b) {
|
|
|
38873
39253
|
axisRect: { interior: rectInterior(p, box) }
|
|
38874
39254
|
});
|
|
38875
39255
|
}
|
|
38876
|
-
function compatCorner(p, w, h, box) {
|
|
39256
|
+
function compatCorner(p, w, h, box, logical) {
|
|
38877
39257
|
const m = gdiDeviceMatrix(p.rCtx);
|
|
38878
39258
|
const cw = Math.round(Math.abs(w * m[0]) * 16);
|
|
38879
39259
|
const ch = Math.round(Math.abs(h * m[3]) * 16);
|
|
@@ -38881,24 +39261,21 @@ function compatCorner(p, w, h, box) {
|
|
|
38881
39261
|
const uy = 16 * p.ky;
|
|
38882
39262
|
if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME && !penIsCosmetic(p.rCtx)) {
|
|
38883
39263
|
const penWidth = p.rCtx.state.penWidth * Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2])) * 16;
|
|
38884
|
-
const
|
|
38885
|
-
return [Math.floor(Math.min(cw,
|
|
38886
|
-
}
|
|
38887
|
-
if (!penIsNull(p) && penIsCosmetic(p.rCtx)) {
|
|
38888
|
-
const width = box.x1 - box.x0, height = box.y1 - box.y0;
|
|
38889
|
-
return [Math.min(cw, width + ux) * width / (width + ux), Math.min(ch, height + uy) * height / (height + uy)];
|
|
39264
|
+
const width2 = box.x1 - box.x0, height2 = box.y1 - box.y0;
|
|
39265
|
+
return [Math.floor(Math.min(cw, width2 + penWidth) * width2 / (width2 + penWidth)), Math.floor(Math.min(ch, height2 + penWidth) * height2 / (height2 + penWidth))];
|
|
38890
39266
|
}
|
|
38891
|
-
|
|
38892
|
-
|
|
38893
|
-
|
|
38894
|
-
|
|
39267
|
+
const width = box.x1 - box.x0, height = box.y1 - box.y0;
|
|
39268
|
+
const fullW = Math.abs((logical[2] - logical[0]) * m[0]) * 16 || width + ux;
|
|
39269
|
+
const fullH = Math.abs((logical[3] - logical[1]) * m[3]) * 16 || height + uy;
|
|
39270
|
+
const scaled2 = [Math.min(Math.abs(w * m[0]) * 16, fullW) * width / fullW, Math.min(Math.abs(h * m[3]) * 16, fullH) * height / fullH];
|
|
39271
|
+
return penIsCosmetic(p.rCtx) && !penIsNull(p) ? scaled2 : [Math.floor(scaled2[0]), Math.floor(scaled2[1])];
|
|
38895
39272
|
}
|
|
38896
39273
|
function wmfRoundRect(p, l, t, r, b, w, h) {
|
|
38897
39274
|
const box = compatBox(p, l, t, r, b, { curved: true });
|
|
38898
39275
|
if (box.x1 < box.x0 || box.y1 < box.y0) {
|
|
38899
39276
|
return;
|
|
38900
39277
|
}
|
|
38901
|
-
const [cw, ch] = compatCorner(p, w, h, box);
|
|
39278
|
+
const [cw, ch] = compatCorner(p, w, h, box, [l, t, r, b]);
|
|
38902
39279
|
const cr = canvasRect(box);
|
|
38903
39280
|
paintGdiShape(p.rCtx, {
|
|
38904
39281
|
build: (c) => {
|
|
@@ -38951,10 +39328,14 @@ function compatArc(p, kind, l, t, r, b, xs, ys, xe, ye) {
|
|
|
38951
39328
|
if (box.x1 < box.x0 || box.y1 < box.y0) {
|
|
38952
39329
|
return null;
|
|
38953
39330
|
}
|
|
38954
|
-
const
|
|
39331
|
+
const m = gdiDeviceMatrix(p.rCtx);
|
|
39332
|
+
const deviceFix = (x, y) => [(m[0] * x + m[2] * y + m[4]) * 16, (m[1] * x + m[3] * y + m[5]) * 16];
|
|
39333
|
+
const [ax, ay] = deviceFix(l, t);
|
|
39334
|
+
const [bx, by] = deviceFix(r, b);
|
|
39335
|
+
const raw = { x0: Math.min(ax, bx), x1: Math.max(ax, bx), y0: Math.min(ay, by), y1: Math.max(ay, by) };
|
|
38955
39336
|
const onBox = (v, r0, r1, b0, b1) => (b0 + b1) / 2 + (r1 !== r0 ? (v - (r0 + r1) / 2) * (b1 - b0) / (r1 - r0) : v - (r0 + r1) / 2);
|
|
38956
39337
|
const radial = (x, y) => {
|
|
38957
|
-
const [fx, fy] =
|
|
39338
|
+
const [fx, fy] = deviceFix(x, y);
|
|
38958
39339
|
return [onBox(fx, raw.x0, raw.x1, box.x0, box.x1), onBox(fy, raw.y0, raw.y1, box.y0, box.y1)];
|
|
38959
39340
|
};
|
|
38960
39341
|
return { box, s: radial(xs, ys), e: radial(xe, ye) };
|