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