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