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