emf-converter 4.8.1 → 4.8.3
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/README.md +1 -1
- package/dist/browser.js +231 -80
- package/dist/browser.mjs +231 -80
- package/dist/index.js +231 -80
- package/dist/index.mjs +231 -80
- package/package.json +1 -1
package/dist/browser.mjs
CHANGED
|
@@ -17037,13 +17037,17 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
|
|
|
17037
17037
|
const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius, cropped ? { x: r, y: r, w: x1 - x0, h: y1 - y0 } : void 0, true) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, Math.ceil((y1 - y0) / (x1 - x0)));
|
|
17038
17038
|
const w = x1 - x0;
|
|
17039
17039
|
const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
|
|
17040
|
+
const halo = new Uint8ClampedArray((y1 - y0) * 4);
|
|
17040
17041
|
for (let y = 0; y < y1 - y0; y++) {
|
|
17041
17042
|
const from = ((y + r) * bw + r) * 4;
|
|
17042
17043
|
for (let i = 0; i < w * 4; i++) {
|
|
17043
17044
|
out[y * w * 4 + i] = Math.round(blurred[from + i]);
|
|
17044
17045
|
}
|
|
17046
|
+
for (let i = 0; i < 4; i++) {
|
|
17047
|
+
halo[y * 4 + i] = Math.round(blurred[from + w * 4 + i]);
|
|
17048
|
+
}
|
|
17045
17049
|
}
|
|
17046
|
-
return out;
|
|
17050
|
+
return { out, halo };
|
|
17047
17051
|
}
|
|
17048
17052
|
function applyImageEffectToRect(rgba, width, height, effect, src) {
|
|
17049
17053
|
if (width <= 0 || height <= 0 || rgba.length !== width * height * 4) {
|
|
@@ -17076,7 +17080,12 @@ function applyImageEffectToRect(rgba, width, height, effect, src) {
|
|
|
17076
17080
|
};
|
|
17077
17081
|
if (src && effect.kind === "blur" && effect.expandEdge) {
|
|
17078
17082
|
const cropped = Math.ceil(src.x + src.w) < width && Math.ceil(src.y + src.h) < height;
|
|
17079
|
-
|
|
17083
|
+
const { out: out2, halo } = expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1, cropped);
|
|
17084
|
+
const region2 = result(out2);
|
|
17085
|
+
if (shownWidth === w && shownHeight === h) {
|
|
17086
|
+
region2.haloRight = halo;
|
|
17087
|
+
}
|
|
17088
|
+
return region2;
|
|
17080
17089
|
}
|
|
17081
17090
|
let region = rgba;
|
|
17082
17091
|
if (w !== width || h !== height) {
|
|
@@ -20448,6 +20457,22 @@ function cubicIntegral(t, a) {
|
|
|
20448
20457
|
}
|
|
20449
20458
|
return Math.sign(t) * v;
|
|
20450
20459
|
}
|
|
20460
|
+
var FAR_FADE = [1, 1, 0.985, 0.95, 0.91, 0.85, 0.8, 0.745, 0.69, 0.63, 0.56, 0.5, 0.43, 0.35, 0.28, 0.22, 0.16, 0.11, 0.065, 0.03, 0];
|
|
20461
|
+
function fadeAt(d, bilinear) {
|
|
20462
|
+
if (d >= 1) {
|
|
20463
|
+
return 0;
|
|
20464
|
+
}
|
|
20465
|
+
if (bilinear) {
|
|
20466
|
+
return 1 - Math.max(0, d);
|
|
20467
|
+
}
|
|
20468
|
+
const x = Math.max(0, d) * 20;
|
|
20469
|
+
const i = Math.floor(x);
|
|
20470
|
+
return FAR_FADE[i] + (FAR_FADE[i + 1] - FAR_FADE[i]) * (x - i);
|
|
20471
|
+
}
|
|
20472
|
+
function nearSourceExtent(deviceLen, srcLen) {
|
|
20473
|
+
const d = Math.ceil(deviceLen - 1e-6) - srcLen;
|
|
20474
|
+
return d >= -1 && d <= 1;
|
|
20475
|
+
}
|
|
20451
20476
|
var BICUBIC_A = -0.5;
|
|
20452
20477
|
var HQ_BICUBIC_A = -1;
|
|
20453
20478
|
function axisFilter(kernel, scale, copy) {
|
|
@@ -20552,13 +20577,39 @@ function mirroredOrigin(o) {
|
|
|
20552
20577
|
return f === 0 ? o : Math.floor(o) + 1 - f;
|
|
20553
20578
|
}
|
|
20554
20579
|
function resampleImage(rgba, width, height, spec, surface) {
|
|
20580
|
+
if (spec.rightHalo && spec.rightHalo.length === height * 4) {
|
|
20581
|
+
const grown = new Uint8ClampedArray((width + 1) * height * 4);
|
|
20582
|
+
for (let y = 0; y < height; y++) {
|
|
20583
|
+
grown.set(rgba.subarray(y * width * 4, (y + 1) * width * 4), y * (width + 1) * 4);
|
|
20584
|
+
grown.set(spec.rightHalo.subarray(y * 4, y * 4 + 4), (y * (width + 1) + width) * 4);
|
|
20585
|
+
}
|
|
20586
|
+
return resampleImage(grown, width + 1, height, { ...spec, rightHalo: void 0 }, surface);
|
|
20587
|
+
}
|
|
20555
20588
|
if (spec.kernel === "nearest" && !spec.wrap) {
|
|
20556
20589
|
return resampleNearest(rgba, width, height, spec, surface);
|
|
20557
20590
|
}
|
|
20558
20591
|
let m = snapToDeviceGrid(spec);
|
|
20559
|
-
|
|
20592
|
+
let kernel = spec.kernel;
|
|
20560
20593
|
const hq = kernel === "hq-bilinear" || kernel === "hq-bicubic";
|
|
20561
20594
|
const axisAligned = m[1] === 0 && m[2] === 0;
|
|
20595
|
+
let farFade = false;
|
|
20596
|
+
let shiftX = 0;
|
|
20597
|
+
let shiftY = 0;
|
|
20598
|
+
if (hq && !axisAligned) {
|
|
20599
|
+
const extentU = Math.hypot(m[0], m[1]) * spec.srcW;
|
|
20600
|
+
const extentV = Math.hypot(m[2], m[3]) * spec.srcH;
|
|
20601
|
+
if (nearSourceExtent(extentU, spec.srcW) || nearSourceExtent(extentV, spec.srcH)) {
|
|
20602
|
+
kernel = kernel === "hq-bicubic" ? "bicubic" : "bilinear";
|
|
20603
|
+
} else {
|
|
20604
|
+
farFade = true;
|
|
20605
|
+
if (spec.halfPixelOffset) {
|
|
20606
|
+
const lu = Math.hypot(m[0], m[1]);
|
|
20607
|
+
const lv = Math.hypot(m[2], m[3]);
|
|
20608
|
+
shiftX = 0.5 * m[0] / lu + 0.5 * m[2] / lv;
|
|
20609
|
+
shiftY = 0.5 * m[1] / lu + 0.5 * m[3] / lv;
|
|
20610
|
+
}
|
|
20611
|
+
}
|
|
20612
|
+
}
|
|
20562
20613
|
if (hq && axisAligned) {
|
|
20563
20614
|
const ox = m[0] * spec.srcX + m[4];
|
|
20564
20615
|
m = [m[0], 0, 0, m[3], m[4] + mirroredOrigin(ox) - ox, m[5]];
|
|
@@ -20613,6 +20664,8 @@ function resampleImage(rgba, width, height, spec, surface) {
|
|
|
20613
20664
|
const vMax = spec.srcY + spec.srcH;
|
|
20614
20665
|
const wu = [];
|
|
20615
20666
|
const wv = [];
|
|
20667
|
+
const gradU = Math.hypot(inv2[0], inv2[2]);
|
|
20668
|
+
const gradV = Math.hypot(inv2[1], inv2[3]);
|
|
20616
20669
|
const c = spec.clampArgb ?? 0;
|
|
20617
20670
|
const edge = {
|
|
20618
20671
|
wrap: spec.wrap,
|
|
@@ -20624,8 +20677,8 @@ function resampleImage(rgba, width, height, spec, surface) {
|
|
|
20624
20677
|
const py = by0 + j + o;
|
|
20625
20678
|
for (let i = 0; i < w; i++) {
|
|
20626
20679
|
const px = bx0 + i + o;
|
|
20627
|
-
const u = inv2[0] * px + inv2[2] * py + inv2[4];
|
|
20628
|
-
const v = inv2[1] * px + inv2[3] * py + inv2[5];
|
|
20680
|
+
const u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
|
|
20681
|
+
const v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
|
|
20629
20682
|
const cx = px + COVERAGE_NUDGE_X;
|
|
20630
20683
|
const cy = py + COVERAGE_NUDGE_Y;
|
|
20631
20684
|
const eu = inv2[0] * cx + inv2[2] * cy + inv2[4];
|
|
@@ -20633,31 +20686,35 @@ function resampleImage(rgba, width, height, spec, surface) {
|
|
|
20633
20686
|
if (eu < spec.srcX || ev < spec.srcY || eu >= uMax || ev >= vMax) {
|
|
20634
20687
|
continue;
|
|
20635
20688
|
}
|
|
20636
|
-
const
|
|
20637
|
-
const
|
|
20638
|
-
|
|
20639
|
-
|
|
20640
|
-
|
|
20641
|
-
|
|
20642
|
-
|
|
20643
|
-
|
|
20644
|
-
|
|
20645
|
-
|
|
20646
|
-
|
|
20647
|
-
|
|
20648
|
-
|
|
20649
|
-
|
|
20650
|
-
|
|
20651
|
-
|
|
20652
|
-
|
|
20653
|
-
|
|
20654
|
-
|
|
20655
|
-
|
|
20656
|
-
|
|
20657
|
-
|
|
20658
|
-
|
|
20659
|
-
|
|
20660
|
-
|
|
20689
|
+
const box = { x0: 0, y0: 0, x1: width, y1: height };
|
|
20690
|
+
const sampleAt = (cu, cv) => {
|
|
20691
|
+
const iu0 = Math.ceil(cu - fu.radius);
|
|
20692
|
+
const iu1 = Math.floor(cu + fu.radius);
|
|
20693
|
+
const iv0 = Math.ceil(cv - fv.radius);
|
|
20694
|
+
const iv1 = Math.floor(cv + fv.radius);
|
|
20695
|
+
wu.length = 0;
|
|
20696
|
+
wv.length = 0;
|
|
20697
|
+
for (let t = iu0; t <= iu1; t++) {
|
|
20698
|
+
wu.push(fu.weight(t, cu));
|
|
20699
|
+
}
|
|
20700
|
+
for (let t = iv0; t <= iv1; t++) {
|
|
20701
|
+
wv.push(fv.weight(t, cv));
|
|
20702
|
+
}
|
|
20703
|
+
return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge);
|
|
20704
|
+
};
|
|
20705
|
+
let [r, g, b, a] = sampleAt(u, v);
|
|
20706
|
+
if (farFade && !spec.wrap && a > 0) {
|
|
20707
|
+
const du = (uMax - u) / gradU;
|
|
20708
|
+
const dv = (vMax - v) / gradV;
|
|
20709
|
+
const k = 1 - (du < 1 ? fadeAt(du, kernel === "hq-bilinear") * (sampleAt(uMax, v)[3] / a) : 0) - (dv < 1 ? fadeAt(dv, kernel === "hq-bilinear") * (sampleAt(u, vMax)[3] / a) : 0);
|
|
20710
|
+
if (k < 1) {
|
|
20711
|
+
const f = Math.max(0, k);
|
|
20712
|
+
r *= f;
|
|
20713
|
+
g *= f;
|
|
20714
|
+
b *= f;
|
|
20715
|
+
a *= f;
|
|
20716
|
+
}
|
|
20717
|
+
}
|
|
20661
20718
|
if (a <= 0) {
|
|
20662
20719
|
continue;
|
|
20663
20720
|
}
|
|
@@ -23484,7 +23541,8 @@ function effectedDraw(img, bitmap, effect, draw, source) {
|
|
|
23484
23541
|
srcY,
|
|
23485
23542
|
srcW,
|
|
23486
23543
|
srcH,
|
|
23487
|
-
toDevice: mulMatrix(draw.resample.toDevice, shift)
|
|
23544
|
+
toDevice: mulMatrix(draw.resample.toDevice, shift),
|
|
23545
|
+
rightHalo: region.haloRight
|
|
23488
23546
|
}
|
|
23489
23547
|
}
|
|
23490
23548
|
};
|
|
@@ -29226,9 +29284,9 @@ function perpendicularVectors(width, dx0, dy0) {
|
|
|
29226
29284
|
const vx = rounded[0], vy = rounded[1];
|
|
29227
29285
|
return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
|
|
29228
29286
|
}
|
|
29229
|
-
function squareExtension(width, dx, dy) {
|
|
29287
|
+
function squareExtension(width, dx, dy, scale = 1) {
|
|
29230
29288
|
const len = Math.hypot(dx, dy);
|
|
29231
|
-
const r = width / 2;
|
|
29289
|
+
const r = width / 2 * scale;
|
|
29232
29290
|
return [Math.floor(dx / len * r + 0.5), Math.floor(dy / len * r + 0.5)];
|
|
29233
29291
|
}
|
|
29234
29292
|
function turnSign(ax, ay, bx, by) {
|
|
@@ -29267,7 +29325,7 @@ var Outliner = class {
|
|
|
29267
29325
|
const [L, R] = drawVertices(this.pen, d[0], d[1]);
|
|
29268
29326
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
29269
29327
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
|
|
29270
|
-
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29328
|
+
return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, perpendicular[0], perpendicular[1]), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
29271
29329
|
}
|
|
29272
29330
|
push(p, v) {
|
|
29273
29331
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -29362,7 +29420,7 @@ var Outliner = class {
|
|
|
29362
29420
|
return side === "R" ? s.v : [-s.v[0], -s.v[1]];
|
|
29363
29421
|
}
|
|
29364
29422
|
/** A cap at `p` from the `from` side of `s` round to the other side (`start`: around the back). */
|
|
29365
|
-
cap(p, s, start) {
|
|
29423
|
+
cap(p, s, start, scale = 1) {
|
|
29366
29424
|
const from = start ? "L" : "R";
|
|
29367
29425
|
const to = start ? "R" : "L";
|
|
29368
29426
|
const { cap } = this.opts;
|
|
@@ -29380,7 +29438,8 @@ var Outliner = class {
|
|
|
29380
29438
|
const sv = this.capSide(s, from);
|
|
29381
29439
|
const ev = this.capSide(s, to);
|
|
29382
29440
|
if (cap === "square") {
|
|
29383
|
-
const
|
|
29441
|
+
const e0 = scale === 1 ? s.e : squareExtension(this.opts.width, s.pe[0], s.pe[1], scale);
|
|
29442
|
+
const e = start ? [-e0[0], -e0[1]] : e0;
|
|
29384
29443
|
this.push(p, [sv[0] + e[0], sv[1] + e[1]]);
|
|
29385
29444
|
this.push(p, [ev[0] + e[0], ev[1] + e[1]]);
|
|
29386
29445
|
} else {
|
|
@@ -29476,7 +29535,7 @@ var Outliner = class {
|
|
|
29476
29535
|
* lets a single point stand for a zero-length dash along `dirs[0]`;
|
|
29477
29536
|
* `draws` (curve end tangents) picks draw vertices only.
|
|
29478
29537
|
*/
|
|
29479
|
-
open(P, dirs, draws, curves) {
|
|
29538
|
+
open(P, dirs, draws, curves, startScale = 1, endScale = 1) {
|
|
29480
29539
|
if (P.length < 2 && !dirs?.[0]) {
|
|
29481
29540
|
this.dot(P[0]);
|
|
29482
29541
|
return;
|
|
@@ -29487,12 +29546,12 @@ var Outliner = class {
|
|
|
29487
29546
|
}
|
|
29488
29547
|
if (segs2.length === 0) {
|
|
29489
29548
|
const s = this.seg(P[0], P[0], dirs?.[0], draws?.[0], curves?.[0]);
|
|
29490
|
-
this.cap(P[0], s, true);
|
|
29491
|
-
this.cap(P[0], s, false);
|
|
29549
|
+
this.cap(P[0], s, true, startScale);
|
|
29550
|
+
this.cap(P[0], s, false, endScale);
|
|
29492
29551
|
this.flush();
|
|
29493
29552
|
return;
|
|
29494
29553
|
}
|
|
29495
|
-
this.cap(P[0], segs2[0], true);
|
|
29554
|
+
this.cap(P[0], segs2[0], true, startScale);
|
|
29496
29555
|
for (let i = 0; i + 1 < segs2.length; i++) {
|
|
29497
29556
|
const s = segs2[i];
|
|
29498
29557
|
const t = segs2[i + 1];
|
|
@@ -29503,7 +29562,7 @@ var Outliner = class {
|
|
|
29503
29562
|
this.join(P[i + 1], s, t, "R", tr < 0);
|
|
29504
29563
|
}
|
|
29505
29564
|
}
|
|
29506
|
-
this.cap(P[P.length - 1], segs2[segs2.length - 1], false);
|
|
29565
|
+
this.cap(P[P.length - 1], segs2[segs2.length - 1], false, endScale);
|
|
29507
29566
|
for (let i = segs2.length - 1; i > 0; i--) {
|
|
29508
29567
|
const s = segs2[i];
|
|
29509
29568
|
const t = segs2[i - 1];
|
|
@@ -29559,7 +29618,7 @@ var Outliner = class {
|
|
|
29559
29618
|
this.flush();
|
|
29560
29619
|
}
|
|
29561
29620
|
};
|
|
29562
|
-
function dashPieces(P, tangents, pattern, shorten) {
|
|
29621
|
+
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors) {
|
|
29563
29622
|
const out = [];
|
|
29564
29623
|
const dashes = [];
|
|
29565
29624
|
for (let i = 0; i < pattern.length; i += 2) {
|
|
@@ -29574,12 +29633,22 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29574
29633
|
let idx = 0;
|
|
29575
29634
|
let left = dashes[0];
|
|
29576
29635
|
let on = true;
|
|
29577
|
-
let cur = { pts: [P[0]], dirs: [], draws: [] };
|
|
29636
|
+
let cur = { pts: [P[0]], dirs: [], draws: [], curves: [], startScale: 1, endScale: 1 };
|
|
29578
29637
|
for (let i = 0; i + 1 < P.length; i++) {
|
|
29579
29638
|
const [x0, y0] = P[i];
|
|
29580
29639
|
const [x1, y1] = P[i + 1];
|
|
29581
29640
|
const dir = [x1 - x0, y1 - y0];
|
|
29582
|
-
const
|
|
29641
|
+
const real = Math.hypot(dir[0], dir[1]);
|
|
29642
|
+
const len = wholePixelVectors ? Math.hypot(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : Math.hypot(dir[0], dir[1]);
|
|
29643
|
+
if (len === 0) {
|
|
29644
|
+
if (on && cur) {
|
|
29645
|
+
cur.pts.push(P[i + 1]);
|
|
29646
|
+
cur.dirs.push(dir);
|
|
29647
|
+
cur.draws.push(tangents[i]);
|
|
29648
|
+
cur.curves.push(curveFlags[i]);
|
|
29649
|
+
}
|
|
29650
|
+
continue;
|
|
29651
|
+
}
|
|
29583
29652
|
let t = 0;
|
|
29584
29653
|
while (len - t > left || left === 0 && on) {
|
|
29585
29654
|
t += left;
|
|
@@ -29588,10 +29657,12 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29588
29657
|
cur.pts.push(q);
|
|
29589
29658
|
cur.dirs.push(dir);
|
|
29590
29659
|
cur.draws.push(tangents[i]);
|
|
29660
|
+
cur.curves.push(curveFlags[i]);
|
|
29661
|
+
cur.endScale = cur.pts[0] === P[0] && q[0] === P[0][0] && q[1] === P[0][1] ? 1 : real / len;
|
|
29591
29662
|
out.push(cur);
|
|
29592
29663
|
cur = null;
|
|
29593
29664
|
} else {
|
|
29594
|
-
cur = { pts: [q], dirs: [], draws: [] };
|
|
29665
|
+
cur = { pts: [q], dirs: [], draws: [], curves: [], startScale: real / len, endScale: 1 };
|
|
29595
29666
|
}
|
|
29596
29667
|
on = !on;
|
|
29597
29668
|
idx = (idx + 1) % dashes.length;
|
|
@@ -29602,9 +29673,12 @@ function dashPieces(P, tangents, pattern, shorten) {
|
|
|
29602
29673
|
cur.pts.push(P[i + 1]);
|
|
29603
29674
|
cur.dirs.push(dir);
|
|
29604
29675
|
cur.draws.push(tangents[i]);
|
|
29676
|
+
cur.curves.push(curveFlags[i]);
|
|
29677
|
+
cur.endScale = real / len;
|
|
29605
29678
|
}
|
|
29606
29679
|
}
|
|
29607
29680
|
if (on && cur && cur.dirs.length > 0) {
|
|
29681
|
+
cur.endScale = 1;
|
|
29608
29682
|
out.push(cur);
|
|
29609
29683
|
}
|
|
29610
29684
|
return out;
|
|
@@ -29639,10 +29713,13 @@ function widenPath(path, opts) {
|
|
|
29639
29713
|
if (dashed) {
|
|
29640
29714
|
const run = closed ? [...P, P[0]] : P;
|
|
29641
29715
|
const shorten = opts.cap === "flat" || opts.shortenDashes === false ? 0 : opts.width;
|
|
29642
|
-
|
|
29716
|
+
const runTangents = closed ? [...dirs, void 0] : dirs;
|
|
29717
|
+
const runCurves = closed ? [...curves, !!fig.roundWiden] : curves;
|
|
29718
|
+
for (const piece of dashPieces(run, runTangents, runCurves, opts.dashes, shorten, !!opts.wholePixelDashVectors)) {
|
|
29643
29719
|
const pts = [piece.pts[0]];
|
|
29644
29720
|
const pdirs = [];
|
|
29645
29721
|
const pdraws = [];
|
|
29722
|
+
const pcurves = [];
|
|
29646
29723
|
for (let i = 1; i < piece.pts.length; i++) {
|
|
29647
29724
|
const q = piece.pts[i];
|
|
29648
29725
|
const last = pts[pts.length - 1];
|
|
@@ -29650,9 +29727,10 @@ function widenPath(path, opts) {
|
|
|
29650
29727
|
pts.push(q);
|
|
29651
29728
|
pdirs.push(piece.dirs[i - 1]);
|
|
29652
29729
|
pdraws.push(piece.draws[i - 1]);
|
|
29730
|
+
pcurves.push(piece.curves[i - 1]);
|
|
29653
29731
|
}
|
|
29654
29732
|
}
|
|
29655
|
-
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]],
|
|
29733
|
+
outliner.open(pts, pdirs.length > 0 ? pdirs : [piece.dirs[0]], pdirs.length > 0 ? pdraws : [piece.draws[0]], pdirs.length > 0 ? pcurves : [piece.curves[0]], piece.startScale, piece.endScale);
|
|
29656
29734
|
}
|
|
29657
29735
|
} else if (closed && P.length >= 3) {
|
|
29658
29736
|
outliner.closed(P, dirs, curves);
|
|
@@ -29860,7 +29938,10 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
29860
29938
|
join: opts.roundPen ? "round" : opts.rectangle && !state.penExtended ? "miter" : !state.penExtended || joinBits === 0 ? "round" : joinBits === 4096 ? "bevel" : "miter",
|
|
29861
29939
|
miterLimit: state.miterLimit ?? 10,
|
|
29862
29940
|
dashes: dashes ? dashes.map((v) => v * 16) : null,
|
|
29863
|
-
shortenDashes: (flags & 15) !== 7
|
|
29941
|
+
shortenDashes: (flags & 15) !== 7,
|
|
29942
|
+
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
29943
|
+
// segments in whole pixels.
|
|
29944
|
+
wholePixelDashVectors: Math.abs(matrix[0] - 1) < 1e-6 && Math.abs(matrix[3] - 1) < 1e-6 && Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6
|
|
29864
29945
|
};
|
|
29865
29946
|
}
|
|
29866
29947
|
function hatchBackgroundMask(hatch) {
|
|
@@ -31400,6 +31481,15 @@ function illuminantCube(index) {
|
|
|
31400
31481
|
}
|
|
31401
31482
|
return cube;
|
|
31402
31483
|
}
|
|
31484
|
+
var ILLUMINANT_MATRICES = {
|
|
31485
|
+
1: [[1.64737, -0.59174, -0.05494], [0.02963, 0.96126, 881e-5], [0.2911, 0.40189, 0.30769]],
|
|
31486
|
+
2: [[1.22319, -0.17765, -0.04515], [275e-5, 0.99054, 645e-5], [0.05514, 0.12795, 0.81816]],
|
|
31487
|
+
3: [[1.02833, -0.01775, -0.01086], [861e-5, 0.98431, 728e-5], [-0.01616, -0.0448, 1.05995]],
|
|
31488
|
+
4: [[1.17271, -0.14059, -0.03174], [-474e-5, 1.00266, 183e-5], [0.05783, 0.14663, 0.79683]],
|
|
31489
|
+
5: [[1.10431, -0.08327, -0.02067], [-336e-5, 1.0025, 67e-5], [0.03344, 0.09072, 0.87702]],
|
|
31490
|
+
7: [[0.92515, 0.05628, 0.01822], [318e-5, 0.9967, 34e-5], [-0.02086, -0.06817, 1.08783]],
|
|
31491
|
+
8: [[1.31275, -0.26259, -0.04977], [-244e-5, 0.99695, 524e-5], [0.10854, 0.23443, 0.65827]]
|
|
31492
|
+
};
|
|
31403
31493
|
function hasIlluminant(ca) {
|
|
31404
31494
|
return illuminantCube(ca.illuminant) !== null;
|
|
31405
31495
|
}
|
|
@@ -31470,9 +31560,9 @@ var BRIGHTNESS_STEP = 0.95625;
|
|
|
31470
31560
|
var COLORFULNESS_SCALE = 1 / 100;
|
|
31471
31561
|
var TINT_RADIANS = -Math.PI / 3;
|
|
31472
31562
|
var RGB_TO_XYZ = [
|
|
31473
|
-
[0.
|
|
31474
|
-
[0.
|
|
31475
|
-
[0.
|
|
31563
|
+
[0.4123908, 0.3575843, 0.1804808],
|
|
31564
|
+
[0.212639, 0.7151687, 0.0721923],
|
|
31565
|
+
[0.0193308, 0.1191948, 0.9505322]
|
|
31476
31566
|
];
|
|
31477
31567
|
var XYZ_TO_RGB = invert3(RGB_TO_XYZ);
|
|
31478
31568
|
var WHITE = RGB_TO_XYZ.map((row2) => row2[0] + row2[1] + row2[2]);
|
|
@@ -31500,13 +31590,13 @@ function adjustChroma(r, g, b, scale, angle) {
|
|
|
31500
31590
|
const z = RGB_TO_XYZ[2][0] * r + RGB_TO_XYZ[2][1] * g + RGB_TO_XYZ[2][2] * b;
|
|
31501
31591
|
const d = x + 15 * y + 3 * z;
|
|
31502
31592
|
if (d <= 1e-9 || y <= 1e-9) {
|
|
31503
|
-
return [r, g, b];
|
|
31593
|
+
return [clamp255(r), clamp255(g), clamp255(b)];
|
|
31504
31594
|
}
|
|
31505
31595
|
const du = 4 * x / d - WHITE_U;
|
|
31506
31596
|
const dv = 9 * y / d - WHITE_V;
|
|
31507
31597
|
const cos = Math.cos(angle) * scale;
|
|
31508
31598
|
const sin = Math.sin(angle) * scale;
|
|
31509
|
-
const u = WHITE_U + du * cos - dv * sin;
|
|
31599
|
+
const u = Math.max(0, WHITE_U + du * cos - dv * sin);
|
|
31510
31600
|
const v = Math.max(1e-6, WHITE_V + du * sin + dv * cos);
|
|
31511
31601
|
const x2 = y * 9 * u / (4 * v);
|
|
31512
31602
|
const z2 = y * (12 - 3 * u - 20 * v) / (4 * v);
|
|
@@ -31525,6 +31615,7 @@ function adjustChroma(r, g, b, scale, angle) {
|
|
|
31525
31615
|
}
|
|
31526
31616
|
function colorAdjustmentMapper(ca) {
|
|
31527
31617
|
const illuminant = illuminantCube(ca.illuminant);
|
|
31618
|
+
const matrix = ILLUMINANT_MATRICES[ca.illuminant];
|
|
31528
31619
|
const gammas = [ca.redGamma / 1e4, ca.greenGamma / 1e4, ca.blueGamma / 1e4];
|
|
31529
31620
|
const black = ca.referenceBlack / 1e4 * 255;
|
|
31530
31621
|
const span = Math.max(1e-6, ca.referenceWhite / 1e4 * 255 - black);
|
|
@@ -31553,16 +31644,17 @@ function colorAdjustmentMapper(ca) {
|
|
|
31553
31644
|
}
|
|
31554
31645
|
return (rgb2) => {
|
|
31555
31646
|
let c = [rgb2 >> 16 & 255, rgb2 >> 8 & 255, rgb2 & 255];
|
|
31556
|
-
if (illuminant) {
|
|
31557
|
-
const mapped = lookupIlluminant(illuminant, c[0] / 255, c[1] / 255, c[2] / 255);
|
|
31558
|
-
c = [mapped[0] * 255, mapped[1] * 255, mapped[2] * 255];
|
|
31559
|
-
}
|
|
31560
31647
|
if (chroma) {
|
|
31561
|
-
|
|
31562
|
-
|
|
31648
|
+
c = c.map(exactPaletteLevel);
|
|
31649
|
+
if (matrix) {
|
|
31650
|
+
const [r, g, b] = c;
|
|
31651
|
+
c = matrix.map((row2) => row2[0] * r + row2[1] * g + row2[2] * b);
|
|
31563
31652
|
}
|
|
31564
|
-
c = adjustChroma(
|
|
31653
|
+
c = adjustChroma(c[0], c[1], c[2], scale, angle);
|
|
31565
31654
|
c = c.map(roundHalfUp);
|
|
31655
|
+
} else if (illuminant) {
|
|
31656
|
+
const mapped = lookupIlluminant(illuminant, c[0] / 255, c[1] / 255, c[2] / 255);
|
|
31657
|
+
c = [mapped[0] * 255, mapped[1] * 255, mapped[2] * 255];
|
|
31566
31658
|
}
|
|
31567
31659
|
return curve(c[0], 0) << 16 | curve(c[1], 1) << 8 | curve(c[2], 2);
|
|
31568
31660
|
};
|
|
@@ -31916,20 +32008,6 @@ function halftoneDespeckle(px, w, h) {
|
|
|
31916
32008
|
}
|
|
31917
32009
|
}
|
|
31918
32010
|
}
|
|
31919
|
-
function halftoneSharpen(px, w, h) {
|
|
31920
|
-
const src = px.slice();
|
|
31921
|
-
const at = (x, y, c) => src[(Math.max(0, Math.min(h - 1, y)) * w + Math.max(0, Math.min(w - 1, x))) * 3 + c];
|
|
31922
|
-
for (let y = 0; y < h; y++) {
|
|
31923
|
-
for (let x = 0; x < w; x++) {
|
|
31924
|
-
for (let c = 0; c < 3; c++) {
|
|
31925
|
-
const v = at(x, y, c);
|
|
31926
|
-
const sum = at(x - 1, y, c) + at(x + 1, y, c) + at(x, y - 1, c) + at(x, y + 1, c);
|
|
31927
|
-
const out = v + Math.floor((4 * v - sum) / 8);
|
|
31928
|
-
px[(y * w + x) * 3 + c] = out < 0 ? 0 : out > 255 ? 255 : out;
|
|
31929
|
-
}
|
|
31930
|
-
}
|
|
31931
|
-
}
|
|
31932
|
-
}
|
|
31933
32011
|
function halftonePairDespeckle(px, w, h, rows) {
|
|
31934
32012
|
const n = rows ? w : h;
|
|
31935
32013
|
const at = (k, side) => (rows ? side * w + k : k * w + side) * 3;
|
|
@@ -31952,6 +32030,46 @@ function halftoneKeepLast(px, w, h, rows) {
|
|
|
31952
32030
|
}
|
|
31953
32031
|
return out;
|
|
31954
32032
|
}
|
|
32033
|
+
function halftoneReduceBoth(rect, sw, sh, dw, dh, flipX, flipY) {
|
|
32034
|
+
const cols = halftoneReduceTaps(sw, dw, flipX);
|
|
32035
|
+
const rows = halftoneReduceTaps(sh, dh, flipY);
|
|
32036
|
+
const wide = new Int32Array(dw * sh * 3);
|
|
32037
|
+
for (let y = 0; y < sh; y++) {
|
|
32038
|
+
for (let x = 0; x < dw; x++) {
|
|
32039
|
+
let total = 0;
|
|
32040
|
+
for (const [, w] of cols[x]) total += w;
|
|
32041
|
+
for (let c = 0; c < 3; c++) {
|
|
32042
|
+
let sum = 0;
|
|
32043
|
+
for (const [xx, w] of cols[x]) sum += rect[(y * sw + xx) * 3 + c] * w;
|
|
32044
|
+
wide[(y * dw + x) * 3 + c] = Math.floor((2 * sum + total) / (2 * total));
|
|
32045
|
+
}
|
|
32046
|
+
}
|
|
32047
|
+
}
|
|
32048
|
+
const avg = new Float64Array(dw * dh * 3);
|
|
32049
|
+
for (let y = 0; y < dh; y++) {
|
|
32050
|
+
let total = 0;
|
|
32051
|
+
for (const [, w] of rows[y]) total += w;
|
|
32052
|
+
for (let x = 0; x < dw; x++) {
|
|
32053
|
+
for (let c = 0; c < 3; c++) {
|
|
32054
|
+
let sum = 0;
|
|
32055
|
+
for (const [yy, w] of rows[y]) sum += wide[(yy * dw + x) * 3 + c] * w;
|
|
32056
|
+
avg[(y * dw + x) * 3 + c] = sum / total;
|
|
32057
|
+
}
|
|
32058
|
+
}
|
|
32059
|
+
}
|
|
32060
|
+
const at = (x, y, c) => avg[(Math.max(0, Math.min(dh - 1, y)) * dw + Math.max(0, Math.min(dw - 1, x))) * 3 + c];
|
|
32061
|
+
const out = new Int32Array(dw * dh * 3);
|
|
32062
|
+
for (let y = 0; y < dh; y++) {
|
|
32063
|
+
for (let x = 0; x < dw; x++) {
|
|
32064
|
+
for (let c = 0; c < 3; c++) {
|
|
32065
|
+
const v = at(x, y, c);
|
|
32066
|
+
const sum = at(x - 1, y, c) + at(x + 1, y, c) + at(x, y - 1, c) + at(x, y + 1, c);
|
|
32067
|
+
out[(y * dw + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (4 * v - sum) / 8)));
|
|
32068
|
+
}
|
|
32069
|
+
}
|
|
32070
|
+
}
|
|
32071
|
+
return out;
|
|
32072
|
+
}
|
|
31955
32073
|
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSampling = false, directDib = false, dither, curves) {
|
|
31956
32074
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
31957
32075
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
@@ -32003,11 +32121,18 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
32003
32121
|
}
|
|
32004
32122
|
const reducedEven = W < SW ? SW % 2 === 0 && H % SH === 0 : SH % 2 === 0 && W % SW === 0;
|
|
32005
32123
|
const ditherAtSource = dithered && (W >= SW && H >= SH || nativeMixed && reducedEven);
|
|
32124
|
+
const extendRow = ditherAtSource && nativeMixed && W < SW && H > SH && !flipY;
|
|
32125
|
+
if (extendRow) {
|
|
32126
|
+
const bigger = new Int32Array((SH + 1) * SW * 3);
|
|
32127
|
+
bigger.set(rect);
|
|
32128
|
+
bigger.copyWithin(SH * SW * 3, (SH - 1) * SW * 3, SH * SW * 3);
|
|
32129
|
+
rect = bigger;
|
|
32130
|
+
}
|
|
32006
32131
|
if (ditherAtSource) {
|
|
32007
32132
|
ditherPixels(
|
|
32008
32133
|
rect,
|
|
32009
32134
|
SW,
|
|
32010
|
-
SH,
|
|
32135
|
+
extendRow ? SH + 1 : SH,
|
|
32011
32136
|
dither,
|
|
32012
32137
|
false,
|
|
32013
32138
|
false,
|
|
@@ -32047,7 +32172,10 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
32047
32172
|
linear(rows, SH, H, flipY);
|
|
32048
32173
|
}
|
|
32049
32174
|
let out = nativeMixed ? new Float64Array(sampleW * sampleH * 3) : new Int32Array(W * H * 3);
|
|
32050
|
-
|
|
32175
|
+
if (reducing) {
|
|
32176
|
+
out = halftoneReduceBoth(rect, SW, SH, W, H, flipX, flipY);
|
|
32177
|
+
}
|
|
32178
|
+
for (let y = 0; !reducing && y < sampleH; y++) {
|
|
32051
32179
|
const ys = rows[y];
|
|
32052
32180
|
for (let x = 0; x < sampleW; x++) {
|
|
32053
32181
|
const xs = cols[x];
|
|
@@ -32072,15 +32200,38 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
32072
32200
|
out[o + 2] = round(b);
|
|
32073
32201
|
}
|
|
32074
32202
|
}
|
|
32075
|
-
if (reducing) {
|
|
32076
|
-
halftoneSharpen(out, W, H);
|
|
32077
|
-
}
|
|
32078
32203
|
if (nativeMixed) {
|
|
32079
32204
|
const reduceHorizontal = W < SW;
|
|
32205
|
+
let extension;
|
|
32206
|
+
if (extendRow) {
|
|
32207
|
+
const reduced = new Float64Array(sampleW * 3);
|
|
32208
|
+
for (let x = 0; x < sampleW; x++) {
|
|
32209
|
+
let total = 0;
|
|
32210
|
+
const sums = [0, 0, 0];
|
|
32211
|
+
for (const [xx, wx] of cols[x]) {
|
|
32212
|
+
total += wx;
|
|
32213
|
+
for (let c = 0; c < 3; c++) sums[c] += rect[(SH * SW + xx) * 3 + c] * wx;
|
|
32214
|
+
}
|
|
32215
|
+
for (let c = 0; c < 3; c++) reduced[x * 3 + c] = sums[c] / total;
|
|
32216
|
+
}
|
|
32217
|
+
extension = reduced;
|
|
32218
|
+
}
|
|
32080
32219
|
for (const horizontal of [reduceHorizontal, !reduceHorizontal]) {
|
|
32081
32220
|
const source2 = out;
|
|
32082
32221
|
out = new Int32Array(source2.length);
|
|
32083
|
-
const
|
|
32222
|
+
const ext = extension;
|
|
32223
|
+
const at = (x, y, c) => y >= sampleH && ext ? ext[Math.max(0, Math.min(sampleW - 1, x)) * 3 + c] : source2[(Math.max(0, Math.min(sampleH - 1, y)) * sampleW + Math.max(0, Math.min(sampleW - 1, x))) * 3 + c];
|
|
32224
|
+
if (horizontal && ext) {
|
|
32225
|
+
const next = new Int32Array(sampleW * 3);
|
|
32226
|
+
for (let x = 0; x < sampleW; x++) {
|
|
32227
|
+
for (let c = 0; c < 3; c++) {
|
|
32228
|
+
const v = ext[x * 3 + c];
|
|
32229
|
+
const sum = at(x - 1, sampleH, c) + at(x + 1, sampleH, c);
|
|
32230
|
+
next[x * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (2 * v - sum) / 4)));
|
|
32231
|
+
}
|
|
32232
|
+
}
|
|
32233
|
+
extension = next;
|
|
32234
|
+
}
|
|
32084
32235
|
for (let y = 0; y < sampleH; y++) {
|
|
32085
32236
|
for (let x = 0; x < sampleW; x++) {
|
|
32086
32237
|
for (let c = 0; c < 3; c++) {
|