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