emf-converter 4.17.0 → 4.18.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/README.md +4 -4
- package/THIRD_PARTY_NOTICES +31 -4
- package/dist/browser.js +1800 -396
- package/dist/browser.mjs +1800 -396
- package/dist/index.js +1800 -396
- package/dist/index.mjs +1800 -396
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -10445,12 +10445,12 @@ function cmykPlanesToRgba(planes, width, height, ycck) {
|
|
|
10445
10445
|
const fracOf = FRAC_OF;
|
|
10446
10446
|
const strides = [N * N * N * 3, N * N * 3, N * 3, 3];
|
|
10447
10447
|
const out = new Uint8Array(width * height * 4);
|
|
10448
|
-
const
|
|
10448
|
+
const fix2 = (x) => Math.floor(x * 65536 + 0.5);
|
|
10449
10449
|
const half = 1 << 15;
|
|
10450
|
-
const crR =
|
|
10451
|
-
const cbB =
|
|
10452
|
-
const crG = -
|
|
10453
|
-
const cbG = -
|
|
10450
|
+
const crR = fix2(1.402);
|
|
10451
|
+
const cbB = fix2(1.772);
|
|
10452
|
+
const crG = -fix2(0.71414);
|
|
10453
|
+
const cbG = -fix2(0.34414);
|
|
10454
10454
|
const inks = [0, 0, 0, 0];
|
|
10455
10455
|
const frac = [0, 0, 0, 0];
|
|
10456
10456
|
const order = [0, 1, 2, 3];
|
|
@@ -11361,12 +11361,12 @@ function convertPlanes({ width, height, planes: full, ids, adobe }, colorTransfo
|
|
|
11361
11361
|
}
|
|
11362
11362
|
} else {
|
|
11363
11363
|
const clamp2 = (v) => v < 0 ? 0 : v > 255 ? 255 : v;
|
|
11364
|
-
const
|
|
11364
|
+
const fix2 = (x) => Math.floor(x * 65536 + 0.5);
|
|
11365
11365
|
const half = 1 << 15;
|
|
11366
|
-
const crR =
|
|
11367
|
-
const cbB =
|
|
11368
|
-
const crG = -
|
|
11369
|
-
const cbG = -
|
|
11366
|
+
const crR = fix2(1.402);
|
|
11367
|
+
const cbB = fix2(1.772);
|
|
11368
|
+
const crG = -fix2(0.71414);
|
|
11369
|
+
const cbG = -fix2(0.34414);
|
|
11370
11370
|
for (let i = 0; i < width * height; i++) {
|
|
11371
11371
|
const y = full[0][i];
|
|
11372
11372
|
const cb = full[1][i] - 128;
|
|
@@ -12333,7 +12333,7 @@ function flattenBezierPath(pts) {
|
|
|
12333
12333
|
}
|
|
12334
12334
|
return out;
|
|
12335
12335
|
}
|
|
12336
|
-
function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = false) {
|
|
12336
|
+
function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = false, floorH = false) {
|
|
12337
12337
|
const w = r - l;
|
|
12338
12338
|
const h = b - t;
|
|
12339
12339
|
let ew = Math.min(Math.abs(cw), w);
|
|
@@ -12346,7 +12346,7 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = fa
|
|
|
12346
12346
|
const topX = compatible ? Math.round(r - ew / 2) : Math.floor(r - ew / 2);
|
|
12347
12347
|
const hx = r - topX;
|
|
12348
12348
|
const verticalControl = clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
|
|
12349
|
-
const horizontalControl = Math.ceil(KAPPA * hx);
|
|
12349
|
+
const horizontalControl = floorH ? Math.floor(KAPPA * hx) : Math.ceil(KAPPA * hx);
|
|
12350
12350
|
const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
|
|
12351
12351
|
const mx = (x) => l + r - x;
|
|
12352
12352
|
const my = (y) => t + b - y;
|
|
@@ -12473,8 +12473,8 @@ var POLYGON_NODES = (() => {
|
|
|
12473
12473
|
const cos = [];
|
|
12474
12474
|
const sin = [];
|
|
12475
12475
|
for (let k = 0; k <= 129; k++) {
|
|
12476
|
-
cos.push(Math.cos(k * TRIG_STEP));
|
|
12477
|
-
sin.push(Math.sin(k * TRIG_STEP));
|
|
12476
|
+
cos.push(Math.fround(Math.cos(k * TRIG_STEP)));
|
|
12477
|
+
sin.push(Math.fround(Math.sin(k * TRIG_STEP)));
|
|
12478
12478
|
}
|
|
12479
12479
|
for (let k = 0; k <= 128; k += 32) {
|
|
12480
12480
|
cos[k] = [1, 0, -1, 0, 1][k / 32];
|
|
@@ -12487,7 +12487,7 @@ function polygonTrig(angle) {
|
|
|
12487
12487
|
if (b < 0) {
|
|
12488
12488
|
b += 2 * Math.PI;
|
|
12489
12489
|
}
|
|
12490
|
-
const x = b / TRIG_STEP;
|
|
12490
|
+
const x = Math.fround(b / TRIG_STEP);
|
|
12491
12491
|
const i = Math.min(127, Math.floor(x));
|
|
12492
12492
|
const f = x - i;
|
|
12493
12493
|
return [
|
|
@@ -12507,16 +12507,38 @@ function approximateArcAngle(x, y) {
|
|
|
12507
12507
|
if (ax === 0 && ay === 0) {
|
|
12508
12508
|
return 0;
|
|
12509
12509
|
}
|
|
12510
|
-
const a = ay <= ax ? interpolatedAtan(ay / ax) : Math.PI / 2 - interpolatedAtan(ax / ay);
|
|
12510
|
+
const a = ay <= ax ? interpolatedAtan(Math.fround(ay / ax)) : Math.PI / 2 - interpolatedAtan(Math.fround(ax / ay));
|
|
12511
12511
|
if (x >= 0) {
|
|
12512
12512
|
return y >= 0 ? a : 2 * Math.PI - a;
|
|
12513
12513
|
}
|
|
12514
12514
|
return y >= 0 ? Math.PI - a : Math.PI + a;
|
|
12515
12515
|
}
|
|
12516
|
-
function unitPiece(from, to, small) {
|
|
12516
|
+
function unitPiece(from, to, small, radius = Infinity) {
|
|
12517
12517
|
const trig = small ? (a) => [Math.cos(a), Math.sin(a)] : polygonTrig;
|
|
12518
12518
|
const p0 = trig(from);
|
|
12519
12519
|
const p3 = trig(to);
|
|
12520
|
+
if (small && 6e-8 * radius / Math.abs(Math.sin(to - from)) > 0.5) {
|
|
12521
|
+
const f = Math.fround;
|
|
12522
|
+
const q0 = [f(p0[0]), f(p0[1])];
|
|
12523
|
+
const q3 = [f(p3[0]), f(p3[1])];
|
|
12524
|
+
const det32 = f(f(q0[0] * q3[1]) - f(q0[1] * q3[0]));
|
|
12525
|
+
if (det32 !== 0) {
|
|
12526
|
+
const X = [f(f(q3[1] - q0[1]) / det32), f(f(q0[0] - q3[0]) / det32)];
|
|
12527
|
+
const c = f(polygonTrig(Math.abs(to - from) / 2)[0]);
|
|
12528
|
+
const kappa = f(f(f(4 / 3) * c) / f(1 + c));
|
|
12529
|
+
return {
|
|
12530
|
+
start: p0,
|
|
12531
|
+
ctrl: [
|
|
12532
|
+
f(q0[0] + f(kappa * f(X[0] - q0[0]))),
|
|
12533
|
+
f(q0[1] + f(kappa * f(X[1] - q0[1]))),
|
|
12534
|
+
f(q3[0] + f(kappa * f(X[0] - q3[0]))),
|
|
12535
|
+
f(q3[1] + f(kappa * f(X[1] - q3[1]))),
|
|
12536
|
+
p3[0],
|
|
12537
|
+
p3[1]
|
|
12538
|
+
]
|
|
12539
|
+
};
|
|
12540
|
+
}
|
|
12541
|
+
}
|
|
12520
12542
|
const det = p0[0] * p3[1] - p0[1] * p3[0];
|
|
12521
12543
|
let ctrl;
|
|
12522
12544
|
if (Math.abs(det) < 1e-12) {
|
|
@@ -12536,7 +12558,7 @@ function unitPiece(from, to, small) {
|
|
|
12536
12558
|
}
|
|
12537
12559
|
return { start: p0, ctrl };
|
|
12538
12560
|
}
|
|
12539
|
-
function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise, halfX = false, framed = false) {
|
|
12561
|
+
function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise, halfX = false, framed = false, mirrorX = false) {
|
|
12540
12562
|
const w = r - l;
|
|
12541
12563
|
const h = b - t;
|
|
12542
12564
|
const Q = Math.PI / 2;
|
|
@@ -12549,16 +12571,21 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise, halfX = false, framed
|
|
|
12549
12571
|
const angle = (x, y) => approximateArcAngle((x - tcx) / (w / 2 || 1), -(y - tcy) / (h / 2 || 1));
|
|
12550
12572
|
const a0 = angle(xs, ys);
|
|
12551
12573
|
let a1 = angle(xe, ye);
|
|
12552
|
-
const
|
|
12574
|
+
const mirrored = (a2) => clockwise ? (2 * Math.PI - a2) % (2 * Math.PI) : a2;
|
|
12575
|
+
const small = a1 !== a0 && Math.abs(mirrored(a1) - mirrored(a0)) <= SMALL_SWEEP;
|
|
12553
12576
|
const s = clockwise ? -1 : 1;
|
|
12554
12577
|
if (s > 0) {
|
|
12555
12578
|
while (a1 <= a0) a1 += 2 * Math.PI;
|
|
12556
12579
|
} else {
|
|
12557
12580
|
while (a1 >= a0) a1 -= 2 * Math.PI;
|
|
12558
12581
|
}
|
|
12559
|
-
const
|
|
12560
|
-
const
|
|
12561
|
-
|
|
12582
|
+
const axis = (r2, c) => Math.fround(r2 * Math.fround(c));
|
|
12583
|
+
const px = (u, v) => mirrorX ? (
|
|
12584
|
+
// The mirrored circle sits on the same centre but its horizontal radius rounds down (native playback, 144 arcs under a mirrored x).
|
|
12585
|
+
Math.round(cx - axis(Math.floor(w / 2), u))
|
|
12586
|
+
) : clockwise && halfX ? Math.ceil(cx + axis(rx, u) + 0.5 - v) : Math.round(cx + axis(rx, u) + (halfX ? 1 + v : 0));
|
|
12587
|
+
const py = (v) => Math.round(cy - axis(ry, v));
|
|
12588
|
+
const eb = mirrorX ? axisBox(r, t, l, b) : axisBox(l, t, r, b);
|
|
12562
12589
|
if (halfX) eb.halfX = true;
|
|
12563
12590
|
const E = ellipseBeziersBox(eb);
|
|
12564
12591
|
if (clockwise) {
|
|
@@ -12594,7 +12621,7 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise, halfX = false, framed
|
|
|
12594
12621
|
continue;
|
|
12595
12622
|
}
|
|
12596
12623
|
const e = s > 0 ? Math.min(next, a1) : Math.max(next, a1);
|
|
12597
|
-
const piece = unitPiece(a, e, small);
|
|
12624
|
+
const piece = unitPiece(a, e, small, Math.max(rx, ry));
|
|
12598
12625
|
for (let i = 0; i < 6; i += 2) {
|
|
12599
12626
|
out.push(px(piece.ctrl[i], piece.ctrl[i + 1]), py(piece.ctrl[i + 1]));
|
|
12600
12627
|
}
|
|
@@ -16262,6 +16289,21 @@ function decodeBmpFile(bytes) {
|
|
|
16262
16289
|
return image ? { kind: "rgba", data: image.data, width: image.width, height: image.height } : null;
|
|
16263
16290
|
}
|
|
16264
16291
|
|
|
16292
|
+
// src/float32-down.ts
|
|
16293
|
+
var float32 = new Float32Array(1);
|
|
16294
|
+
var float32Bits = new Uint32Array(float32.buffer);
|
|
16295
|
+
function down32(x) {
|
|
16296
|
+
const r = Math.fround(x);
|
|
16297
|
+
if (r <= x || Number.isNaN(r)) return r;
|
|
16298
|
+
if (r === 0) {
|
|
16299
|
+
float32Bits[0] = 2147483649;
|
|
16300
|
+
return float32[0];
|
|
16301
|
+
}
|
|
16302
|
+
float32[0] = r;
|
|
16303
|
+
float32Bits[0] += r > 0 ? -1 : 1;
|
|
16304
|
+
return float32[0];
|
|
16305
|
+
}
|
|
16306
|
+
|
|
16265
16307
|
// src/emf-plus-linear-ramp.ts
|
|
16266
16308
|
var GAMMA = 2.2;
|
|
16267
16309
|
function linearRampIntervals(pointCount, rect) {
|
|
@@ -16537,30 +16579,76 @@ function pathGradientQuantum(boundary, matrix = IDENTITY) {
|
|
|
16537
16579
|
let x1 = -Infinity;
|
|
16538
16580
|
let y1 = -Infinity;
|
|
16539
16581
|
for (const p of boundary) {
|
|
16540
|
-
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
x1 = Math.max(x1, x);
|
|
16545
|
-
y1 = Math.max(y1, y);
|
|
16582
|
+
x0 = Math.min(x0, p.x);
|
|
16583
|
+
y0 = Math.min(y0, p.y);
|
|
16584
|
+
x1 = Math.max(x1, p.x);
|
|
16585
|
+
y1 = Math.max(y1, p.y);
|
|
16546
16586
|
}
|
|
16547
|
-
const
|
|
16587
|
+
const w = x1 - x0;
|
|
16588
|
+
const h = y1 - y0;
|
|
16589
|
+
const first = Math.hypot(matrix[0] * w + matrix[2] * h, matrix[1] * w + matrix[3] * h);
|
|
16590
|
+
const second = Math.hypot(matrix[0] * w - matrix[2] * h, matrix[1] * w - matrix[3] * h);
|
|
16591
|
+
const steps = Math.ceil(first + second);
|
|
16548
16592
|
return Number.isFinite(steps) && steps > 0 ? steps : 0;
|
|
16549
16593
|
}
|
|
16594
|
+
var TIE_LEVEL = 1e-9;
|
|
16550
16595
|
var TIE_EPSILON = 1e-7;
|
|
16596
|
+
function pathGradientRatio(shape, x, y, focusPoint) {
|
|
16597
|
+
const report = { s: NaN };
|
|
16598
|
+
return pathGradientColorAt(shape, x, y, focusPoint, 0, report) === null ? null : report.s;
|
|
16599
|
+
}
|
|
16551
16600
|
function quantisedPathArgb(surround, centre, t, quantum) {
|
|
16552
16601
|
const scaled2 = t * quantum;
|
|
16553
16602
|
const tie = Math.abs(scaled2 - Math.floor(scaled2) - 0.5) < TIE_EPSILON;
|
|
16554
|
-
|
|
16555
|
-
|
|
16603
|
+
return quantisedStepArgb(surround, centre, tie ? scaled2 : Math.floor(scaled2 + 0.5), quantum, t < 0.5);
|
|
16604
|
+
}
|
|
16605
|
+
function roundTowards(v, target) {
|
|
16606
|
+
const floor = Math.floor(v);
|
|
16607
|
+
const fraction = v - floor;
|
|
16608
|
+
if (Math.abs(fraction - 0.5) < TIE_LEVEL) return target > v ? floor + 1 : floor;
|
|
16609
|
+
return fraction > 0.5 ? floor + 1 : floor;
|
|
16610
|
+
}
|
|
16611
|
+
var centreWeightTables = /* @__PURE__ */ new Map();
|
|
16612
|
+
function centreWeight(quantum, j) {
|
|
16613
|
+
let table2 = centreWeightTables.get(quantum);
|
|
16614
|
+
if (!table2) {
|
|
16615
|
+
table2 = new Float64Array(quantum + 1);
|
|
16616
|
+
const step = down32(1 / quantum);
|
|
16617
|
+
let w = 0;
|
|
16618
|
+
for (let i = 1; i <= quantum; i++) {
|
|
16619
|
+
w = down32(w + step);
|
|
16620
|
+
table2[i] = w;
|
|
16621
|
+
}
|
|
16622
|
+
if (centreWeightTables.size > 64) centreWeightTables.clear();
|
|
16623
|
+
centreWeightTables.set(quantum, table2);
|
|
16624
|
+
}
|
|
16625
|
+
return table2[j];
|
|
16626
|
+
}
|
|
16627
|
+
function centreWeightArgb(surround, centre, k, quantum) {
|
|
16628
|
+
const w = centreWeight(quantum, quantum - k);
|
|
16629
|
+
const aS = surround >>> 24 & 255;
|
|
16630
|
+
const aC = centre >>> 24 & 255;
|
|
16631
|
+
const level2 = (s, c) => roundTowards(c + (s - c) * w, c);
|
|
16632
|
+
const alpha = level2(aS, aC);
|
|
16633
|
+
if (alpha <= 0) return 0;
|
|
16634
|
+
const ch = (shift) => {
|
|
16635
|
+
const p = level2((surround >>> shift & 255) * aS / 255, (centre >>> shift & 255) * aC / 255);
|
|
16636
|
+
return Math.min(255, Math.max(0, Math.round(p * 255 / alpha)));
|
|
16637
|
+
};
|
|
16638
|
+
return (alpha << 24 | ch(16) << 16 | ch(8) << 8 | ch(0)) >>> 0;
|
|
16639
|
+
}
|
|
16640
|
+
function quantisedStepArgb(surround, centre, k, quantum, fromBoundary) {
|
|
16641
|
+
if (Number.isInteger(k)) return centreWeightArgb(surround, centre, k, quantum);
|
|
16556
16642
|
const w = (fromBoundary ? k : quantum - k) / quantum;
|
|
16557
16643
|
const aS = surround >>> 24 & 255;
|
|
16558
16644
|
const aC = centre >>> 24 & 255;
|
|
16559
16645
|
const mix2 = (s, c) => fromBoundary ? s + (c - s) * w : c + (s - c) * w;
|
|
16560
|
-
const
|
|
16646
|
+
const whole = Number.isInteger(k);
|
|
16647
|
+
const level2 = (s, c) => whole ? roundTowards(mix2(s, c), c) : Math.floor(mix2(s, c) + 0.5);
|
|
16648
|
+
const alpha = level2(aS, aC);
|
|
16561
16649
|
if (alpha <= 0) return 0;
|
|
16562
16650
|
const ch = (shift) => {
|
|
16563
|
-
const p =
|
|
16651
|
+
const p = level2((surround >>> shift & 255) * aS / 255, (centre >>> shift & 255) * aC / 255);
|
|
16564
16652
|
return Math.min(255, Math.max(0, Math.round(p * 255 / alpha)));
|
|
16565
16653
|
};
|
|
16566
16654
|
return (alpha << 24 | ch(16) << 16 | ch(8) << 8 | ch(0)) >>> 0;
|
|
@@ -16570,6 +16658,24 @@ function quantisedPosition(pos, quantum) {
|
|
|
16570
16658
|
const tie = Math.abs(scaled2 - Math.floor(scaled2) - 0.5) < TIE_EPSILON;
|
|
16571
16659
|
return (tie ? scaled2 : Math.floor(scaled2 + 0.5)) / quantum;
|
|
16572
16660
|
}
|
|
16661
|
+
function pathGradientStepColor(shape, k, quantum) {
|
|
16662
|
+
const pos = k / quantum;
|
|
16663
|
+
if (shape.preset && shape.preset.positions.length > 0) {
|
|
16664
|
+
const { positions, argb } = shape.preset;
|
|
16665
|
+
if (pos <= positions[0]) return argb[0];
|
|
16666
|
+
for (let i = 1; i < positions.length; i++) {
|
|
16667
|
+
if (pos <= positions[i]) {
|
|
16668
|
+
const span = positions[i] - positions[i - 1];
|
|
16669
|
+
return lerpArgb(argb[i - 1], argb[i], span > 0 ? (pos - positions[i - 1]) / span : 1);
|
|
16670
|
+
}
|
|
16671
|
+
}
|
|
16672
|
+
return argb[positions.length - 1];
|
|
16673
|
+
}
|
|
16674
|
+
const surround = shape.boundaryArgb[0] ?? shape.centerArgb;
|
|
16675
|
+
if (!shape.blend) return quantisedStepArgb(surround, shape.centerArgb, k, quantum, k * 2 < quantum);
|
|
16676
|
+
const t = Math.min(1, Math.max(0, piecewise2(shape.blend.positions, shape.blend.factors, pos)));
|
|
16677
|
+
return surround >>> 24 !== shape.centerArgb >>> 24 ? lerpUniformPathArgb(surround, shape.centerArgb, t) : lerpArgb(surround, shape.centerArgb, t);
|
|
16678
|
+
}
|
|
16573
16679
|
function piecewise2(xs, ys, x) {
|
|
16574
16680
|
const n = Math.min(xs.length, ys.length);
|
|
16575
16681
|
if (n === 0) {
|
|
@@ -16604,7 +16710,7 @@ function stopColorAt(stops, t) {
|
|
|
16604
16710
|
}
|
|
16605
16711
|
return stops[stops.length - 1].argb;
|
|
16606
16712
|
}
|
|
16607
|
-
function pathGradientColorAt(shape, x, y, focusPoint, quantum) {
|
|
16713
|
+
function pathGradientColorAt(shape, x, y, focusPoint, quantum, report) {
|
|
16608
16714
|
const { center, boundary, boundaryArgb } = shape;
|
|
16609
16715
|
const n = boundary.length;
|
|
16610
16716
|
const px = x - center.x;
|
|
@@ -16710,6 +16816,7 @@ function pathGradientColorAt(shape, x, y, focusPoint, quantum) {
|
|
|
16710
16816
|
}
|
|
16711
16817
|
}
|
|
16712
16818
|
if (found < 0 || !Number.isFinite(s)) return null;
|
|
16819
|
+
if (report) report.s = s;
|
|
16713
16820
|
const exactPos = 1 - s;
|
|
16714
16821
|
const pos = quantum && quantum > 0 ? quantisedPosition(exactPos, quantum) : exactPos;
|
|
16715
16822
|
if (shape.preset && shape.preset.positions.length > 0) {
|
|
@@ -17306,19 +17413,31 @@ function applyTint(src, hue, amount) {
|
|
|
17306
17413
|
var TINT_FULL = 254;
|
|
17307
17414
|
function applyRedEyeCorrection(src, width, height, areas) {
|
|
17308
17415
|
const out = new Uint8ClampedArray(src);
|
|
17309
|
-
const carry = { x: 0, y: 0 };
|
|
17416
|
+
const carry = { x: 0, y: 0, set: false };
|
|
17310
17417
|
for (const a of areas) {
|
|
17311
17418
|
correctRedEyeArea(out, width, clamp(a.left, 0, width), clamp(a.top, 0, height), clamp(a.right, 0, width), clamp(a.bottom, 0, height), carry);
|
|
17312
17419
|
}
|
|
17313
17420
|
return out;
|
|
17314
17421
|
}
|
|
17315
17422
|
var RED_EYE_SECTORS = 60;
|
|
17316
|
-
var
|
|
17317
|
-
|
|
17318
|
-
|
|
17423
|
+
var RED_EYE_LEGACY = {
|
|
17424
|
+
blueWeight: 0.225,
|
|
17425
|
+
pureWeight: 1 / 1.225,
|
|
17426
|
+
carry: 0.81
|
|
17427
|
+
};
|
|
17428
|
+
var RED_EYE_CENTRE_SECTOR = 15;
|
|
17429
|
+
var RED_EYE_BLUE_WEIGHT = 2 / 9;
|
|
17430
|
+
var RED_EYE_PURE_WEIGHT = 1;
|
|
17431
|
+
var RED_EYE_CARRY = 1;
|
|
17432
|
+
function redEyeLuma(g, b) {
|
|
17433
|
+
return Math.floor((9 * g + 2 * b + 5) / 11);
|
|
17434
|
+
}
|
|
17319
17435
|
var RED_EYE_GREEN_SHARE = 5 / 16;
|
|
17320
|
-
var RED_EYE_SPREAD_STEPS = [
|
|
17436
|
+
var RED_EYE_SPREAD_STEPS = [25, 40, 80];
|
|
17321
17437
|
var RED_EYE_STRENGTHS = [0.25, 0.5, 0.661, 0.75];
|
|
17438
|
+
var RED_EYE_HIGHLIGHT_RISE = 40;
|
|
17439
|
+
var RED_EYE_FALLBACK_SLOPE = 0.33;
|
|
17440
|
+
var RED_EYE_HIGHLIGHT_REST = 5;
|
|
17322
17441
|
function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
|
|
17323
17442
|
const w = x1 - x0;
|
|
17324
17443
|
const h = y1 - y0;
|
|
@@ -17328,9 +17447,19 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
|
|
|
17328
17447
|
}
|
|
17329
17448
|
const redness = new Float64Array(count);
|
|
17330
17449
|
const dark = new Float64Array(count);
|
|
17450
|
+
const lumas = new Int32Array(count);
|
|
17331
17451
|
let sx = 0;
|
|
17332
17452
|
let sy = 0;
|
|
17333
17453
|
let sw = 0;
|
|
17454
|
+
let sxL = 0;
|
|
17455
|
+
let syL = 0;
|
|
17456
|
+
let swL = 0;
|
|
17457
|
+
let redCount = 0;
|
|
17458
|
+
let sx32 = 0;
|
|
17459
|
+
let sy32 = 0;
|
|
17460
|
+
let sw32 = 0;
|
|
17461
|
+
let firstRed = -1;
|
|
17462
|
+
let uniformRed = true;
|
|
17334
17463
|
for (let y = 0; y < h; y++) {
|
|
17335
17464
|
for (let x = 0; x < w; x++) {
|
|
17336
17465
|
const i = ((y0 + y) * stride + x0 + x) * 4;
|
|
@@ -17340,24 +17469,53 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
|
|
|
17340
17469
|
const k = y * w + x;
|
|
17341
17470
|
const d = g + RED_EYE_BLUE_WEIGHT * b;
|
|
17342
17471
|
dark[k] = d;
|
|
17472
|
+
const dL = g + RED_EYE_LEGACY.blueWeight * b;
|
|
17473
|
+
const luma = redEyeLuma(g, b);
|
|
17474
|
+
lumas[k] = luma;
|
|
17343
17475
|
const v = r - Math.max(g, b);
|
|
17344
17476
|
if (v > 0) {
|
|
17345
17477
|
redness[k] = v;
|
|
17346
|
-
const weight =
|
|
17478
|
+
const weight = luma >= 1 ? v / luma : RED_EYE_PURE_WEIGHT;
|
|
17347
17479
|
sx += weight * (x + 0.5);
|
|
17348
17480
|
sy += weight * (y + 0.5);
|
|
17349
17481
|
sw += weight;
|
|
17482
|
+
redCount++;
|
|
17483
|
+
const weight32 = Math.fround(weight);
|
|
17484
|
+
sx32 = Math.fround(sx32 + Math.fround(weight32 * Math.fround(x + 0.5)));
|
|
17485
|
+
sy32 = Math.fround(sy32 + Math.fround(weight32 * Math.fround(y + 0.5)));
|
|
17486
|
+
sw32 = Math.fround(sw32 + weight32);
|
|
17487
|
+
const triple = r << 16 | g << 8 | b;
|
|
17488
|
+
if (firstRed < 0) {
|
|
17489
|
+
firstRed = triple;
|
|
17490
|
+
} else if (triple !== firstRed) {
|
|
17491
|
+
uniformRed = false;
|
|
17492
|
+
}
|
|
17493
|
+
const weightL = dL >= 1 ? v / dL : RED_EYE_LEGACY.pureWeight;
|
|
17494
|
+
sxL += weightL * (x + 0.5);
|
|
17495
|
+
syL += weightL * (y + 0.5);
|
|
17496
|
+
swL += weightL;
|
|
17350
17497
|
}
|
|
17351
17498
|
}
|
|
17352
17499
|
}
|
|
17353
17500
|
if (sw === 0) {
|
|
17354
17501
|
return;
|
|
17355
17502
|
}
|
|
17356
|
-
|
|
17357
|
-
|
|
17503
|
+
const snap2 = (v) => Math.round(v * 1e9) / 1e9;
|
|
17504
|
+
const lumaCx = snap2((sx + (carry.set ? carry.x - 0.5 : 0) * RED_EYE_CARRY) / sw);
|
|
17505
|
+
const lumaCy = snap2((sy + (carry.set ? carry.y - 0.5 : 0) * RED_EYE_CARRY) / sw);
|
|
17506
|
+
const onPixelCentre = (v) => Number.isInteger(snap2(v - 0.5));
|
|
17507
|
+
const symmetric = redCount > 1 && (onPixelCentre(lumaCx) || onPixelCentre(lumaCy));
|
|
17508
|
+
const exactCentre = (c, sum32) => !onPixelCentre(c) || Math.fround(sum32 / sw32) === c;
|
|
17509
|
+
const exactSymmetric = symmetric && !uniformRed && !carry.set && exactCentre(lumaCx, sx32) && exactCentre(lumaCy, sy32);
|
|
17510
|
+
const legacyWeights = symmetric && !exactSymmetric;
|
|
17511
|
+
let cx = legacyWeights ? (sxL + RED_EYE_LEGACY.carry * (carry.set ? carry.x : 0)) / swL : lumaCx;
|
|
17512
|
+
let cy = legacyWeights ? (syL + RED_EYE_LEGACY.carry * (carry.set ? carry.y : 0)) / swL : lumaCy;
|
|
17358
17513
|
carry.x = x0 + cx;
|
|
17359
17514
|
carry.y = y0 + cy;
|
|
17360
|
-
|
|
17515
|
+
carry.set = true;
|
|
17516
|
+
let fellBack = false;
|
|
17517
|
+
if (Math.hypot(cx - w / 2, cy - h / 2) >= (w + h) / 6) {
|
|
17518
|
+
fellBack = true;
|
|
17361
17519
|
cx = w / 2;
|
|
17362
17520
|
cy = h / 2;
|
|
17363
17521
|
}
|
|
@@ -17369,10 +17527,17 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
|
|
|
17369
17527
|
if (!(radius > 0)) {
|
|
17370
17528
|
return;
|
|
17371
17529
|
}
|
|
17372
|
-
const sorted =
|
|
17373
|
-
const
|
|
17530
|
+
const sorted = Int32Array.from(lumas).sort();
|
|
17531
|
+
const p70 = sorted[Math.floor(0.7 * count)];
|
|
17532
|
+
const spread = p70 - sorted[Math.floor(0.3 * count)];
|
|
17533
|
+
const brightest = sorted[count - 1];
|
|
17534
|
+
const second = count > 1 ? sorted[count - 2] : -1;
|
|
17535
|
+
let highlight = -1;
|
|
17536
|
+
if (brightest > second && brightest - p70 >= RED_EYE_HIGHLIGHT_RISE) {
|
|
17537
|
+
highlight = lumas.indexOf(brightest);
|
|
17538
|
+
}
|
|
17374
17539
|
let level2 = 0;
|
|
17375
|
-
while (level2 < RED_EYE_SPREAD_STEPS.length && spread
|
|
17540
|
+
while (level2 < RED_EYE_SPREAD_STEPS.length && spread > RED_EYE_SPREAD_STEPS[level2]) {
|
|
17376
17541
|
level2++;
|
|
17377
17542
|
}
|
|
17378
17543
|
const strength = RED_EYE_STRENGTHS[level2];
|
|
@@ -17393,7 +17558,7 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
|
|
|
17393
17558
|
if (angle < 0) {
|
|
17394
17559
|
angle += 360;
|
|
17395
17560
|
}
|
|
17396
|
-
const s = Math.min(RED_EYE_SECTORS - 1, Math.floor(angle / 6));
|
|
17561
|
+
const s = dx === 0 && dy === 0 ? RED_EYE_CENTRE_SECTOR : dy === 0 ? 0 : Math.min(RED_EYE_SECTORS - 1, Math.floor(angle / 6));
|
|
17397
17562
|
sector[k] = s;
|
|
17398
17563
|
if (d < radius) {
|
|
17399
17564
|
sectorSum[s] += redness[k];
|
|
@@ -17415,8 +17580,13 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
|
|
|
17415
17580
|
const ratio = meanDark > 0 ? dark[k] / meanDark : 1;
|
|
17416
17581
|
const u = distance[k] / radius;
|
|
17417
17582
|
const darknessFalloff = ratio < 2 ? 0.5 * (1 - ratio) ** 2 : 0;
|
|
17418
|
-
const falloff = Math.max(strength * (1 - u) * (1 - u), darknessFalloff);
|
|
17419
|
-
|
|
17583
|
+
const falloff = Math.max(strength * (1 - u) * (1 - u), darknessFalloff, fellBack ? RED_EYE_FALLBACK_SLOPE * (1 - u) : 0);
|
|
17584
|
+
let rest = (1 - falloff) * mean;
|
|
17585
|
+
if (highlight >= 0) {
|
|
17586
|
+
const hdx = x - highlight % w;
|
|
17587
|
+
const hdy = y - Math.floor(highlight / w);
|
|
17588
|
+
rest = Math.min(rest, RED_EYE_HIGHLIGHT_REST * (hdx * hdx + hdy * hdy));
|
|
17589
|
+
}
|
|
17420
17590
|
if (rest >= v) {
|
|
17421
17591
|
continue;
|
|
17422
17592
|
}
|
|
@@ -19636,13 +19806,13 @@ function recordDeviceFigures(buildPath, device) {
|
|
|
19636
19806
|
const f = fig;
|
|
19637
19807
|
f.curved = true;
|
|
19638
19808
|
const n = f.pts.length;
|
|
19639
|
-
const
|
|
19640
|
-
const p0x =
|
|
19641
|
-
const p0y =
|
|
19809
|
+
const fix2 = (v) => toPlusFix(v);
|
|
19810
|
+
const p0x = fix2(f.pts[n - 2]);
|
|
19811
|
+
const p0y = fix2(f.pts[n - 1]);
|
|
19642
19812
|
f.pts[n - 2] = p0x / 16;
|
|
19643
19813
|
f.pts[n - 1] = p0y / 16;
|
|
19644
19814
|
const out = [];
|
|
19645
|
-
const ctrl = [p0x, p0y,
|
|
19815
|
+
const ctrl = [p0x, p0y, fix2(dx(c1x, c1y)), fix2(dy(c1x, c1y)), fix2(dx(c2x, c2y)), fix2(dy(c2x, c2y)), fix2(dx(x, y)), fix2(dy(x, y))];
|
|
19646
19816
|
flattenBezierGdiplus(ctrl, out);
|
|
19647
19817
|
for (const v of out) {
|
|
19648
19818
|
f.pts.push(v / 16);
|
|
@@ -19916,7 +20086,7 @@ function frame(a, b) {
|
|
|
19916
20086
|
const uy = (b.y - a.y) / len;
|
|
19917
20087
|
return { ux, uy, nx: -uy, ny: ux };
|
|
19918
20088
|
}
|
|
19919
|
-
function joinPoints(p, f1, f2, o, pen) {
|
|
20089
|
+
function joinPoints(p, f1, f2, o, pen, meetInside = false) {
|
|
19920
20090
|
const a = { x: p.x + f1.nx * o, y: p.y + f1.ny * o };
|
|
19921
20091
|
const b = { x: p.x + f2.nx * o, y: p.y + f2.ny * o };
|
|
19922
20092
|
if (o === 0) {
|
|
@@ -19928,6 +20098,11 @@ function joinPoints(p, f1, f2, o, pen) {
|
|
|
19928
20098
|
}
|
|
19929
20099
|
const outer = cross * o < 0;
|
|
19930
20100
|
if (!outer) {
|
|
20101
|
+
if (meetInside) {
|
|
20102
|
+
const den2 = f1.ux * f2.uy - f1.uy * f2.ux;
|
|
20103
|
+
const t2 = ((b.x - a.x) * f2.uy - (b.y - a.y) * f2.ux) / den2;
|
|
20104
|
+
return [{ x: a.x + f1.ux * t2, y: a.y + f1.uy * t2 }];
|
|
20105
|
+
}
|
|
19931
20106
|
return [a, b];
|
|
19932
20107
|
}
|
|
19933
20108
|
if (pen.join === 2) {
|
|
@@ -19995,7 +20170,7 @@ function sidePoints(pts, closed, o, pen) {
|
|
|
19995
20170
|
const inIdx = i - 1 >= 0 ? i - 1 : closed ? segs2 - 1 : -1;
|
|
19996
20171
|
const outIdx = i < segs2 ? i : -1;
|
|
19997
20172
|
if (inIdx >= 0 && outIdx >= 0) {
|
|
19998
|
-
out.push(...joinPoints(pts[i], frames[inIdx], frames[outIdx], o, pen));
|
|
20173
|
+
out.push(...joinPoints(pts[i], frames[inIdx], frames[outIdx], o, pen, closed && !!pen.compound));
|
|
19999
20174
|
} else {
|
|
20000
20175
|
const f = frames[outIdx >= 0 ? outIdx : inIdx];
|
|
20001
20176
|
out.push({ x: pts[i].x + f.nx * o, y: pts[i].y + f.ny * o });
|
|
@@ -20102,6 +20277,50 @@ function signedArea(pts) {
|
|
|
20102
20277
|
}
|
|
20103
20278
|
return a / 2;
|
|
20104
20279
|
}
|
|
20280
|
+
function insidePolygon(pts, q) {
|
|
20281
|
+
let inside = false;
|
|
20282
|
+
for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) {
|
|
20283
|
+
const a = pts[i];
|
|
20284
|
+
const b = pts[j];
|
|
20285
|
+
if (a.y > q.y !== b.y > q.y && q.x < (b.x - a.x) * (q.y - a.y) / (b.y - a.y) + a.x) {
|
|
20286
|
+
inside = !inside;
|
|
20287
|
+
}
|
|
20288
|
+
}
|
|
20289
|
+
return inside;
|
|
20290
|
+
}
|
|
20291
|
+
function insetCollapses(pts, d) {
|
|
20292
|
+
const sign = signedArea(pts) > 0 ? 1 : -1;
|
|
20293
|
+
const n = pts.length;
|
|
20294
|
+
const frames = Array.from({ length: n }, (_, i) => frame(pts[i], pts[(i + 1) % n]));
|
|
20295
|
+
const moved = pts.map((v, i) => {
|
|
20296
|
+
const f1 = frames[(i + n - 1) % n];
|
|
20297
|
+
const f2 = frames[i];
|
|
20298
|
+
const n1x = f1.nx * sign, n1y = f1.ny * sign, n2x = f2.nx * sign, n2y = f2.ny * sign;
|
|
20299
|
+
const k = 1 + n1x * n2x + n1y * n2y;
|
|
20300
|
+
return k < 1e-9 ? { x: v.x + n1x * d, y: v.y + n1y * d } : { x: v.x + (n1x + n2x) * d / k, y: v.y + (n1y + n2y) * d / k };
|
|
20301
|
+
});
|
|
20302
|
+
return Math.sign(signedArea(moved)) !== sign || moved.some((q) => !insidePolygon(pts, q));
|
|
20303
|
+
}
|
|
20304
|
+
function innerBoundary(pts, d, pen) {
|
|
20305
|
+
const sign = signedArea(pts) > 0 ? 1 : -1;
|
|
20306
|
+
const n = pts.length;
|
|
20307
|
+
const frames = Array.from({ length: n }, (_, i) => frame(pts[i], pts[(i + 1) % n]));
|
|
20308
|
+
const out = [];
|
|
20309
|
+
for (let i = 0; i < n; i++) {
|
|
20310
|
+
const f1 = frames[(i + n - 1) % n];
|
|
20311
|
+
const f2 = frames[i];
|
|
20312
|
+
const o = sign * d;
|
|
20313
|
+
const cross = f1.ux * f2.uy - f1.uy * f2.ux;
|
|
20314
|
+
if (cross * o < 0) {
|
|
20315
|
+
out.push(...joinPoints(pts[i], f1, f2, o, pen));
|
|
20316
|
+
} else {
|
|
20317
|
+
const n1x = f1.nx * sign, n1y = f1.ny * sign, n2x = f2.nx * sign, n2y = f2.ny * sign;
|
|
20318
|
+
const k = 1 + n1x * n2x + n1y * n2y;
|
|
20319
|
+
out.push(k < 1e-9 ? { x: pts[i].x + n1x * d, y: pts[i].y + n1y * d } : { x: pts[i].x + (n1x + n2x) * d / k, y: pts[i].y + (n1y + n2y) * d / k });
|
|
20320
|
+
}
|
|
20321
|
+
}
|
|
20322
|
+
return out;
|
|
20323
|
+
}
|
|
20105
20324
|
function widenFigures(figures, pen) {
|
|
20106
20325
|
const polys = [];
|
|
20107
20326
|
const h = pen.half;
|
|
@@ -20113,6 +20332,13 @@ function widenFigures(figures, pen) {
|
|
|
20113
20332
|
const closed = fig.closed && pts.length > 2;
|
|
20114
20333
|
let lo = -h;
|
|
20115
20334
|
let hi = h;
|
|
20335
|
+
if (pen.inset && closed && !pen.dash && !pen.compound) {
|
|
20336
|
+
polys.push(pts.slice());
|
|
20337
|
+
if (!insetCollapses(pts, 2 * h)) {
|
|
20338
|
+
polys.push(innerBoundary(pts, 2 * h, pen).reverse());
|
|
20339
|
+
}
|
|
20340
|
+
continue;
|
|
20341
|
+
}
|
|
20116
20342
|
if (pen.inset && closed) {
|
|
20117
20343
|
if (signedArea(pts) > 0) {
|
|
20118
20344
|
lo = 0;
|
|
@@ -21022,6 +21248,106 @@ async function preDecodeMetafileCaches(view, depth = 0) {
|
|
|
21022
21248
|
};
|
|
21023
21249
|
}
|
|
21024
21250
|
|
|
21251
|
+
// src/emf-plus-hq-cubic-weights.ts
|
|
21252
|
+
var HQ_CUBIC_HALF_TABLE = [
|
|
21253
|
+
[-1675, 5953, 56660, 6337, -1739],
|
|
21254
|
+
[-1612, 5575, 56650, 6727, -1804],
|
|
21255
|
+
[-1550, 5203, 56630, 7123, -1870],
|
|
21256
|
+
[-1489, 4837, 56600, 7525, -1937],
|
|
21257
|
+
[-1429, 4477, 56561, 7931, -2004],
|
|
21258
|
+
[-1371, 4125, 56510, 8345, -2073],
|
|
21259
|
+
[-1313, 3777, 56451, 8763, -2142],
|
|
21260
|
+
[-1257, 3437, 56381, 9187, -2212],
|
|
21261
|
+
[-1202, 3103, 56301, 9617, -2283],
|
|
21262
|
+
[-1148, 2775, 56211, 10053, -2355],
|
|
21263
|
+
[-1095, 2453, 56112, 10493, -2427],
|
|
21264
|
+
[-1044, 2139, 56002, 10939, -2500],
|
|
21265
|
+
[-993, 1829, 55884, 11389, -2573],
|
|
21266
|
+
[-945, 1529, 55754, 11845, -2647],
|
|
21267
|
+
[-897, 1233, 55616, 12305, -2721],
|
|
21268
|
+
[-851, 945, 55467, 12771, -2796],
|
|
21269
|
+
[-806, 663, 55309, 13241, -2871],
|
|
21270
|
+
[-762, 387, 55142, 13715, -2946],
|
|
21271
|
+
[-720, 119, 54964, 14195, -3022],
|
|
21272
|
+
[-679, -143, 54778, 14677, -3097],
|
|
21273
|
+
[-639, -399, 54582, 15165, -3173],
|
|
21274
|
+
[-600, -649, 54377, 15657, -3249],
|
|
21275
|
+
[-563, -891, 54162, 16153, -3325],
|
|
21276
|
+
[-528, -1125, 53937, 16653, -3401],
|
|
21277
|
+
[-493, -1355, 53705, 17155, -3476],
|
|
21278
|
+
[-460, -1577, 53462, 17663, -3552],
|
|
21279
|
+
[-429, -1791, 53210, 18173, -3627],
|
|
21280
|
+
[-398, -2001, 52950, 18687, -3702],
|
|
21281
|
+
[-369, -2203, 52681, 19203, -3776],
|
|
21282
|
+
[-341, -2399, 52403, 19723, -3850],
|
|
21283
|
+
[-315, -2587, 52116, 20245, -3923],
|
|
21284
|
+
[-289, -2771, 51821, 20771, -3996],
|
|
21285
|
+
[-265, -2947, 51517, 21299, -4068],
|
|
21286
|
+
[-243, -3115, 51204, 21829, -4139],
|
|
21287
|
+
[-221, -3279, 50884, 22361, -4209],
|
|
21288
|
+
[-201, -3435, 50554, 22897, -4279],
|
|
21289
|
+
[-182, -3585, 50217, 23433, -4347],
|
|
21290
|
+
[-164, -3729, 49872, 23971, -4414],
|
|
21291
|
+
[-147, -3867, 49518, 24513, -4481],
|
|
21292
|
+
[-131, -3999, 49158, 25053, -4545],
|
|
21293
|
+
[-117, -4123, 48788, 25597, -4609],
|
|
21294
|
+
[-103, -4243, 48412, 26141, -4671],
|
|
21295
|
+
[-90, -4357, 48029, 26685, -4731],
|
|
21296
|
+
[-79, -4463, 47637, 27231, -4790],
|
|
21297
|
+
[-68, -4565, 47239, 27777, -4847],
|
|
21298
|
+
[-59, -4659, 46833, 28323, -4902],
|
|
21299
|
+
[-50, -4749, 46421, 28869, -4955],
|
|
21300
|
+
[-42, -4833, 46002, 29415, -5006],
|
|
21301
|
+
[-35, -4911, 45576, 29961, -5055],
|
|
21302
|
+
[-29, -4983, 45143, 30507, -5102],
|
|
21303
|
+
[-24, -5049, 44704, 31051, -5146],
|
|
21304
|
+
[-19, -5111, 44259, 31595, -5188],
|
|
21305
|
+
[-15, -5167, 43807, 32139, -5228],
|
|
21306
|
+
[-11, -5219, 43351, 32679, -5264],
|
|
21307
|
+
[-8, -5265, 42888, 33219, -5298],
|
|
21308
|
+
[-6, -5305, 42419, 33757, -5329],
|
|
21309
|
+
[-4, -5341, 41944, 34295, -5358],
|
|
21310
|
+
[-3, -5371, 41464, 34829, -5383],
|
|
21311
|
+
[-2, -5397, 40980, 35359, -5404],
|
|
21312
|
+
[-1, -5419, 40490, 35889, -5423],
|
|
21313
|
+
[0, -5437, 39996, 36415, -5438],
|
|
21314
|
+
[0, -5449, 39497, 36937, -5449],
|
|
21315
|
+
[0, -5457, 38993, 37457, -5457],
|
|
21316
|
+
[0, -5461, 38485, 37973, -5461]
|
|
21317
|
+
];
|
|
21318
|
+
function hqCubicBinWeights(bin) {
|
|
21319
|
+
if (bin < 64) {
|
|
21320
|
+
return { first: -2, weights: HQ_CUBIC_HALF_TABLE[bin] };
|
|
21321
|
+
}
|
|
21322
|
+
return { first: -1, weights: HQ_CUBIC_HALF_TABLE[127 - bin].slice().reverse() };
|
|
21323
|
+
}
|
|
21324
|
+
var HQ_CUBIC_CDF = (() => {
|
|
21325
|
+
const cdf = new Int32Array(512).fill(Number.NaN);
|
|
21326
|
+
for (let bin = 0; bin < 128; bin++) {
|
|
21327
|
+
const { first, weights } = hqCubicBinWeights(bin);
|
|
21328
|
+
let acc = -32768;
|
|
21329
|
+
for (let i = 0; i <= 5; i++) {
|
|
21330
|
+
const m = 128 * (first + i) - 64 - bin - 1;
|
|
21331
|
+
if (m >= -256 && m <= 255) {
|
|
21332
|
+
cdf[m + 256] = acc;
|
|
21333
|
+
}
|
|
21334
|
+
if (i < 5) {
|
|
21335
|
+
acc += weights[i];
|
|
21336
|
+
}
|
|
21337
|
+
}
|
|
21338
|
+
}
|
|
21339
|
+
return cdf;
|
|
21340
|
+
})();
|
|
21341
|
+
function hqCubicCdf(m) {
|
|
21342
|
+
if (m < -256) {
|
|
21343
|
+
return -32768;
|
|
21344
|
+
}
|
|
21345
|
+
if (m > 255) {
|
|
21346
|
+
return 32768;
|
|
21347
|
+
}
|
|
21348
|
+
return HQ_CUBIC_CDF[m + 256];
|
|
21349
|
+
}
|
|
21350
|
+
|
|
21025
21351
|
// src/emf-plus-image-resample.ts
|
|
21026
21352
|
var INTERPOLATION_KERNELS = {
|
|
21027
21353
|
0: "bilinear",
|
|
@@ -21074,6 +21400,20 @@ function snapToDeviceGrid(spec) {
|
|
|
21074
21400
|
const [a, b, c, d] = m;
|
|
21075
21401
|
return [a, b, c, d, ox - a * spec.srcX - c * spec.srcY, oy - b * spec.srcX - d * spec.srcY];
|
|
21076
21402
|
}
|
|
21403
|
+
function snapOriginKeepCorners(spec) {
|
|
21404
|
+
const m = spec.toDevice;
|
|
21405
|
+
const map = (u, v) => [m[0] * u + m[2] * v + m[4], m[1] * u + m[3] * v + m[5]];
|
|
21406
|
+
const [rx, ry] = map(spec.srcX, spec.srcY);
|
|
21407
|
+
const ox = Math.round(rx * SUBPIXEL_GRID) / SUBPIXEL_GRID;
|
|
21408
|
+
const oy = Math.round(ry * SUBPIXEL_GRID) / SUBPIXEL_GRID;
|
|
21409
|
+
const [ux, uy] = map(spec.srcX + spec.srcW, spec.srcY);
|
|
21410
|
+
const [vx, vy] = map(spec.srcX, spec.srcY + spec.srcH);
|
|
21411
|
+
const a = (ux - ox) / spec.srcW;
|
|
21412
|
+
const b = (uy - oy) / spec.srcW;
|
|
21413
|
+
const c = (vx - ox) / spec.srcH;
|
|
21414
|
+
const d = (vy - oy) / spec.srcH;
|
|
21415
|
+
return [a, b, c, d, ox - a * spec.srcX - c * spec.srcY, oy - b * spec.srcX - d * spec.srcY];
|
|
21416
|
+
}
|
|
21077
21417
|
function cubicKernel(t, a) {
|
|
21078
21418
|
const x = Math.abs(t);
|
|
21079
21419
|
if (x < 1) {
|
|
@@ -21100,18 +21440,6 @@ function cubicIntegral(t, a) {
|
|
|
21100
21440
|
}
|
|
21101
21441
|
return Math.sign(t) * v;
|
|
21102
21442
|
}
|
|
21103
|
-
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];
|
|
21104
|
-
function fadeAt(d, bilinear) {
|
|
21105
|
-
if (d >= 1) {
|
|
21106
|
-
return 0;
|
|
21107
|
-
}
|
|
21108
|
-
if (bilinear) {
|
|
21109
|
-
return 1 - Math.max(0, d);
|
|
21110
|
-
}
|
|
21111
|
-
const x = Math.max(0, d) * 20;
|
|
21112
|
-
const i = Math.floor(x);
|
|
21113
|
-
return FAR_FADE[i] + (FAR_FADE[i + 1] - FAR_FADE[i]) * (x - i);
|
|
21114
|
-
}
|
|
21115
21443
|
function ceilExtent(len) {
|
|
21116
21444
|
return Math.ceil(len * (1 - 15e-8));
|
|
21117
21445
|
}
|
|
@@ -21119,6 +21447,17 @@ function nearSourceExtent(deviceLen, srcLen) {
|
|
|
21119
21447
|
const d = ceilExtent(deviceLen) - srcLen;
|
|
21120
21448
|
return d >= -1 && d <= 1;
|
|
21121
21449
|
}
|
|
21450
|
+
function unitCopyOffset(t, other, spec) {
|
|
21451
|
+
const f = t - Math.round(t);
|
|
21452
|
+
if (f > -1 / 64 + 1e-9) {
|
|
21453
|
+
return f <= 1 / 64 + 1e-9;
|
|
21454
|
+
}
|
|
21455
|
+
if (Math.abs(f + 1 / 64) > 1e-9 || !isPowerOfTwo(spec.srcW) || !isPowerOfTwo(spec.srcH)) {
|
|
21456
|
+
return false;
|
|
21457
|
+
}
|
|
21458
|
+
const g = (other - Math.round(other)) * 128;
|
|
21459
|
+
return spec.srcW * spec.srcH * Math.max(spec.srcW, spec.srcH) <= 256 || Math.abs(g - Math.round(g)) < 1e-9;
|
|
21460
|
+
}
|
|
21122
21461
|
var BICUBIC_A = -0.5;
|
|
21123
21462
|
var HQ_BICUBIC_A = -1;
|
|
21124
21463
|
function axisFilter(kernel, scale, copy) {
|
|
@@ -21238,6 +21577,9 @@ function resampleImage(rgba, width, height, spec, surface, options2 = {}) {
|
|
|
21238
21577
|
}
|
|
21239
21578
|
return resampleImage(grown, width + 1, height, { ...spec, rightHalo: void 0 }, surface);
|
|
21240
21579
|
}
|
|
21580
|
+
if (spec.wrap === "clamp" && (spec.clampArgb ?? 0) >>> 24 === 0 && (spec.kernel === "hq-bicubic" || spec.kernel === "hq-bilinear")) {
|
|
21581
|
+
return resampleImage(rgba, width, height, { ...spec, wrap: void 0, clampArgb: void 0 }, surface, options2);
|
|
21582
|
+
}
|
|
21241
21583
|
if (spec.kernel === "nearest" && !spec.wrap) {
|
|
21242
21584
|
return resampleNearest(rgba, width, height, spec, surface);
|
|
21243
21585
|
}
|
|
@@ -21248,32 +21590,21 @@ function resampleImage(rgba, width, height, spec, surface, options2 = {}) {
|
|
|
21248
21590
|
m = [m[0], 0, 0, m[3], m[4], m[5]];
|
|
21249
21591
|
}
|
|
21250
21592
|
const axisAligned = m[1] === 0 && m[2] === 0;
|
|
21593
|
+
if (hq && !axisAligned && !keepOrigin) {
|
|
21594
|
+
m = snapOriginKeepCorners(spec);
|
|
21595
|
+
}
|
|
21251
21596
|
let plainRotated = plainRotatedPass;
|
|
21252
|
-
const unitBicubicCopy = kernel === "bicubic" && axisAligned && !spec.halfPixelOffset && m[0] === 1 && m[3] === 1 &&
|
|
21253
|
-
let farFade = false;
|
|
21597
|
+
const unitBicubicCopy = kernel === "bicubic" && axisAligned && !spec.halfPixelOffset && m[0] === 1 && m[3] === 1 && unitCopyOffset(m[4], m[5], spec) && unitCopyOffset(m[5], m[4], spec);
|
|
21254
21598
|
let shiftX = 0;
|
|
21255
21599
|
let shiftY = 0;
|
|
21256
21600
|
if (hq && !axisAligned) {
|
|
21257
21601
|
const extentU = Math.hypot(m[0], m[1]) * spec.srcW;
|
|
21258
21602
|
const extentV = Math.hypot(m[2], m[3]) * spec.srcH;
|
|
21259
21603
|
const near = nearSourceExtent(extentU, spec.srcW) || nearSourceExtent(extentV, spec.srcH);
|
|
21260
|
-
|
|
21261
|
-
return resampleRotatedTwoStage(rgba, width, height, spec, surface, m, kernel, near);
|
|
21262
|
-
} else if (near) {
|
|
21263
|
-
kernel = kernel === "hq-bicubic" ? "bicubic" : "bilinear";
|
|
21264
|
-
plainRotated = true;
|
|
21265
|
-
} else {
|
|
21266
|
-
farFade = true;
|
|
21267
|
-
if (spec.halfPixelOffset) {
|
|
21268
|
-
const lu = Math.hypot(m[0], m[1]);
|
|
21269
|
-
const lv = Math.hypot(m[2], m[3]);
|
|
21270
|
-
shiftX = 0.5 * m[0] / lu + 0.5 * m[2] / lv;
|
|
21271
|
-
shiftY = 0.5 * m[1] / lu + 0.5 * m[3] / lv;
|
|
21272
|
-
}
|
|
21273
|
-
}
|
|
21604
|
+
return resampleRotatedTwoStage(rgba, width, height, spec, surface, m, kernel, near);
|
|
21274
21605
|
}
|
|
21275
21606
|
const integerBicubic = kernel === "bicubic" && (axisAligned || plainRotated);
|
|
21276
|
-
if (hq && axisAligned && !
|
|
21607
|
+
if (hq && axisAligned && !premultSource) {
|
|
21277
21608
|
const phased = resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut);
|
|
21278
21609
|
if (phased !== void 0) {
|
|
21279
21610
|
return phased;
|
|
@@ -21334,8 +21665,8 @@ function resampleImage(rgba, width, height, spec, surface, options2 = {}) {
|
|
|
21334
21665
|
const vMax = spec.srcY + spec.srcH;
|
|
21335
21666
|
const wu = [];
|
|
21336
21667
|
const wv = [];
|
|
21337
|
-
|
|
21338
|
-
|
|
21668
|
+
Math.hypot(inv2[0], inv2[2]);
|
|
21669
|
+
Math.hypot(inv2[1], inv2[3]);
|
|
21339
21670
|
const c = spec.clampArgb ?? 0;
|
|
21340
21671
|
const edge = {
|
|
21341
21672
|
wrap: spec.wrap,
|
|
@@ -21391,18 +21722,6 @@ function resampleImage(rgba, width, height, spec, surface, options2 = {}) {
|
|
|
21391
21722
|
return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge, integerBicubic, premultSource);
|
|
21392
21723
|
};
|
|
21393
21724
|
let [r, g, b, a] = sampleAt(u, v);
|
|
21394
|
-
if (farFade && !spec.wrap && a > 0) {
|
|
21395
|
-
const du = (uMax - u) / gradU;
|
|
21396
|
-
const dv = (vMax - v) / gradV;
|
|
21397
|
-
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);
|
|
21398
|
-
if (k < 1) {
|
|
21399
|
-
const f = Math.max(0, k);
|
|
21400
|
-
r *= f;
|
|
21401
|
-
g *= f;
|
|
21402
|
-
b *= f;
|
|
21403
|
-
a *= f;
|
|
21404
|
-
}
|
|
21405
|
-
}
|
|
21406
21725
|
if (a <= 0) {
|
|
21407
21726
|
continue;
|
|
21408
21727
|
}
|
|
@@ -21430,21 +21749,74 @@ function resampleImage(rgba, width, height, spec, surface, options2 = {}) {
|
|
|
21430
21749
|
return { x: bx0, y: by0, w, h, rgba: out };
|
|
21431
21750
|
}
|
|
21432
21751
|
var HQ_PHASES = 128;
|
|
21752
|
+
function isPowerOfTwo(v) {
|
|
21753
|
+
return Number.isInteger(v) && v > 0 && (v & v - 1) === 0;
|
|
21754
|
+
}
|
|
21755
|
+
function mirroredUnitIsExact(spec) {
|
|
21756
|
+
return !spec.pointsForm || isPowerOfTwo(spec.srcW) && isPowerOfTwo(spec.srcH);
|
|
21757
|
+
}
|
|
21758
|
+
function mirroredBias(spec, scale, fractionalEdge) {
|
|
21759
|
+
if (mirroredUnitIsExact(spec)) {
|
|
21760
|
+
return scale === 1 ? -(fractionalEdge ? 2 : 1) * 65536 + (spec.kernel === "hq-bicubic" ? 1 : 0) : 0;
|
|
21761
|
+
}
|
|
21762
|
+
return scale <= 1 ? 1 : 0;
|
|
21763
|
+
}
|
|
21764
|
+
function hqStep(scale) {
|
|
21765
|
+
return Math.round(65536 / scale);
|
|
21766
|
+
}
|
|
21767
|
+
function hqTentCdf(j) {
|
|
21768
|
+
if (j <= -128) {
|
|
21769
|
+
return -32768;
|
|
21770
|
+
}
|
|
21771
|
+
if (j >= 128) {
|
|
21772
|
+
return 32768;
|
|
21773
|
+
}
|
|
21774
|
+
return j < 0 ? -(512 * -j - 2 * j * j) : 512 * j - 2 * j * j;
|
|
21775
|
+
}
|
|
21776
|
+
function hqReductionTaps(cubic, scale, step, position, origin, from, to) {
|
|
21777
|
+
const taps = [];
|
|
21778
|
+
const s = Math.fround(scale);
|
|
21779
|
+
const radius = (cubic ? 2 : 1) * (step / 65536) + 1;
|
|
21780
|
+
for (let k = from; k <= to; k++) {
|
|
21781
|
+
const p = position(k);
|
|
21782
|
+
const centre = origin + p / 65536;
|
|
21783
|
+
const first = Math.ceil(centre - radius);
|
|
21784
|
+
const last = Math.floor(centre + radius);
|
|
21785
|
+
const weights = [];
|
|
21786
|
+
let prev = Number.NaN;
|
|
21787
|
+
for (let t = first; t <= last + 1; t++) {
|
|
21788
|
+
const q = 128 * s * (t - 0.5 - origin - p / 65536);
|
|
21789
|
+
const edge = Math.floor(q);
|
|
21790
|
+
const cdf = cubic ? hqCubicCdf(edge) : hqTentCdf(edge);
|
|
21791
|
+
if (t > first) {
|
|
21792
|
+
weights.push((cdf - prev) / 65536);
|
|
21793
|
+
}
|
|
21794
|
+
prev = cdf;
|
|
21795
|
+
}
|
|
21796
|
+
taps.push({ first, weights });
|
|
21797
|
+
}
|
|
21798
|
+
return taps;
|
|
21799
|
+
}
|
|
21433
21800
|
function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut) {
|
|
21434
21801
|
const kernel = spec.kernel;
|
|
21435
|
-
const
|
|
21802
|
+
const mirrorU = m[0] < 0;
|
|
21803
|
+
const scaleU = Math.abs(m[0]);
|
|
21436
21804
|
const scaleV = m[3];
|
|
21437
|
-
if (!(scaleU
|
|
21805
|
+
if (!(scaleU > 0 && scaleV > 0) || spec.rightHalo) {
|
|
21438
21806
|
return void 0;
|
|
21439
21807
|
}
|
|
21440
21808
|
const integral = (v) => Math.abs(v - Math.round(v)) < 1e-9;
|
|
21441
|
-
if (scaleU === 1 && scaleV === 1 && integral(m[4]) && integral(m[5])) {
|
|
21809
|
+
if (scaleU === 1 && scaleV === 1 && !mirrorU && integral(m[4]) && integral(m[5])) {
|
|
21442
21810
|
return void 0;
|
|
21443
21811
|
}
|
|
21812
|
+
const unitMirror = mirrorU && scaleU === 1;
|
|
21444
21813
|
const shift = spec.halfPixelOffset ? 0.5 : 0;
|
|
21445
|
-
const
|
|
21814
|
+
const edge0 = m[0] * spec.srcX + m[4] - shift;
|
|
21815
|
+
const edge1 = edge0 + m[0] * spec.srcW;
|
|
21816
|
+
const rawLeft = spec.toDevice[0] * (spec.srcX + spec.srcW) + spec.toDevice[4] - shift;
|
|
21817
|
+
const left = mirrorU ? Math.round(rawLeft * SUBPIXEL_GRID) / SUBPIXEL_GRID : Math.min(edge0, edge1);
|
|
21446
21818
|
const top = m[3] * spec.srcY + m[5] - shift;
|
|
21447
|
-
const right = left +
|
|
21819
|
+
const right = mirrorU ? left + scaleU * spec.srcW : Math.max(edge0, edge1);
|
|
21448
21820
|
const bottom = top + m[3] * spec.srcH;
|
|
21449
21821
|
const xFirst = Math.ceil(left - COVERAGE_NUDGE_X);
|
|
21450
21822
|
const xLast = Math.ceil(right - COVERAGE_NUDGE_X) - 1;
|
|
@@ -21464,43 +21836,86 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
21464
21836
|
}
|
|
21465
21837
|
const cubic = kernel === "hq-bicubic";
|
|
21466
21838
|
const bin = cubic ? 0.5 : 1;
|
|
21467
|
-
const stepU =
|
|
21468
|
-
const stepV =
|
|
21469
|
-
const
|
|
21839
|
+
const stepU = hqStep(scaleU);
|
|
21840
|
+
const stepV = hqStep(scaleV);
|
|
21841
|
+
const rawLeftEdge = mirrorU ? rawLeft : spec.toDevice[0] * spec.srcX + spec.toDevice[4] - shift;
|
|
21842
|
+
const dxRaw = xFirst - rawLeftEdge;
|
|
21843
|
+
const dx = dxRaw < 1e-5 ? 0 : dxRaw;
|
|
21470
21844
|
const dy = Math.max(0, yFirst - top);
|
|
21471
|
-
|
|
21845
|
+
if (mirrorU && (spec.halfPixelOffset || !integral(spec.srcX) || !integral(spec.srcW))) {
|
|
21846
|
+
return void 0;
|
|
21847
|
+
}
|
|
21848
|
+
const mirroredPixels = xLast - xFirst + 1 + dx;
|
|
21849
|
+
const offsetU = !mirrorU && dx > 1e-9 ? Math.round((1 - dx) * stepU) : 0;
|
|
21472
21850
|
const offsetV = dy > 1e-9 ? Math.round(dy * stepV) : 0;
|
|
21473
21851
|
const filterU = axisFilter(kernel, scaleU, false);
|
|
21474
21852
|
const filterV = axisFilter(kernel, scaleV, false);
|
|
21475
|
-
const tapsFor = (filter, step, offset, origin, from, to) => {
|
|
21853
|
+
const tapsFor = (filter, step, offset, origin, from, to, scale, mirror2 = false) => {
|
|
21476
21854
|
const taps = [];
|
|
21855
|
+
const farBias = ((step & step - 1) === 0 ? 0 : Math.round(spec.srcW / 170)) + (mirror2 ? mirroredBias(spec, scale, dx > 1e-9) : 0);
|
|
21856
|
+
const position = (k) => mirror2 ? Math.round((mirroredPixels - k) * step) + farBias : k * step + offset;
|
|
21857
|
+
if (mirror2 && unitMirror && dx <= 1e-9 && mirroredUnitIsExact(spec)) {
|
|
21858
|
+
for (let k = from; k <= to; k++) {
|
|
21859
|
+
taps.push({ first: Math.round(origin + position(k) / 65536), weights: [1] });
|
|
21860
|
+
}
|
|
21861
|
+
return taps;
|
|
21862
|
+
}
|
|
21863
|
+
const originBins = origin * HQ_PHASES;
|
|
21864
|
+
const wholeBins = Math.abs(originBins - Math.round(originBins)) < 1e-6;
|
|
21865
|
+
if (scale < 1 && wholeBins) {
|
|
21866
|
+
return hqReductionTaps(cubic, scale, step, position, origin, from, to);
|
|
21867
|
+
}
|
|
21868
|
+
const tabulated = cubic && wholeBins;
|
|
21477
21869
|
for (let k = from; k <= to; k++) {
|
|
21478
|
-
const phase = Math.floor((k
|
|
21479
|
-
|
|
21480
|
-
|
|
21481
|
-
|
|
21870
|
+
const phase = Math.floor((position(k) - 1) / (65536 / HQ_PHASES));
|
|
21871
|
+
if (tabulated) {
|
|
21872
|
+
const total = Math.round(originBins) + phase;
|
|
21873
|
+
const bins = hqCubicBinWeights((total % HQ_PHASES + HQ_PHASES) % HQ_PHASES);
|
|
21874
|
+
taps.push({
|
|
21875
|
+
first: Math.floor(total / HQ_PHASES) + bins.first,
|
|
21876
|
+
weights: bins.weights.map((w2) => w2 / 65536)
|
|
21877
|
+
});
|
|
21878
|
+
continue;
|
|
21879
|
+
}
|
|
21880
|
+
const c2 = origin + (phase + bin) / HQ_PHASES;
|
|
21881
|
+
const first = Math.ceil(c2 - filter.radius);
|
|
21882
|
+
const last = Math.floor(c2 + filter.radius);
|
|
21482
21883
|
const weights = [];
|
|
21483
21884
|
for (let t = first; t <= last; t++) {
|
|
21484
|
-
weights.push(filter.weight(t,
|
|
21885
|
+
weights.push(filter.weight(t, c2));
|
|
21485
21886
|
}
|
|
21486
21887
|
taps.push({ first, weights });
|
|
21487
21888
|
}
|
|
21488
21889
|
return taps;
|
|
21489
21890
|
};
|
|
21490
|
-
const colTaps = tapsFor(filterU, stepU, offsetU, spec.srcX, cx0 - xFirst, cx1 - xFirst);
|
|
21491
|
-
const rowTaps = tapsFor(filterV, stepV, offsetV, spec.srcY, cy0 - yFirst, cy1 - yFirst);
|
|
21891
|
+
const colTaps = tapsFor(filterU, stepU, offsetU, spec.srcX, cx0 - xFirst, cx1 - xFirst, scaleU, mirrorU);
|
|
21892
|
+
const rowTaps = tapsFor(filterV, stepV, offsetV, spec.srcY, cy0 - yFirst, cy1 - yFirst, scaleV);
|
|
21492
21893
|
let rowMin = Infinity;
|
|
21493
21894
|
let rowMax = -Infinity;
|
|
21494
21895
|
for (const t of rowTaps) {
|
|
21495
21896
|
rowMin = Math.min(rowMin, t.first);
|
|
21496
21897
|
rowMax = Math.max(rowMax, t.first + t.weights.length - 1);
|
|
21497
21898
|
}
|
|
21498
|
-
|
|
21499
|
-
|
|
21899
|
+
const c = spec.clampArgb ?? 0;
|
|
21900
|
+
const edge = spec.wrap ? {
|
|
21901
|
+
wrap: spec.wrap,
|
|
21902
|
+
clamp: [c >>> 16 & 255, c >>> 8 & 255, c & 255, c >>> 24 & 255],
|
|
21903
|
+
mirrorX: spec.wrap === "tile-flip-x" || spec.wrap === "tile-flip-xy",
|
|
21904
|
+
mirrorY: spec.wrap === "tile-flip-y" || spec.wrap === "tile-flip-xy"
|
|
21905
|
+
} : null;
|
|
21906
|
+
if (!edge) {
|
|
21907
|
+
rowMin = Math.max(0, rowMin);
|
|
21908
|
+
rowMax = Math.min(height - 1, rowMax);
|
|
21909
|
+
}
|
|
21500
21910
|
const rows = Math.max(0, rowMax - rowMin + 1);
|
|
21911
|
+
const rowMargin = edge || Math.abs(scaleV - 1) < 1e-9 ? Infinity : Math.ceil((cubic ? 2 : 1) / Math.min(1, scaleV));
|
|
21501
21912
|
const inter = new Uint8Array(rows * w * 4);
|
|
21502
21913
|
for (let r = 0; r < rows; r++) {
|
|
21503
|
-
const
|
|
21914
|
+
const rowTexel = edge ? wrapTap(rowMin + r, 0, height, edge.mirrorY, edge) : rowMin + r;
|
|
21915
|
+
if (rowTexel === OUTSIDE_TRANSPARENT || rowTexel < spec.srcY - rowMargin || rowTexel > spec.srcY + spec.srcH + rowMargin - 1) {
|
|
21916
|
+
continue;
|
|
21917
|
+
}
|
|
21918
|
+
const srcRow = rowTexel * width;
|
|
21504
21919
|
for (let i = 0; i < w; i++) {
|
|
21505
21920
|
const t = colTaps[i];
|
|
21506
21921
|
let pr = 0;
|
|
@@ -21508,19 +21923,30 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
21508
21923
|
let pb = 0;
|
|
21509
21924
|
let pa = 0;
|
|
21510
21925
|
for (let q = 0; q < t.weights.length; q++) {
|
|
21511
|
-
|
|
21512
|
-
|
|
21926
|
+
let tx = t.first + q;
|
|
21927
|
+
let px = rgba;
|
|
21928
|
+
let o = 0;
|
|
21929
|
+
if (edge) {
|
|
21930
|
+
tx = wrapTap(tx, 0, width, edge.mirrorX, edge);
|
|
21931
|
+
if (tx === OUTSIDE_TRANSPARENT) {
|
|
21932
|
+
continue;
|
|
21933
|
+
}
|
|
21934
|
+
} else if (tx < 0 || tx >= width) {
|
|
21513
21935
|
continue;
|
|
21514
21936
|
}
|
|
21515
|
-
|
|
21516
|
-
|
|
21937
|
+
if (tx === OUTSIDE_CLAMP || rowTexel === OUTSIDE_CLAMP) {
|
|
21938
|
+
px = edge?.clamp ?? [0, 0, 0, 0];
|
|
21939
|
+
} else {
|
|
21940
|
+
o = (srcRow + tx) * 4;
|
|
21941
|
+
}
|
|
21942
|
+
const a = px[o + 3];
|
|
21517
21943
|
if (a === 0) {
|
|
21518
21944
|
continue;
|
|
21519
21945
|
}
|
|
21520
21946
|
const wq = t.weights[q];
|
|
21521
|
-
pr += wq * Math.round(
|
|
21522
|
-
pg += wq * Math.round(
|
|
21523
|
-
pb += wq * Math.round(
|
|
21947
|
+
pr += wq * Math.round(px[o] * a / 255);
|
|
21948
|
+
pg += wq * Math.round(px[o + 1] * a / 255);
|
|
21949
|
+
pb += wq * Math.round(px[o + 2] * a / 255);
|
|
21524
21950
|
pa += wq * a;
|
|
21525
21951
|
}
|
|
21526
21952
|
const alpha = Math.min(255, Math.max(0, Math.round(pa)));
|
|
@@ -21566,7 +21992,7 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
21566
21992
|
return { x: cx0, y: cy0, w, h, rgba: out, premultiplied: premultOut };
|
|
21567
21993
|
}
|
|
21568
21994
|
function resampleRotatedTwoStage(rgba, width, height, spec, surface, m, kernel, near) {
|
|
21569
|
-
const pad = 2;
|
|
21995
|
+
const pad = spec.wrap ? 0 : 2;
|
|
21570
21996
|
let img;
|
|
21571
21997
|
let pw;
|
|
21572
21998
|
let ph;
|
|
@@ -21607,7 +22033,9 @@ function resampleRotatedTwoStage(rgba, width, height, spec, surface, m, kernel,
|
|
|
21607
22033
|
srcH: spec.srcH,
|
|
21608
22034
|
toDevice: [kx, 0, 0, ky, -spec.srcX * kx, -spec.srcY * ky],
|
|
21609
22035
|
kernel,
|
|
21610
|
-
halfPixelOffset: false
|
|
22036
|
+
halfPixelOffset: false,
|
|
22037
|
+
wrap: spec.wrap,
|
|
22038
|
+
clampArgb: spec.clampArgb
|
|
21611
22039
|
}, { w: W, h: H }, { premultOut: true });
|
|
21612
22040
|
if (!pre) {
|
|
21613
22041
|
return null;
|
|
@@ -21648,7 +22076,9 @@ function resampleRotatedTwoStage(rgba, width, height, spec, surface, m, kernel,
|
|
|
21648
22076
|
srcH: ph,
|
|
21649
22077
|
toDevice: [a, b, c, d, ex - a * pad - c * pad, ey - b * pad - d * pad],
|
|
21650
22078
|
kernel: kernel === "hq-bicubic" ? "bicubic" : "bilinear",
|
|
21651
|
-
halfPixelOffset: false
|
|
22079
|
+
halfPixelOffset: false,
|
|
22080
|
+
wrap: spec.wrap,
|
|
22081
|
+
clampArgb: spec.clampArgb
|
|
21652
22082
|
}, surface, { plainRotated: true, keepOrigin: true, premultSource: true });
|
|
21653
22083
|
if (!block) {
|
|
21654
22084
|
return block;
|
|
@@ -23772,21 +24202,21 @@ function popState(rCtx, stackId) {
|
|
|
23772
24202
|
if (idx !== void 0 && idx < rCtx.saveStack.length) {
|
|
23773
24203
|
const saved = rCtx.saveStack[idx];
|
|
23774
24204
|
rCtx.worldTransform = [...saved.transform];
|
|
23775
|
-
const
|
|
23776
|
-
if (
|
|
23777
|
-
rCtx.clipRegion =
|
|
23778
|
-
rCtx.antiAlias =
|
|
23779
|
-
rCtx.interpolationMode =
|
|
23780
|
-
rCtx.pixelOffsetMode =
|
|
23781
|
-
rCtx.textRenderingHint =
|
|
23782
|
-
rCtx.pageUnit =
|
|
23783
|
-
rCtx.pageScale =
|
|
24205
|
+
const snap2 = saved.snapshot;
|
|
24206
|
+
if (snap2) {
|
|
24207
|
+
rCtx.clipRegion = snap2.clipRegion;
|
|
24208
|
+
rCtx.antiAlias = snap2.antiAlias;
|
|
24209
|
+
rCtx.interpolationMode = snap2.interpolationMode;
|
|
24210
|
+
rCtx.pixelOffsetMode = snap2.pixelOffsetMode;
|
|
24211
|
+
rCtx.textRenderingHint = snap2.textRenderingHint;
|
|
24212
|
+
rCtx.pageUnit = snap2.pageUnit;
|
|
24213
|
+
rCtx.pageScale = snap2.pageScale;
|
|
23784
24214
|
const ext = plusExt(rCtx);
|
|
23785
24215
|
const { multiFormatSkip, pendingEffect } = ext;
|
|
23786
24216
|
for (const key of Object.keys(ext)) {
|
|
23787
24217
|
delete ext[key];
|
|
23788
24218
|
}
|
|
23789
|
-
Object.assign(ext,
|
|
24219
|
+
Object.assign(ext, snap2.ext, { multiFormatSkip, pendingEffect });
|
|
23790
24220
|
}
|
|
23791
24221
|
rCtx.saveStack.length = idx;
|
|
23792
24222
|
const newMap = /* @__PURE__ */ new Map();
|
|
@@ -23796,7 +24226,7 @@ function popState(rCtx, stackId) {
|
|
|
23796
24226
|
}
|
|
23797
24227
|
}
|
|
23798
24228
|
rCtx.saveIdMap = newMap;
|
|
23799
|
-
if (
|
|
24229
|
+
if (snap2) {
|
|
23800
24230
|
reapplyPlusClip(rCtx);
|
|
23801
24231
|
}
|
|
23802
24232
|
}
|
|
@@ -25265,6 +25695,7 @@ function defaultGS() {
|
|
|
25265
25695
|
deltaShift: 3,
|
|
25266
25696
|
instructControl: 0,
|
|
25267
25697
|
scanControl: false,
|
|
25698
|
+
scanSet: false,
|
|
25268
25699
|
scanType: 0,
|
|
25269
25700
|
gep0: 1,
|
|
25270
25701
|
gep1: 1,
|
|
@@ -25277,6 +25708,13 @@ function defaultGS() {
|
|
|
25277
25708
|
var HintError = class extends Error {
|
|
25278
25709
|
};
|
|
25279
25710
|
var MAX_INSTRUCTIONS = 1e6;
|
|
25711
|
+
var SIZE_TWEAK_BODIES = [
|
|
25712
|
+
// MPPEM GTEQ SWAP MPPEM LTEQ AND IF SHPIX ELSE POP POP EIF
|
|
25713
|
+
[75, 83, 35, 75, 81, 90, 88, 56, 27, 33, 33, 89],
|
|
25714
|
+
// MPPEM EQ IF SHPIX ELSE POP POP EIF
|
|
25715
|
+
[75, 84, 88, 56, 27, 33, 33, 89]
|
|
25716
|
+
];
|
|
25717
|
+
var DEFAULT_DROPOUT_PPEM = 32;
|
|
25280
25718
|
var HintedSize = class _HintedSize {
|
|
25281
25719
|
constructor(font, ppemX, ppemY, env, hinting = true) {
|
|
25282
25720
|
this.fdefs = [];
|
|
@@ -25293,6 +25731,8 @@ var HintedSize = class _HintedSize {
|
|
|
25293
25731
|
this.callFrames = [];
|
|
25294
25732
|
/** The glyph program being run belongs to a composite glyph. */
|
|
25295
25733
|
this.inComposite = false;
|
|
25734
|
+
/** IUP[y] has run in the current glyph program. */
|
|
25735
|
+
this.iupy = false;
|
|
25296
25736
|
this.count = 0;
|
|
25297
25737
|
this.font = font;
|
|
25298
25738
|
this.env = env;
|
|
@@ -25360,7 +25800,7 @@ var HintedSize = class _HintedSize {
|
|
|
25360
25800
|
}
|
|
25361
25801
|
/** The scan-conversion mode prep left, used when a glyph program doesn't set its own. */
|
|
25362
25802
|
get defaultScan() {
|
|
25363
|
-
return { scanControl: this.gs0.scanControl, scanType: this.gs0.scanType };
|
|
25803
|
+
return { scanControl: this.gs0.scanControl, scanSet: this.gs0.scanSet, scanType: this.gs0.scanType };
|
|
25364
25804
|
}
|
|
25365
25805
|
// -----------------------------------------------------------------------
|
|
25366
25806
|
// Glyph loading
|
|
@@ -25388,6 +25828,7 @@ var HintedSize = class _HintedSize {
|
|
|
25388
25828
|
advance: pp2x - pp1x,
|
|
25389
25829
|
linearAdvance: mulFix(advance, this.xScale),
|
|
25390
25830
|
scanControl: res2.scanControl,
|
|
25831
|
+
scanSet: res2.scanSet,
|
|
25391
25832
|
scanType: res2.scanType
|
|
25392
25833
|
};
|
|
25393
25834
|
}
|
|
@@ -25452,7 +25893,7 @@ var HintedSize = class _HintedSize {
|
|
|
25452
25893
|
let lastScan = scan;
|
|
25453
25894
|
for (const comp of glyph.components) {
|
|
25454
25895
|
const sub = this.loadRecursive(comp.glyphIndex, depth + 1);
|
|
25455
|
-
lastScan = { scanControl: sub.scanControl, scanType: sub.scanType };
|
|
25896
|
+
lastScan = { scanControl: sub.scanControl, scanSet: sub.scanSet, scanType: sub.scanType };
|
|
25456
25897
|
const z = sub.zone;
|
|
25457
25898
|
const m = z.n - 4;
|
|
25458
25899
|
if (comp.flags & (WE_HAVE_A_SCALE | WE_HAVE_AN_X_AND_Y_SCALE | WE_HAVE_A_TWO_BY_TWO)) {
|
|
@@ -25588,12 +26029,13 @@ var HintedSize = class _HintedSize {
|
|
|
25588
26029
|
this.pts = zone;
|
|
25589
26030
|
this.zp0 = this.zp1 = this.zp2 = zone;
|
|
25590
26031
|
this.stack = [];
|
|
26032
|
+
this.iupy = false;
|
|
25591
26033
|
this.computeFuncs();
|
|
25592
26034
|
try {
|
|
25593
26035
|
this.execute(instructions);
|
|
25594
26036
|
} catch {
|
|
25595
26037
|
}
|
|
25596
|
-
return { zone, scanControl: this.gs.scanControl, scanType: this.gs.scanType };
|
|
26038
|
+
return { zone, scanControl: this.gs.scanControl, scanSet: this.gs.scanSet, scanType: this.gs.scanType };
|
|
25597
26039
|
}
|
|
25598
26040
|
// -----------------------------------------------------------------------
|
|
25599
26041
|
// Vector / projection machinery
|
|
@@ -25693,14 +26135,21 @@ var HintedSize = class _HintedSize {
|
|
|
25693
26135
|
}
|
|
25694
26136
|
/**
|
|
25695
26137
|
* Backward-compatible ClearType reads storage 22 (TypeMan Talk
|
|
25696
|
-
* DStroke/IStroke)
|
|
25697
|
-
*
|
|
25698
|
-
*
|
|
26138
|
+
* DStroke/IStroke) and 24 (spacing functions) as 0 inside the functions
|
|
26139
|
+
* whose signatures Microsoft documents, which bypasses them, and storage
|
|
26140
|
+
* 8 (VacuFormRound) as 0 wherever it is read: the Monotype fonts store
|
|
26141
|
+
* there whether the size is small (`MPPEM <= limit`) and, when it is,
|
|
26142
|
+
* run a block of corner-squaring ALIGNRP and SHPIX calls after the IUPs
|
|
26143
|
+
* that native ClearType never runs (Arial and Times New Roman bowls at
|
|
26144
|
+
* 9 to 17 ppem; 2,890 to 3,059 of 3,720 size-sheet captures exact).
|
|
25699
26145
|
*/
|
|
25700
26146
|
ctBypassStorage(i) {
|
|
25701
26147
|
if (!this.ctCompat() || i !== 22 && i !== 24 && i !== 8) {
|
|
25702
26148
|
return false;
|
|
25703
26149
|
}
|
|
26150
|
+
if (i === 8) {
|
|
26151
|
+
return true;
|
|
26152
|
+
}
|
|
25704
26153
|
const frame2 = this.callFrames[this.callFrames.length - 1];
|
|
25705
26154
|
if (!frame2) {
|
|
25706
26155
|
return false;
|
|
@@ -25711,10 +26160,7 @@ var HintedSize = class _HintedSize {
|
|
|
25711
26160
|
if (i === 22) {
|
|
25712
26161
|
return at([176, 22, 67, 88]);
|
|
25713
26162
|
}
|
|
25714
|
-
|
|
25715
|
-
return at([1, 176, 24, 67, 88]) || at([1, 24, 176, 24, 67, 88]);
|
|
25716
|
-
}
|
|
25717
|
-
return at([69, 35, 70, 96, 32, 176, 38]);
|
|
26163
|
+
return at([1, 176, 24, 67, 88]) || at([1, 24, 176, 24, 67, 88]);
|
|
25718
26164
|
}
|
|
25719
26165
|
/** True when the projection vector points (mostly) along x, ClearType's direction. */
|
|
25720
26166
|
ctDirection() {
|
|
@@ -25884,6 +26330,27 @@ var HintedSize = class _HintedSize {
|
|
|
25884
26330
|
this.stack.push(v | 0);
|
|
25885
26331
|
}
|
|
25886
26332
|
/** Returns the length of the instruction at `ip` (for skipping). */
|
|
26333
|
+
/**
|
|
26334
|
+
* True for the two generic per-size tweak helpers of Monotype-hinted fonts
|
|
26335
|
+
* (Arial, Times New Roman, Tahoma), whose whole body is `MPPEM >= lo and
|
|
26336
|
+
* MPPEM <= hi: SHPIX` or `MPPEM == ppem: SHPIX`. Native ClearType ignores
|
|
26337
|
+
* the x shifts they issue; the mode-selected variants (the same body behind
|
|
26338
|
+
* `RS 2` / `EQ`), inline shifts and every other function are applied. Measured on
|
|
26339
|
+
* private fonts (`shpix-*.ttf`): any other body, such as extra bytes before
|
|
26340
|
+
* or after the helper, strict comparisons or a missing ELSE branch, is
|
|
26341
|
+
* applied, and the function number does not matter.
|
|
26342
|
+
*/
|
|
26343
|
+
static isSizeTweak(def) {
|
|
26344
|
+
if (def.sizeTweak === void 0) {
|
|
26345
|
+
const n = def.end - def.start;
|
|
26346
|
+
def.sizeTweak = SIZE_TWEAK_BODIES.some((body) => body.length === n && body.every((b, i) => def.code[def.start + i] === b));
|
|
26347
|
+
}
|
|
26348
|
+
return def.sizeTweak;
|
|
26349
|
+
}
|
|
26350
|
+
inSizeTweak() {
|
|
26351
|
+
const frame2 = this.callFrames[this.callFrames.length - 1];
|
|
26352
|
+
return !!frame2 && _HintedSize.isSizeTweak(frame2.def);
|
|
26353
|
+
}
|
|
25887
26354
|
static insLength(code, ip) {
|
|
25888
26355
|
const op = code[ip];
|
|
25889
26356
|
if (op === 64) {
|
|
@@ -25903,6 +26370,7 @@ var HintedSize = class _HintedSize {
|
|
|
25903
26370
|
execute(code) {
|
|
25904
26371
|
const calls = [];
|
|
25905
26372
|
this.callFrames = calls;
|
|
26373
|
+
this.count = 0;
|
|
25906
26374
|
let ip = 0;
|
|
25907
26375
|
let cur = code;
|
|
25908
26376
|
while (true) {
|
|
@@ -26350,7 +26818,7 @@ var HintedSize = class _HintedSize {
|
|
|
26350
26818
|
while (gs.loop > 0) {
|
|
26351
26819
|
const p = this.pop();
|
|
26352
26820
|
if (p >= 0 && p < this.zp2.n) {
|
|
26353
|
-
const keep = !this.ctCompat() || this.inComposite || gs.fvx === 0 && (this.zp2.tags[p] & TOUCH_Y) !== 0;
|
|
26821
|
+
const keep = !this.ctCompat() || this.inComposite || gs.fvx === 0 && (this.zp2.tags[p] & TOUCH_Y) !== 0 || gs.fvx !== 0 && !this.env.grayscale && !this.inSizeTweak();
|
|
26354
26822
|
if (keep) {
|
|
26355
26823
|
this.moveZp2(p, dx, dy, true);
|
|
26356
26824
|
}
|
|
@@ -26382,7 +26850,7 @@ var HintedSize = class _HintedSize {
|
|
|
26382
26850
|
this.zp1.curY[p] - this.zp0.curY[gs.rp0]
|
|
26383
26851
|
);
|
|
26384
26852
|
let target = d;
|
|
26385
|
-
if (this.ctCompat() && gs.gep0 !== 0 && gs.gep1 !== 0) {
|
|
26853
|
+
if (this.ctCompat() && this.ctDirection() && gs.gep0 !== 0 && gs.gep1 !== 0) {
|
|
26386
26854
|
const org = this.dualProjectOrus(
|
|
26387
26855
|
this.zp1.orusX[p] - this.zp0.orusX[gs.rp0],
|
|
26388
26856
|
this.zp1.orusY[p] - this.zp0.orusY[gs.rp0]
|
|
@@ -26675,6 +27143,7 @@ var HintedSize = class _HintedSize {
|
|
|
26675
27143
|
case 133: {
|
|
26676
27144
|
const v = this.pop();
|
|
26677
27145
|
const a = v & 255;
|
|
27146
|
+
gs.scanSet = true;
|
|
26678
27147
|
if (a === 255) {
|
|
26679
27148
|
gs.scanControl = true;
|
|
26680
27149
|
return true;
|
|
@@ -26685,10 +27154,10 @@ var HintedSize = class _HintedSize {
|
|
|
26685
27154
|
}
|
|
26686
27155
|
if (v & 256 && this.ppem <= a) gs.scanControl = true;
|
|
26687
27156
|
if (v & 512 && this.env.rotated) gs.scanControl = true;
|
|
26688
|
-
if (v & 1024 && this.stretched) gs.scanControl = true;
|
|
27157
|
+
if (v & 1024 && (this.stretched || this.env.reportStretched)) gs.scanControl = true;
|
|
26689
27158
|
if (v & 2048 && this.ppem > a) gs.scanControl = false;
|
|
26690
27159
|
if (v & 4096 && this.env.rotated) gs.scanControl = false;
|
|
26691
|
-
if (v & 8192 && this.stretched) gs.scanControl = false;
|
|
27160
|
+
if (v & 8192 && (this.stretched || this.env.reportStretched)) gs.scanControl = false;
|
|
26692
27161
|
return true;
|
|
26693
27162
|
}
|
|
26694
27163
|
case 134:
|
|
@@ -26700,7 +27169,7 @@ var HintedSize = class _HintedSize {
|
|
|
26700
27169
|
let k = 0;
|
|
26701
27170
|
if (sel & 1) k = this.env.version;
|
|
26702
27171
|
if (sel & 2 && this.env.rotated) k |= 1 << 8;
|
|
26703
|
-
if (sel & 4 && this.stretched) k |= 1 << 9;
|
|
27172
|
+
if (sel & 4 && (this.stretched || this.env.reportStretched)) k |= 1 << 9;
|
|
26704
27173
|
if (sel & 32 && this.env.grayscale) k |= 1 << 12;
|
|
26705
27174
|
if (sel & 64 && this.env.clearType) k |= 1 << 13;
|
|
26706
27175
|
if (sel & 128 && this.env.clearType && this.env.compatibleWidths !== false) k |= 1 << 14;
|
|
@@ -27002,6 +27471,7 @@ var HintedSize = class _HintedSize {
|
|
|
27002
27471
|
return this.dualProject(mulFix(dx, this.xScale), mulFix(dy, this.yScale));
|
|
27003
27472
|
}
|
|
27004
27473
|
insIUP(xAxis) {
|
|
27474
|
+
if (!xAxis) this.iupy = true;
|
|
27005
27475
|
const z = this.pts;
|
|
27006
27476
|
const mask = xAxis ? TOUCH_X : TOUCH_Y;
|
|
27007
27477
|
const orgs = xAxis ? z.orgX : z.orgY;
|
|
@@ -27133,7 +27603,7 @@ var HintedSize = class _HintedSize {
|
|
|
27133
27603
|
let s = (b & 15) - 8;
|
|
27134
27604
|
if (s >= 0) s++;
|
|
27135
27605
|
s *= 1 << 6 - this.gs.deltaShift;
|
|
27136
|
-
if (this.ctCompat() && !(this.gs.fvx === 0 && (this.zp0.tags[a] & TOUCH_Y) !== 0)) {
|
|
27606
|
+
if (this.ctCompat() && (this.iupy || !(this.gs.fvx === 0 && (this.zp0.tags[a] & TOUCH_Y) !== 0))) {
|
|
27137
27607
|
continue;
|
|
27138
27608
|
}
|
|
27139
27609
|
this.move(this.zp0, a, s);
|
|
@@ -27812,7 +28282,7 @@ function monoBox(o) {
|
|
|
27812
28282
|
}
|
|
27813
28283
|
return { xMin, xMax, yMin, yMax };
|
|
27814
28284
|
}
|
|
27815
|
-
function rasterizeMono(o, dropout, fixedBox) {
|
|
28285
|
+
function rasterizeMono(o, dropout, fixedBox, stubOvershoot = true) {
|
|
27816
28286
|
const box = fixedBox ?? monoBox(o);
|
|
27817
28287
|
if (!box) {
|
|
27818
28288
|
return null;
|
|
@@ -27868,10 +28338,10 @@ function rasterizeMono(o, dropout, fixedBox) {
|
|
|
27868
28338
|
break;
|
|
27869
28339
|
case 1:
|
|
27870
28340
|
case 5:
|
|
27871
|
-
if (left.next === right && left.height <= 0 && !(left.flags & OVERSHOOT_TOP && x2 - x1 >= r.half)) {
|
|
28341
|
+
if (left.next === right && left.height <= 0 && !(stubOvershoot && left.flags & OVERSHOOT_TOP && x2 - x1 >= r.half)) {
|
|
27872
28342
|
return;
|
|
27873
28343
|
}
|
|
27874
|
-
if (right.next === left && left.start === y && !(left.flags & OVERSHOOT_BOTTOM && x2 - x1 >= r.half)) {
|
|
28344
|
+
if (right.next === left && left.start === y && !(stubOvershoot && left.flags & OVERSHOOT_BOTTOM && x2 - x1 >= r.half)) {
|
|
27875
28345
|
return;
|
|
27876
28346
|
}
|
|
27877
28347
|
pxl = mode === 1 ? e2 : r.floorPub(Math.floor((x1 + x2 + Math.floor(P * 63 / 64)) / 2));
|
|
@@ -27927,10 +28397,10 @@ function rasterizeMono(o, dropout, fixedBox) {
|
|
|
27927
28397
|
break;
|
|
27928
28398
|
case 1:
|
|
27929
28399
|
case 5:
|
|
27930
|
-
if (left.next === right && left.height <= 0 && !(left.flags & OVERSHOOT_TOP && x2 - x1 >= h.half)) {
|
|
28400
|
+
if (left.next === right && left.height <= 0 && !(stubOvershoot && left.flags & OVERSHOOT_TOP && x2 - x1 >= h.half)) {
|
|
27931
28401
|
return;
|
|
27932
28402
|
}
|
|
27933
|
-
if (right.next === left && left.start === col && !(left.flags & OVERSHOOT_BOTTOM && x2 - x1 >= h.half)) {
|
|
28403
|
+
if (right.next === left && left.start === col && !(stubOvershoot && left.flags & OVERSHOOT_BOTTOM && x2 - x1 >= h.half)) {
|
|
27934
28404
|
return;
|
|
27935
28405
|
}
|
|
27936
28406
|
pxl = mode === 1 ? e2 : h.floorPub(Math.floor((x1 + x2 + Math.floor(P * 63 / 64)) / 2));
|
|
@@ -27956,7 +28426,7 @@ function rasterizeMono(o, dropout, fixedBox) {
|
|
|
27956
28426
|
return { width, height, left: box.xMin, top: box.yMax, data };
|
|
27957
28427
|
}
|
|
27958
28428
|
var GRAY_OVERSAMPLE = 4;
|
|
27959
|
-
function rasterizeSamples(o, kx, ky, padX = 0) {
|
|
28429
|
+
function rasterizeSamples(o, kx, ky, padX = 0, dropout = 2, stubOvershoot = true) {
|
|
27960
28430
|
const n = o.xs.length;
|
|
27961
28431
|
if (n === 0) {
|
|
27962
28432
|
return null;
|
|
@@ -27985,10 +28455,10 @@ function rasterizeSamples(o, kx, ky, padX = 0) {
|
|
|
27985
28455
|
onCurve: o.onCurve,
|
|
27986
28456
|
endPts: o.endPts
|
|
27987
28457
|
};
|
|
27988
|
-
const hi = rasterizeMono(big,
|
|
28458
|
+
const hi = rasterizeMono(big, dropout, { xMin: box.xMin * kx, xMax: box.xMax * kx, yMin: box.yMin * ky, yMax: box.yMax * ky }, stubOvershoot);
|
|
27989
28459
|
return hi ? { box, hi } : null;
|
|
27990
28460
|
}
|
|
27991
|
-
function rasterizeGray(o) {
|
|
28461
|
+
function rasterizeGray(o, dropout = 2) {
|
|
27992
28462
|
const n = o.xs.length;
|
|
27993
28463
|
if (n === 0) {
|
|
27994
28464
|
return null;
|
|
@@ -28018,7 +28488,7 @@ function rasterizeGray(o) {
|
|
|
28018
28488
|
onCurve: o.onCurve,
|
|
28019
28489
|
endPts: o.endPts
|
|
28020
28490
|
};
|
|
28021
|
-
const hi = rasterizeMono(big,
|
|
28491
|
+
const hi = rasterizeMono(big, dropout, { xMin: box.xMin * k, xMax: box.xMax * k, yMin: box.yMin * k, yMax: box.yMax * k }, false);
|
|
28022
28492
|
if (!hi) {
|
|
28023
28493
|
return null;
|
|
28024
28494
|
}
|
|
@@ -28076,7 +28546,8 @@ function slantRows(b) {
|
|
|
28076
28546
|
}
|
|
28077
28547
|
return { ...b, width, data };
|
|
28078
28548
|
}
|
|
28079
|
-
var RASTER_STRETCH_COST = [0, 0, 120, 150, 250, 250];
|
|
28549
|
+
var RASTER_STRETCH_COST = [0, 0, 120, 150, 250, 250, 1150, 1280, 1840];
|
|
28550
|
+
var RASTER_MAX_X_SCALE = 5;
|
|
28080
28551
|
function unitOf(f) {
|
|
28081
28552
|
return Math.max(1, f.pixHeight - f.internalLeading);
|
|
28082
28553
|
}
|
|
@@ -28499,8 +28970,7 @@ var RealizedFont = class {
|
|
|
28499
28970
|
const skew = m && !(Math.abs(m[1]) < 1e-9 && Math.abs(m[2]) < 1e-9) && !(Math.abs(m[0]) < 1e-9 && Math.abs(m[3]) < 1e-9);
|
|
28500
28971
|
const src = skew ? this.rotatedOutline(index) : this.outline(index);
|
|
28501
28972
|
if (skew && m) {
|
|
28502
|
-
|
|
28503
|
-
m = [Math.round(m[0] * p) / p, Math.round(m[1] * p) / p, Math.round(m[2] * p) / p, Math.round(m[3] * p) / p];
|
|
28973
|
+
m = roundedRotationMatrix(m, this.ppem);
|
|
28504
28974
|
}
|
|
28505
28975
|
let o = this.mode === "cleartype" && !m && !this.syntheticItalic ? this.ctOutline(index) : src;
|
|
28506
28976
|
if (this.syntheticItalic || m || subX || subY) {
|
|
@@ -28526,11 +28996,12 @@ var RealizedFont = class {
|
|
|
28526
28996
|
}
|
|
28527
28997
|
let bitmap;
|
|
28528
28998
|
if (this.mode === "mono") {
|
|
28529
|
-
bitmap = rasterizeMono(o, dropoutMode(src.scanControl, src.scanType));
|
|
28999
|
+
bitmap = rasterizeMono(o, dropoutMode(src.scanSet ? src.scanControl : this.ppem <= DEFAULT_DROPOUT_PPEM, src.scanType));
|
|
28530
29000
|
} else if (this.mode === "cleartype") {
|
|
28531
|
-
|
|
29001
|
+
const dropout = src.scanSet ? dropoutMode(src.scanControl, src.scanType) : 2;
|
|
29002
|
+
bitmap = rasterizeClearType(o, this.gdiPlus, this.gdiPlus ? clearTypeSpread(this.ttf) : void 0, dropout);
|
|
28532
29003
|
} else {
|
|
28533
|
-
bitmap = rasterizeGray(o);
|
|
29004
|
+
bitmap = rasterizeGray(o, src.scanSet ? dropoutMode(src.scanControl, src.scanType) : 2);
|
|
28534
29005
|
}
|
|
28535
29006
|
if (bitmap && this.syntheticBold) {
|
|
28536
29007
|
bitmap = embolden(bitmap, this.mode === "mono" ? 1 : 16);
|
|
@@ -28540,6 +29011,19 @@ var RealizedFont = class {
|
|
|
28540
29011
|
return g;
|
|
28541
29012
|
}
|
|
28542
29013
|
};
|
|
29014
|
+
function roundedRotationMatrix(m, ppem) {
|
|
29015
|
+
const isRotation = Math.abs(m[0] - m[3]) < 1e-6 && Math.abs(m[1] + m[2]) < 1e-6;
|
|
29016
|
+
if (isRotation && ppem > 0) {
|
|
29017
|
+
const major = ppem * Math.max(Math.abs(m[0]), Math.abs(m[1]));
|
|
29018
|
+
const target = Math.round(major);
|
|
29019
|
+
if (target >= 1) {
|
|
29020
|
+
const k = target / major;
|
|
29021
|
+
return [m[0] * k, m[1] * k, m[2] * k, m[3] * k];
|
|
29022
|
+
}
|
|
29023
|
+
}
|
|
29024
|
+
const p = ppem;
|
|
29025
|
+
return [Math.round(m[0] * p) / p, Math.round(m[1] * p) / p, Math.round(m[2] * p) / p, Math.round(m[3] * p) / p];
|
|
29026
|
+
}
|
|
28543
29027
|
function embolden(b, full) {
|
|
28544
29028
|
const w = b.width + 1;
|
|
28545
29029
|
const data = new Uint8Array(w * b.height);
|
|
@@ -28638,8 +29122,9 @@ var GdiFontCollection = class _GdiFontCollection {
|
|
|
28638
29122
|
* heights for a negative lfHeight and cell heights for a positive one.
|
|
28639
29123
|
* The cost model is fitted to GetTextMetrics over lfHeight -60..60 for
|
|
28640
29124
|
* MS Sans Serif, MS Serif, Courier, Small Fonts, System and Terminal
|
|
28641
|
-
* (98% exact): 150 per pixel too small; 290 plus
|
|
28642
|
-
* a stretch cost by factor (120, 150, 250, 250 for 2x..5x
|
|
29125
|
+
* (98% exact): 150 per pixel too small; 290 plus 340 per pixel too big;
|
|
29126
|
+
* a stretch cost by factor (120, 150, 250, 250 for 2x..5x and 1,150,
|
|
29127
|
+
* 1,280 and 1,840 for 6x..8x, the largest GDI uses) plus 100 per
|
|
28643
29128
|
* extra factor divided by the face's character height (small faces
|
|
28644
29129
|
* stretch less readily); ties go to the smaller stretch, then to the
|
|
28645
29130
|
* 96 dpi face. A weight mismatch costs 3 per 10 units (so Terminal's
|
|
@@ -28659,9 +29144,9 @@ var GdiFontCollection = class _GdiFontCollection {
|
|
|
28659
29144
|
let bestCost = Infinity;
|
|
28660
29145
|
for (const f of pool) {
|
|
28661
29146
|
const unit = height < 0 ? unitOf(f) : f.pixHeight;
|
|
28662
|
-
for (let n = 1; n
|
|
29147
|
+
for (let n = 1; n < RASTER_STRETCH_COST.length; n++) {
|
|
28663
29148
|
const d = unit * n - target;
|
|
28664
|
-
const cost = (d < 0 ? -d * 150 : d > 0 ? 290 + d *
|
|
29149
|
+
const cost = (d < 0 ? -d * 150 : d > 0 ? 290 + d * 340 : 0) + RASTER_STRETCH_COST[n] + (n > 1 ? 100 * (n - 1) / unitOf(f) : 0) + Math.abs(f.weight - weight) * 3 / 10 + n * 0.01 + (f.vertRes === 96 ? 0 : 1e-3);
|
|
28665
29150
|
if (cost < bestCost) {
|
|
28666
29151
|
bestCost = cost;
|
|
28667
29152
|
best = { face: f, scale: n };
|
|
@@ -28677,7 +29162,7 @@ var GdiFontCollection = class _GdiFontCollection {
|
|
|
28677
29162
|
return null;
|
|
28678
29163
|
}
|
|
28679
29164
|
const { face, scale } = pick;
|
|
28680
|
-
const scaleX = spec.width > 0 && face.avgWidth > 0 ? Math.max(1, Math.ceil(spec.width / face.avgWidth - 0.5)) : scale;
|
|
29165
|
+
const scaleX = spec.width > 0 && face.avgWidth > 0 ? Math.max(1, Math.ceil(spec.width / face.avgWidth - 0.5)) : Math.min(scale, RASTER_MAX_X_SCALE);
|
|
28681
29166
|
return new RasterRealizedFont(face, scale, weight >= 600 && face.weight < 600, scaleX, spec.italic && !face.italic);
|
|
28682
29167
|
}
|
|
28683
29168
|
/**
|
|
@@ -28828,9 +29313,15 @@ function resolvePpem(font, height) {
|
|
|
28828
29313
|
return ppem;
|
|
28829
29314
|
}
|
|
28830
29315
|
var CLEARTYPE_OVERSAMPLE = 6;
|
|
28831
|
-
function
|
|
29316
|
+
function clearTypeSpread(ttf) {
|
|
29317
|
+
if (ttf.family.toLowerCase() !== "courier new") {
|
|
29318
|
+
return void 0;
|
|
29319
|
+
}
|
|
29320
|
+
return { left: 1, right: ttf.weightClass >= 600 ? 1 : 2 };
|
|
29321
|
+
}
|
|
29322
|
+
function rasterizeClearType(o, truncate = false, spread, dropout = 2) {
|
|
28832
29323
|
const S = CLEARTYPE_OVERSAMPLE / 3;
|
|
28833
|
-
const r = rasterizeSamples(o, CLEARTYPE_OVERSAMPLE, 1, 1);
|
|
29324
|
+
const r = rasterizeSamples(o, CLEARTYPE_OVERSAMPLE, 1, 1, dropout, false);
|
|
28834
29325
|
if (!r) {
|
|
28835
29326
|
return null;
|
|
28836
29327
|
}
|
|
@@ -28844,12 +29335,23 @@ function rasterizeClearType(o, truncate = false) {
|
|
|
28844
29335
|
sub.fill(0);
|
|
28845
29336
|
const row2 = y * hi.width;
|
|
28846
29337
|
for (let x = 0; x < hi.width; x++) {
|
|
28847
|
-
|
|
29338
|
+
let on = hi.data[row2 + x] !== 0;
|
|
29339
|
+
if (spread && !on) {
|
|
29340
|
+
for (let k = x - spread.right; k <= x + spread.left && !on; k++) {
|
|
29341
|
+
on = k >= 0 && k < hi.width && hi.data[row2 + k] !== 0;
|
|
29342
|
+
}
|
|
29343
|
+
}
|
|
29344
|
+
if (on) {
|
|
28848
29345
|
sub[Math.floor(x / S)] += 1;
|
|
28849
29346
|
}
|
|
28850
29347
|
}
|
|
28851
29348
|
for (let j = 0; j < n; j++) {
|
|
28852
|
-
const
|
|
29349
|
+
const before = j > 0 ? sub[j - 1] : 0;
|
|
29350
|
+
const after = j + 1 < n ? sub[j + 1] : 0;
|
|
29351
|
+
let acc = before + sub[j] + after;
|
|
29352
|
+
if (spread && acc === 1 && sub[j] === 0 && (j % 3 === 0 && before === 1 || (j + 1) % 3 === 0 && after === 1)) {
|
|
29353
|
+
acc = 0;
|
|
29354
|
+
}
|
|
28853
29355
|
data[y * n + j] = (truncate ? Math.floor : Math.round)(255 * acc / (3 * S));
|
|
28854
29356
|
}
|
|
28855
29357
|
}
|
|
@@ -29137,6 +29639,12 @@ function gdiDevicePixelX(r) {
|
|
|
29137
29639
|
function gdiDevicePixelY(r) {
|
|
29138
29640
|
return !r.useMappingMode || r.deviceToCanvas ? r.sy : 1;
|
|
29139
29641
|
}
|
|
29642
|
+
function gdiDeviceToCanvasX(r, x) {
|
|
29643
|
+
return !r.useMappingMode || r.deviceToCanvas ? (x - r.bounds.left) * r.sx : x;
|
|
29644
|
+
}
|
|
29645
|
+
function gdiDeviceToCanvasY(r, y) {
|
|
29646
|
+
return !r.useMappingMode || r.deviceToCanvas ? (y - r.bounds.top) * r.sy : y;
|
|
29647
|
+
}
|
|
29140
29648
|
function activateGdiMappingMode(r) {
|
|
29141
29649
|
r.useMappingMode = true;
|
|
29142
29650
|
}
|
|
@@ -30168,22 +30676,27 @@ function penPolygon(width, height = width) {
|
|
|
30168
30676
|
return pen;
|
|
30169
30677
|
}
|
|
30170
30678
|
var matrixPenCache = /* @__PURE__ */ new Map();
|
|
30679
|
+
function halfVectorComponent(v) {
|
|
30680
|
+
return Math.sign(v) * Math.floor(Math.abs(v) + 0.75);
|
|
30681
|
+
}
|
|
30171
30682
|
function penPolygonMatrix(width, m) {
|
|
30172
30683
|
const key = `${width},${m.join(",")}`;
|
|
30173
30684
|
const cached = matrixPenCache.get(key);
|
|
30174
30685
|
if (cached) {
|
|
30175
30686
|
return cached;
|
|
30176
30687
|
}
|
|
30177
|
-
const
|
|
30688
|
+
const scale = Math.hypot(m[0], m[1]);
|
|
30689
|
+
if (Math.abs(Math.hypot(m[2], m[3]) - scale) < 1e-4 * scale && Math.abs(m[0] * m[2] + m[1] * m[3]) < 1e-4 * scale * scale && width * scale < HOBBY_LIMIT) {
|
|
30690
|
+
const digital = penPolygon(Math.round(width * scale));
|
|
30691
|
+
matrixPenCache.set(key, digital);
|
|
30692
|
+
return digital;
|
|
30693
|
+
}
|
|
30694
|
+
const h = width / 2;
|
|
30178
30695
|
const mirror2 = m[0] * m[3] - m[1] * m[2] < 0 ? -1 : 1;
|
|
30179
|
-
const
|
|
30180
|
-
const
|
|
30181
|
-
|
|
30182
|
-
|
|
30183
|
-
const y = bez[i + 1] * mirror2;
|
|
30184
|
-
dev.push(Math.round(m[0] * x + m[2] * y), Math.round(m[1] * x + m[3] * y));
|
|
30185
|
-
}
|
|
30186
|
-
const f = flattenBezierPath(dev);
|
|
30696
|
+
const hx = [halfVectorComponent(m[0] * h), halfVectorComponent(m[1] * h)];
|
|
30697
|
+
const hy = [mirror2 * halfVectorComponent(m[2] * h), mirror2 * halfVectorComponent(m[3] * h)];
|
|
30698
|
+
const box = ellipseBeziersBox({ ax: -hx[0] - hy[0], ay: -hx[1] - hy[1], exx: 2 * hx[0], exy: 2 * hx[1], eyx: 2 * hy[0], eyy: 2 * hy[1] });
|
|
30699
|
+
const f = flattenBezierPath(box.slice(0, 14));
|
|
30187
30700
|
const half = [];
|
|
30188
30701
|
for (let i = 0; i + 1 < f.length; i += 2) {
|
|
30189
30702
|
half.push([f[i], f[i + 1]]);
|
|
@@ -30255,9 +30768,10 @@ function perpendicularVectors(width, dx0, dy0, height = width, matrixPen) {
|
|
|
30255
30768
|
const den = 2 * (bh - hB + (bh - hS));
|
|
30256
30769
|
const w = den === 0 ? 0 : (hB - hS) / den;
|
|
30257
30770
|
const x = D[0] + (B[0] - D[0]) * w, y = D[1] + (B[1] - D[1]) * w;
|
|
30258
|
-
const signs = [dx === 0 ? 0 : Math.sign(dy), Math.sign(dx)];
|
|
30259
|
-
const firstEdge = best === 0 && hP >= hN;
|
|
30260
30771
|
const num = hB - hS;
|
|
30772
|
+
const sign = (c) => Math.sign(den === 0 ? D[c] : D[c] * den + (B[c] - D[c]) * num);
|
|
30773
|
+
const signs = matrixPen ? [sign(0) !== 0 ? -sign(0) : dx === 0 ? 0 : Math.sign(dy), sign(1) !== 0 ? sign(1) : Math.sign(dx)] : [dx === 0 ? 0 : Math.sign(dy), Math.sign(dx)];
|
|
30774
|
+
const firstEdge = matrixPen ? best < n / 2 : best === 0 && hP >= hN;
|
|
30261
30775
|
const rounded = [0, 1].map((c) => {
|
|
30262
30776
|
const bias2 = signs[c] + 2 * oddEdgeAdjustment(Math.abs(B[c] - D[c]) % 2 === 1, firstEdge);
|
|
30263
30777
|
if (den === 0) {
|
|
@@ -30284,7 +30798,8 @@ function squareExtension(width, dx, dy, scale = 1, height = width, matrix, whole
|
|
|
30284
30798
|
if (l === 0) return [0, 0];
|
|
30285
30799
|
}
|
|
30286
30800
|
const q = width / 2 * scale / l;
|
|
30287
|
-
|
|
30801
|
+
const round2 = symmetric ? (v) => Math.sign(v) * Math.floor(Math.abs(v) + 0.5) : (v) => Math.floor(v + 0.5);
|
|
30802
|
+
return [round2((matrix[0] * lx + matrix[2] * ly) * q), round2((matrix[1] * lx + matrix[3] * ly) * q)];
|
|
30288
30803
|
}
|
|
30289
30804
|
const [ax, ay] = typeof logicalScale === "number" ? [logicalScale, logicalScale] : logicalScale;
|
|
30290
30805
|
const r = width / 2 * scale;
|
|
@@ -30338,7 +30853,8 @@ var Outliner = class {
|
|
|
30338
30853
|
const [L, R] = drawVertices(this.pen, d[0], d[1], this.opts.width, this.opts.height, nibMatrix);
|
|
30339
30854
|
const perpendicular = curve && drawDir ? drawDir : [dx, dy];
|
|
30340
30855
|
const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1], this.opts.height, nibMatrix ? this.pen : void 0);
|
|
30341
|
-
|
|
30856
|
+
const reversed = !!drawDir && dx * drawDir[0] + dy * drawDir[1] < 0;
|
|
30857
|
+
return { dx, dy, tx: reversed ? drawDir[0] : dx, ty: reversed ? drawDir[1] : dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.capWidth ?? this.opts.width, perpendicular[0], perpendicular[1], 1, this.opts.height ?? this.opts.capWidth, nibMatrix, !!(this.opts.wholePixelDashVectors || this.opts.cutToLogicalUnits), void 0, this.opts.logicalScale), pe: [perpendicular[0], perpendicular[1]], curveEnd: !!drawDir, role: drawDir?.[2] ?? 3, tangentLength: drawDir ? drawDir[0] * drawDir[0] + drawDir[1] * drawDir[1] : 0, curve };
|
|
30342
30858
|
}
|
|
30343
30859
|
push(p, v) {
|
|
30344
30860
|
this.pts.push([p[0] + v[0], p[1] + v[1]]);
|
|
@@ -30451,7 +30967,7 @@ var Outliner = class {
|
|
|
30451
30967
|
const sv = this.capSide(s, from);
|
|
30452
30968
|
const ev = this.capSide(s, to);
|
|
30453
30969
|
if (cap === "square") {
|
|
30454
|
-
const e0 = scale === 1 || s.curveEnd ? s.e :
|
|
30970
|
+
const e0 = scale === 1 || s.curveEnd ? s.e : this.scaledExtension(s, scale);
|
|
30455
30971
|
const e = start ? [-e0[0], -e0[1]] : e0;
|
|
30456
30972
|
this.push(p, [sv[0] + e[0], sv[1] + e[1]]);
|
|
30457
30973
|
this.push(p, [ev[0] + e[0], ev[1] + e[1]]);
|
|
@@ -30460,6 +30976,23 @@ var Outliner = class {
|
|
|
30460
30976
|
this.push(p, ev);
|
|
30461
30977
|
}
|
|
30462
30978
|
}
|
|
30979
|
+
/**
|
|
30980
|
+
* The square-cap extension of a dash end that GDI scales by its real over whole-pixel length. At one logical unit per device pixel the
|
|
30981
|
+
* extension is the vector component times (half the width over the whole-pixel length), a float32 product of a float32 ratio, rounded
|
|
30982
|
+
* half away from zero; ties of the exact product (110.5, 3.5, 57.5, -62.5) fall where that single-precision value puts them.
|
|
30983
|
+
*/
|
|
30984
|
+
scaledExtension(s, scale) {
|
|
30985
|
+
const o = this.opts;
|
|
30986
|
+
if (o.wholePixelDashVectors && !o.matrix && !o.dashMetric && (o.height === void 0 || o.height === o.width)) {
|
|
30987
|
+
const length = norm(Math.floor(s.pe[0] / 16), Math.floor(s.pe[1] / 16)) * 16;
|
|
30988
|
+
if (length > 0) {
|
|
30989
|
+
const ratio = Math.fround(o.width / 2 / length);
|
|
30990
|
+
const component = (v) => Math.sign(v) * Math.floor(Math.fround(Math.abs(v) * ratio) + 0.5);
|
|
30991
|
+
return [component(s.pe[0]), component(s.pe[1])];
|
|
30992
|
+
}
|
|
30993
|
+
}
|
|
30994
|
+
return squareExtension(o.width, s.pe[0], s.pe[1], scale, o.height, o.deviceNib ? o.matrix : void 0, false, !!o.wholePixelDashVectors);
|
|
30995
|
+
}
|
|
30463
30996
|
/**
|
|
30464
30997
|
* The join at `p` on `side`, coming along `a` and leaving along `b` in
|
|
30465
30998
|
* outline order (for the left side, walked backwards, `a` is the later
|
|
@@ -30503,7 +31036,7 @@ var Outliner = class {
|
|
|
30503
31036
|
}
|
|
30504
31037
|
}
|
|
30505
31038
|
} else if (join === "miter") {
|
|
30506
|
-
const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit, side, this.opts.height);
|
|
31039
|
+
const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit, side, this.opts.height, this.opts.deviceNib ? this.opts.matrix : void 0);
|
|
30507
31040
|
if (m) {
|
|
30508
31041
|
this.push(p, m);
|
|
30509
31042
|
}
|
|
@@ -30577,7 +31110,7 @@ var Outliner = class {
|
|
|
30577
31110
|
for (let i = 0; i + 1 < segs2.length; i++) {
|
|
30578
31111
|
const s = segs2[i];
|
|
30579
31112
|
const t = segs2[i + 1];
|
|
30580
|
-
const tr = turnSign(s.
|
|
31113
|
+
const tr = turnSign(s.tx, s.ty, t.tx, t.ty);
|
|
30581
31114
|
if (tr === 0) {
|
|
30582
31115
|
this.push(P[i + 1], this.joinSide(s, "R"));
|
|
30583
31116
|
} else {
|
|
@@ -30588,7 +31121,7 @@ var Outliner = class {
|
|
|
30588
31121
|
for (let i = segs2.length - 1; i > 0; i--) {
|
|
30589
31122
|
const s = segs2[i];
|
|
30590
31123
|
const t = segs2[i - 1];
|
|
30591
|
-
const tr = turnSign(t.
|
|
31124
|
+
const tr = turnSign(t.tx, t.ty, s.tx, s.ty);
|
|
30592
31125
|
if (tr === 0) {
|
|
30593
31126
|
this.push(P[i], this.joinSide(s, "L"));
|
|
30594
31127
|
} else {
|
|
@@ -30608,7 +31141,7 @@ var Outliner = class {
|
|
|
30608
31141
|
const i = j % m;
|
|
30609
31142
|
const s = segs2[(i + m - 1) % m];
|
|
30610
31143
|
const t = segs2[i];
|
|
30611
|
-
const tr = turnSign(s.
|
|
31144
|
+
const tr = turnSign(s.tx, s.ty, t.tx, t.ty);
|
|
30612
31145
|
if (tr === 0) {
|
|
30613
31146
|
this.push(P[i], this.joinSide(s, "R"));
|
|
30614
31147
|
} else {
|
|
@@ -30620,7 +31153,7 @@ var Outliner = class {
|
|
|
30620
31153
|
const i = (m - j) % m;
|
|
30621
31154
|
const s = segs2[i];
|
|
30622
31155
|
const t = segs2[(i + m - 1) % m];
|
|
30623
|
-
const tr = turnSign(t.
|
|
31156
|
+
const tr = turnSign(t.tx, t.ty, s.tx, s.ty);
|
|
30624
31157
|
if (tr === 0) {
|
|
30625
31158
|
this.push(P[i], this.joinSide(s, "L"));
|
|
30626
31159
|
} else {
|
|
@@ -30640,6 +31173,14 @@ var Outliner = class {
|
|
|
30640
31173
|
this.flush();
|
|
30641
31174
|
}
|
|
30642
31175
|
};
|
|
31176
|
+
function nearestUnit(v) {
|
|
31177
|
+
return Math.sign(v) * Math.floor((Math.abs(v) + 8) / 16) * 16;
|
|
31178
|
+
}
|
|
31179
|
+
function cutCoordinate(x0, d, t, len) {
|
|
31180
|
+
const offset = Math.abs(d) * (t / len);
|
|
31181
|
+
const v = Math.fround(x0 + (d < 0 ? -offset : offset));
|
|
31182
|
+
return d < 0 ? Math.ceil(v - 0.5) : Math.floor(v + 0.5);
|
|
31183
|
+
}
|
|
30643
31184
|
function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors, metric, matrix) {
|
|
30644
31185
|
const out = [];
|
|
30645
31186
|
const dashes = [];
|
|
@@ -30662,7 +31203,7 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
30662
31203
|
const dir = [x1 - x0, y1 - y0];
|
|
30663
31204
|
const det = matrix ? matrix[0] * matrix[3] - matrix[1] * matrix[2] : 1;
|
|
30664
31205
|
const real = matrix ? Math.hypot((matrix[3] * dir[0] - matrix[2] * dir[1]) / det, (-matrix[1] * dir[0] + matrix[0] * dir[1]) / det) : metric ? Math.hypot(dir[0] / metric[0], dir[1] / metric[1]) : norm(dir[0], dir[1]);
|
|
30665
|
-
const len = metric
|
|
31206
|
+
const len = metric ? norm(nearestUnit(dir[0] / metric[0]), nearestUnit(dir[1] / metric[1])) : matrix ? norm(nearestUnit((matrix[3] * dir[0] - matrix[2] * dir[1]) / det), nearestUnit((-matrix[1] * dir[0] + matrix[0] * dir[1]) / det)) : wholePixelVectors ? norm(Math.floor(dir[0] / 16), Math.floor(dir[1] / 16)) * 16 : norm(dir[0], dir[1]);
|
|
30666
31207
|
if (len === 0) {
|
|
30667
31208
|
if (on && cur) {
|
|
30668
31209
|
cur.pts.push(P[i + 1]);
|
|
@@ -30675,7 +31216,7 @@ function dashPieces(P, tangents, curveFlags, pattern, shorten, wholePixelVectors
|
|
|
30675
31216
|
let t = 0;
|
|
30676
31217
|
while (len - t > left || left === 0 && on) {
|
|
30677
31218
|
t += left;
|
|
30678
|
-
const q = [
|
|
31219
|
+
const q = [cutCoordinate(x0, dir[0], t, len), cutCoordinate(y0, dir[1], t, len)];
|
|
30679
31220
|
if (on && cur) {
|
|
30680
31221
|
cur.pts.push(q);
|
|
30681
31222
|
cur.dirs.push(dir);
|
|
@@ -30732,7 +31273,7 @@ function widenInLogicalSpace(path, opts, m) {
|
|
|
30732
31273
|
});
|
|
30733
31274
|
}
|
|
30734
31275
|
function widenPath(path, opts) {
|
|
30735
|
-
if (opts.matrix && !
|
|
31276
|
+
if (opts.matrix && !opts.deviceNib) {
|
|
30736
31277
|
return widenInLogicalSpace(path, opts, opts.matrix);
|
|
30737
31278
|
}
|
|
30738
31279
|
const out = [];
|
|
@@ -30786,7 +31327,7 @@ function widenPath(path, opts) {
|
|
|
30786
31327
|
}
|
|
30787
31328
|
return out;
|
|
30788
31329
|
}
|
|
30789
|
-
function miterPoint(sa, da, sb, db, width, limit, side, height = width) {
|
|
31330
|
+
function miterPoint(sa, da, sb, db, width, limit, side, height = width, matrix) {
|
|
30790
31331
|
const den = da[0] * db[1] - da[1] * db[0];
|
|
30791
31332
|
if (den === 0) {
|
|
30792
31333
|
return null;
|
|
@@ -30799,6 +31340,12 @@ function miterPoint(sa, da, sb, db, width, limit, side, height = width) {
|
|
|
30799
31340
|
const x = Math.sign(mx) * Math.floor(Math.abs(mx) + 0.5);
|
|
30800
31341
|
const y = Math.sign(my) * Math.floor(Math.abs(my) + 0.5);
|
|
30801
31342
|
const pixel = side === "L" ? Math.ceil : Math.floor;
|
|
31343
|
+
if (matrix) {
|
|
31344
|
+
const det = matrix[0] * matrix[3] - matrix[1] * matrix[2];
|
|
31345
|
+
const lx = (matrix[3] * x - matrix[2] * y) / det;
|
|
31346
|
+
const ly = (-matrix[1] * x + matrix[0] * y) / det;
|
|
31347
|
+
return Math.hypot(Math.round(lx / 16), Math.round(ly / 16)) > limit * width / 32 ? null : [x, y];
|
|
31348
|
+
}
|
|
30802
31349
|
const yDistance = height === width ? pixel(y / 16) : pixel(y / 16) * width / height;
|
|
30803
31350
|
if (Math.hypot(pixel(x / 16), yDistance) > limit * width / 32) {
|
|
30804
31351
|
return null;
|
|
@@ -30882,9 +31429,12 @@ function boxFrame(box) {
|
|
|
30882
31429
|
const h = Math.round(Math.hypot(box.eyx, box.eyy));
|
|
30883
31430
|
return { l: 0, t: 0, r: w, b: h };
|
|
30884
31431
|
}
|
|
30885
|
-
function roundRectDeviceBeziers(box, cw, ch,
|
|
31432
|
+
function roundRectDeviceBeziers(box, cw, ch, recordedClockwise = false, compatible = false) {
|
|
30886
31433
|
const f = boxFrame(box);
|
|
30887
|
-
const
|
|
31434
|
+
const mirrorX = isAxisBox(box) && box.exx < 0;
|
|
31435
|
+
const mirrorY = isAxisBox(box) && box.eyy < 0;
|
|
31436
|
+
const clockwise = recordedClockwise !== mirrorY;
|
|
31437
|
+
const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible, clockwise, mirrorX);
|
|
30888
31438
|
const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
|
|
30889
31439
|
const pts = [];
|
|
30890
31440
|
for (let i = 0; i < q.length; i += 2) {
|
|
@@ -30936,6 +31486,11 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = fal
|
|
|
30936
31486
|
set(15, null, f.b - hy);
|
|
30937
31487
|
}
|
|
30938
31488
|
}
|
|
31489
|
+
if (mirrorX) {
|
|
31490
|
+
for (let i = 0; i < pts.length; i += 2) {
|
|
31491
|
+
pts[i] = f.l + f.r - pts[i];
|
|
31492
|
+
}
|
|
31493
|
+
}
|
|
30939
31494
|
return pts;
|
|
30940
31495
|
}
|
|
30941
31496
|
function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false, compatible = false) {
|
|
@@ -30949,7 +31504,7 @@ function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false,
|
|
|
30949
31504
|
path.closeFigure();
|
|
30950
31505
|
return path;
|
|
30951
31506
|
}
|
|
30952
|
-
function arcRasterPath(box, s, e, clockwise, kind, from, path = new GdiRasterPath()) {
|
|
31507
|
+
function arcRasterPath(box, s, e, clockwise, kind, from, path = new GdiRasterPath(), mirror2) {
|
|
30953
31508
|
const f = boxFrame(box);
|
|
30954
31509
|
const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
|
|
30955
31510
|
let sx = s[0];
|
|
@@ -30971,12 +31526,19 @@ function arcRasterPath(box, s, e, clockwise, kind, from, path = new GdiRasterPat
|
|
|
30971
31526
|
if (det < 0) {
|
|
30972
31527
|
cw = !cw;
|
|
30973
31528
|
}
|
|
31529
|
+
} else if (mirror2) {
|
|
31530
|
+
cw = clockwise !== mirror2.y;
|
|
31531
|
+
if (mirror2.x) {
|
|
31532
|
+
sx = f.l + f.r - sx;
|
|
31533
|
+
ex = f.l + f.r - ex;
|
|
31534
|
+
}
|
|
30974
31535
|
} else {
|
|
30975
31536
|
if (box.exx < 0 !== box.eyy < 0) {
|
|
30976
31537
|
cw = !cw;
|
|
30977
31538
|
}
|
|
30978
31539
|
}
|
|
30979
|
-
const
|
|
31540
|
+
const mirrorX = !!mirror2?.x && isAxisBox(box);
|
|
31541
|
+
const bz = arcBeziers(f.l, f.t, f.r, f.b, sx, sy, ex, ey, cw, !!box.halfX, !!box.framed, mirrorX);
|
|
30980
31542
|
const pts = [];
|
|
30981
31543
|
for (let i = 0; i < bz.length; i += 2) {
|
|
30982
31544
|
pts.push(...map(bz[i], bz[i + 1]));
|
|
@@ -30990,7 +31552,7 @@ function arcRasterPath(box, s, e, clockwise, kind, from, path = new GdiRasterPat
|
|
|
30990
31552
|
if (kind === "pie") {
|
|
30991
31553
|
const w = f.r - f.l;
|
|
30992
31554
|
const h = f.b - f.t;
|
|
30993
|
-
const [cx, cy] = map(f.l + Math.ceil(w / 2) + (box.halfX ? 1 : 0), f.t + Math.ceil(h / 2));
|
|
31555
|
+
const [cx, cy] = map(f.l + Math.ceil(w / 2) + (box.halfX && !mirrorX ? 1 : 0), f.t + Math.ceil(h / 2));
|
|
30994
31556
|
path.lineTo(cx, cy);
|
|
30995
31557
|
}
|
|
30996
31558
|
if (kind === "pie" || kind === "chord") {
|
|
@@ -31031,8 +31593,10 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
31031
31593
|
const rotatedOrSheared = Math.abs(matrix[1]) >= 1e-6 || Math.abs(matrix[2]) >= 1e-6;
|
|
31032
31594
|
const quarterTurn = Math.abs(matrix[0]) < 1e-9 && Math.abs(matrix[3]) < 1e-9;
|
|
31033
31595
|
const general = !rCtx.wholeDevicePixels && rotatedOrSheared && !quarterTurn && Math.abs(det) > 1e-9 && state.penWidth * Math.sqrt(Math.abs(det)) * 16 >= 1;
|
|
31034
|
-
const
|
|
31035
|
-
const
|
|
31596
|
+
const unrotated = Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6;
|
|
31597
|
+
const scaled2 = !rCtx.wholeDevicePixels && unrotated && (Math.abs(Math.abs(matrix[0]) - 1) > 1e-6 || Math.abs(Math.abs(matrix[3]) - 1) > 1e-6);
|
|
31598
|
+
const dashes = state.penExtended ? ellipse || general || scaled2 ? geometricStyle(flags, state.penWidth, state.penUserStyle, 1) : geometricStyle(flags, widthPx, state.penUserStyle, widthPx / (state.penWidth || 1)) : null;
|
|
31599
|
+
const dashMetric = (ellipse || scaled2) && !general && dashes ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : void 0;
|
|
31036
31600
|
if (general) {
|
|
31037
31601
|
return {
|
|
31038
31602
|
width: Math.round(state.penWidth * 16),
|
|
@@ -31047,8 +31611,6 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
31047
31611
|
cutToLogicalUnits: !dashes
|
|
31048
31612
|
};
|
|
31049
31613
|
}
|
|
31050
|
-
const unrotated = Math.abs(matrix[1]) < 1e-6 && Math.abs(matrix[2]) < 1e-6;
|
|
31051
|
-
const scaled2 = !rCtx.wholeDevicePixels && unrotated && (Math.abs(Math.abs(matrix[0]) - 1) > 1e-6 || Math.abs(Math.abs(matrix[3]) - 1) > 1e-6);
|
|
31052
31614
|
const uniform = scaled2 && !ellipse && state.penExtended && (flags & 15) !== 6;
|
|
31053
31615
|
return {
|
|
31054
31616
|
width: Math.round((ellipse ? state.penWidth * Math.abs(matrix[0]) : widthPx) * 16),
|
|
@@ -31062,7 +31624,7 @@ function penWidenOptions(rCtx, opts = {}) {
|
|
|
31062
31624
|
// One logical unit per device pixel, unrotated: GDI measures dash
|
|
31063
31625
|
// segments in whole pixels.
|
|
31064
31626
|
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,
|
|
31065
|
-
...scaled2
|
|
31627
|
+
...scaled2 ? {
|
|
31066
31628
|
cutToLogicalUnits: true,
|
|
31067
31629
|
logicalScale: ellipse ? [Math.abs(matrix[0]), Math.abs(matrix[3])] : Math.abs(matrix[0]),
|
|
31068
31630
|
// A square cap extends by half the unrounded width in FIX.
|
|
@@ -31495,6 +32057,406 @@ function withoutOutline(spans, path) {
|
|
|
31495
32057
|
return out;
|
|
31496
32058
|
}
|
|
31497
32059
|
|
|
32060
|
+
// src/emf-plus-path-gradient-copies.ts
|
|
32061
|
+
var fix = (v) => Math.floor(v * 16 + 0.5) / 16;
|
|
32062
|
+
var TIE = 1e-6;
|
|
32063
|
+
var STRIP_TIE = 5e-3;
|
|
32064
|
+
var CONTAINMENT_TIE = 5e-4;
|
|
32065
|
+
var SLANTED_NEAR = 5e-6;
|
|
32066
|
+
var CEIL_EPSILON = 1e-9;
|
|
32067
|
+
function prepareCopies(shape, full, steps) {
|
|
32068
|
+
const n = shape.boundary.length;
|
|
32069
|
+
if (n < 3 || steps <= 0) return null;
|
|
32070
|
+
const isotropic = !shape.focus || Math.abs(shape.focus.x - shape.focus.y) <= 1e-9;
|
|
32071
|
+
const focus = shape.focus && isotropic ? Math.min(1, Math.max(0, shape.focus.x)) : 0;
|
|
32072
|
+
const vx = new Float64Array(n);
|
|
32073
|
+
const vy = new Float64Array(n);
|
|
32074
|
+
for (let i = 0; i < n; i++) {
|
|
32075
|
+
const p = shape.boundary[i];
|
|
32076
|
+
vx[i] = fix(full[0] * p.x + full[2] * p.y + full[4]);
|
|
32077
|
+
vy[i] = fix(full[1] * p.x + full[3] * p.y + full[5]);
|
|
32078
|
+
}
|
|
32079
|
+
const c = shape.center;
|
|
32080
|
+
const cx = fix(full[0] * c.x + full[2] * c.y + full[4]);
|
|
32081
|
+
const cy = fix(full[1] * c.x + full[3] * c.y + full[5]);
|
|
32082
|
+
const anisotropic = isotropic ? null : {
|
|
32083
|
+
...shape,
|
|
32084
|
+
boundary: Array.from(vx, (x, i) => ({ x, y: vy[i] })),
|
|
32085
|
+
center: { x: cx, y: cy },
|
|
32086
|
+
boundaryArgb: shape.boundaryArgb,
|
|
32087
|
+
blend: null,
|
|
32088
|
+
preset: null,
|
|
32089
|
+
transform: null
|
|
32090
|
+
};
|
|
32091
|
+
let degenerate = false;
|
|
32092
|
+
for (let i = 0; i < n; i++) {
|
|
32093
|
+
const j = (i + 1) % n;
|
|
32094
|
+
if ((vx[i] - cx) * (vy[j] - cy) - (vy[i] - cy) * (vx[j] - cx) === 0) degenerate = true;
|
|
32095
|
+
}
|
|
32096
|
+
return { cx, cy, vx, vy, steps, focus, anisotropic, degenerate };
|
|
32097
|
+
}
|
|
32098
|
+
function floatCopyIndex(g, edge, dx, dy) {
|
|
32099
|
+
const n = g.vx.length;
|
|
32100
|
+
const ax = g.vx[edge] - g.cx;
|
|
32101
|
+
const ay = g.vy[edge] - g.cy;
|
|
32102
|
+
const ex = g.vx[(edge + 1) % n] - g.vx[edge];
|
|
32103
|
+
const ey = g.vy[(edge + 1) % n] - g.vy[edge];
|
|
32104
|
+
const denominator = down32(down32(ex * dy) - down32(ey * dx));
|
|
32105
|
+
if (denominator === 0) return null;
|
|
32106
|
+
const u = down32(down32(down32(ay * dx) - down32(ax * dy)) / denominator);
|
|
32107
|
+
const bx = down32(ax + down32(u * ex));
|
|
32108
|
+
const by = down32(ay + down32(u * ey));
|
|
32109
|
+
const useX = Math.abs(bx) >= Math.abs(by);
|
|
32110
|
+
const boundary = useX ? bx : by;
|
|
32111
|
+
if (boundary === 0) return null;
|
|
32112
|
+
const r = Math.abs(down32((useX ? dx : dy) / boundary));
|
|
32113
|
+
return Math.max(0, Math.floor(down32(down32(g.steps * r) + 0.5)));
|
|
32114
|
+
}
|
|
32115
|
+
function focusCopyIndex(g, edge, px, py) {
|
|
32116
|
+
const n = g.vx.length;
|
|
32117
|
+
const dx = px - g.cx;
|
|
32118
|
+
const dy = py - g.cy;
|
|
32119
|
+
const f = Math.fround(g.focus);
|
|
32120
|
+
const j = (edge + 1) % n;
|
|
32121
|
+
const ax = g.vx[edge] - g.cx;
|
|
32122
|
+
const ay = g.vy[edge] - g.cy;
|
|
32123
|
+
const ex = g.vx[j] - g.vx[edge];
|
|
32124
|
+
const ey = g.vy[j] - g.vy[edge];
|
|
32125
|
+
const denominator = down32(down32(ex * dy) - down32(ey * dx));
|
|
32126
|
+
if (denominator === 0) return null;
|
|
32127
|
+
const u = down32(down32(down32(ay * dx) - down32(ax * dy)) / denominator);
|
|
32128
|
+
const bx = down32(ax + down32(u * ex));
|
|
32129
|
+
const by = down32(ay + down32(u * ey));
|
|
32130
|
+
const useX = Math.abs(bx) >= Math.abs(by);
|
|
32131
|
+
const b = useX ? bx : by;
|
|
32132
|
+
if (b === 0) return null;
|
|
32133
|
+
const c = useX ? g.cx : g.cy;
|
|
32134
|
+
const p = useX ? px : py;
|
|
32135
|
+
const outer = down32(c + b);
|
|
32136
|
+
const scaled2 = (c0, v) => down32(c0 + down32(f * (v - c0)));
|
|
32137
|
+
const f0x = scaled2(g.cx, g.vx[edge]);
|
|
32138
|
+
const f0y = scaled2(g.cy, g.vy[edge]);
|
|
32139
|
+
const f1x = scaled2(g.cx, g.vx[j]);
|
|
32140
|
+
const f1y = scaled2(g.cy, g.vy[j]);
|
|
32141
|
+
const fax = down32(f0x - g.cx);
|
|
32142
|
+
const fay = down32(f0y - g.cy);
|
|
32143
|
+
const fex = down32(f1x - f0x);
|
|
32144
|
+
const fey = down32(f1y - f0y);
|
|
32145
|
+
const focusDenominator = down32(down32(fex * dy) - down32(fey * dx));
|
|
32146
|
+
if (focusDenominator === 0) return null;
|
|
32147
|
+
const fu = down32(down32(down32(fay * dx) - down32(fax * dy)) / focusDenominator);
|
|
32148
|
+
const inner = down32((useX ? f0x : f0y) + down32(fu * (useX ? fex : fey)));
|
|
32149
|
+
const span = Math.fround(outer - inner);
|
|
32150
|
+
if (span === 0) return null;
|
|
32151
|
+
const t = down32(Math.fround(p - inner) / span);
|
|
32152
|
+
const position = Math.fround(down32(g.steps * t) + 0.5);
|
|
32153
|
+
if (ex !== 0 && ey !== 0) {
|
|
32154
|
+
const ulp = (v) => 2 ** (Math.floor(Math.log2(Math.abs(v) || 1)) - 23);
|
|
32155
|
+
const slack = g.steps * (ulp(inner) + ulp(outer)) / Math.abs(span);
|
|
32156
|
+
const short = Math.ceil(position) - position;
|
|
32157
|
+
if (short > 0 && short <= slack) return null;
|
|
32158
|
+
}
|
|
32159
|
+
return Math.max(0, Math.floor(position));
|
|
32160
|
+
}
|
|
32161
|
+
function tieSide(g, edge, dx, dy, q, focus = 0) {
|
|
32162
|
+
const n = g.vx.length;
|
|
32163
|
+
const ex = g.vx[(edge + 1) % n] - g.vx[edge];
|
|
32164
|
+
const ey = g.vy[(edge + 1) % n] - g.vy[edge];
|
|
32165
|
+
if (ex === 0 && ey === 0) return null;
|
|
32166
|
+
const adx = Math.abs(dx);
|
|
32167
|
+
const ady = Math.abs(dy);
|
|
32168
|
+
let odd = g.steps;
|
|
32169
|
+
while (odd % 2 === 0) odd /= 2;
|
|
32170
|
+
const fractional = (2 * q + 1) % odd !== 0;
|
|
32171
|
+
const axisAligned = ex === 0 || ey === 0;
|
|
32172
|
+
const alike = axisAligned ? ex === 0 ? adx <= ady : ady <= adx : Math.abs(ex) === Math.abs(ey) || Math.abs(ex) > Math.abs(ey) === adx > ady;
|
|
32173
|
+
if (!alike) return axisAligned ? fractional : null;
|
|
32174
|
+
const forward = ex > 0 || ex === 0 && ey > 0;
|
|
32175
|
+
if (!forward) return focus > 0 && !axisAligned ? null : fractional;
|
|
32176
|
+
if (dx * ex + dy * ey < 0) return fractional || !edgeParameterIsBinary(g, edge, dx, dy, q);
|
|
32177
|
+
return fractional && adx === ady;
|
|
32178
|
+
}
|
|
32179
|
+
function gcd(a, b) {
|
|
32180
|
+
while (b) [a, b] = [b, a % b];
|
|
32181
|
+
return a;
|
|
32182
|
+
}
|
|
32183
|
+
function edgeParameterIsBinary(g, edge, dx, dy, q) {
|
|
32184
|
+
const n = g.vx.length;
|
|
32185
|
+
const k = 16;
|
|
32186
|
+
const ex = Math.round((g.vx[(edge + 1) % n] - g.vx[edge]) * k);
|
|
32187
|
+
const ey = Math.round((g.vy[(edge + 1) % n] - g.vy[edge]) * k);
|
|
32188
|
+
const ax = Math.round((g.vx[edge] - g.cx) * k);
|
|
32189
|
+
const ay = Math.round((g.vy[edge] - g.cy) * k);
|
|
32190
|
+
const S = 2 * q + 1;
|
|
32191
|
+
const D = 2 * g.steps;
|
|
32192
|
+
const P = Math.round(dx * k) * ex + Math.round(dy * k) * ey;
|
|
32193
|
+
const A = ax * ex + ay * ey;
|
|
32194
|
+
const numerator = P * D - A * S;
|
|
32195
|
+
const denominator = (ex * ex + ey * ey) * S;
|
|
32196
|
+
if (!Number.isSafeInteger(numerator) || !Number.isSafeInteger(denominator)) return false;
|
|
32197
|
+
if (numerator === 0) return true;
|
|
32198
|
+
let d = Math.abs(denominator / gcd(Math.abs(numerator), Math.abs(denominator)));
|
|
32199
|
+
while (d % 2 === 0) d /= 2;
|
|
32200
|
+
return d === 1;
|
|
32201
|
+
}
|
|
32202
|
+
function insideCopy(g, scale, px, py, scaleY = scale) {
|
|
32203
|
+
const n = g.vx.length;
|
|
32204
|
+
let xl = Infinity;
|
|
32205
|
+
let xr = -Infinity;
|
|
32206
|
+
let ax = g.cx + (g.vx[n - 1] - g.cx) * scale;
|
|
32207
|
+
let ay = g.cy + (g.vy[n - 1] - g.cy) * scaleY;
|
|
32208
|
+
for (let i = 0; i < n; i++) {
|
|
32209
|
+
const bx = g.cx + (g.vx[i] - g.cx) * scale;
|
|
32210
|
+
const by = g.cy + (g.vy[i] - g.cy) * scaleY;
|
|
32211
|
+
if (ay <= py && by > py || by <= py && ay > py) {
|
|
32212
|
+
const x = ax + (py - ay) / (by - ay) * (bx - ax);
|
|
32213
|
+
if (x < xl) xl = x;
|
|
32214
|
+
if (x > xr) xr = x;
|
|
32215
|
+
}
|
|
32216
|
+
ax = bx;
|
|
32217
|
+
ay = by;
|
|
32218
|
+
}
|
|
32219
|
+
return xl !== Infinity && px >= Math.ceil(xl - CEIL_EPSILON) && px < Math.ceil(xr - CEIL_EPSILON);
|
|
32220
|
+
}
|
|
32221
|
+
function edgeAt(g, scaleX, scaleY, px, py) {
|
|
32222
|
+
const n = g.vx.length;
|
|
32223
|
+
const near = 1e-6;
|
|
32224
|
+
let hit = null;
|
|
32225
|
+
let vertexRow = false;
|
|
32226
|
+
for (let i = 0; i < n; i++) {
|
|
32227
|
+
const j = (i + 1) % n;
|
|
32228
|
+
const ax = g.cx + (g.vx[i] - g.cx) * scaleX;
|
|
32229
|
+
const ay = g.cy + (g.vy[i] - g.cy) * scaleY;
|
|
32230
|
+
const bx = g.cx + (g.vx[j] - g.cx) * scaleX;
|
|
32231
|
+
const by = g.cy + (g.vy[j] - g.cy) * scaleY;
|
|
32232
|
+
if (Math.abs(ax - bx) < near && Math.abs(px - ax) < near && py >= Math.min(ay, by) - near && py <= Math.max(ay, by) + near) return { kind: "vertical", edge: i };
|
|
32233
|
+
if (Math.abs(ay - by) < near && Math.abs(py - ay) < near && px >= Math.min(ax, bx) - near && px <= Math.max(ax, bx) + near) return { kind: "horizontal", edge: i };
|
|
32234
|
+
if (Math.abs(ay - py) < near) vertexRow = true;
|
|
32235
|
+
const length = Math.hypot(bx - ax, by - ay);
|
|
32236
|
+
if (length < near) continue;
|
|
32237
|
+
const across = ((px - ax) * (by - ay) - (py - ay) * (bx - ax)) / length;
|
|
32238
|
+
const along = ((px - ax) * (bx - ax) + (py - ay) * (by - ay)) / (length * length);
|
|
32239
|
+
if (Math.abs(across) < SLANTED_NEAR && along >= -near && along <= 1 + near) hit = { kind: "slanted", edge: i };
|
|
32240
|
+
}
|
|
32241
|
+
return hit ?? (vertexRow ? { kind: "slanted", edge: -1 } : null);
|
|
32242
|
+
}
|
|
32243
|
+
function focusedEdgeStep(g, px, py) {
|
|
32244
|
+
const focus = g.anisotropic.focus;
|
|
32245
|
+
const full = 1 - 1e-9;
|
|
32246
|
+
if (focus.x < full && focus.y < full) return void 0;
|
|
32247
|
+
const n = g.vx.length;
|
|
32248
|
+
let onEdge = false;
|
|
32249
|
+
for (let i = 0; i < n && !onEdge; i++) {
|
|
32250
|
+
const j = (i + 1) % n;
|
|
32251
|
+
const near = 1e-6;
|
|
32252
|
+
if (focus.x >= full && Math.abs(g.vx[i] - g.vx[j]) < near && Math.abs(px - g.vx[i]) < near && py >= Math.min(g.vy[i], g.vy[j]) - near && py <= Math.max(g.vy[i], g.vy[j]) + near) onEdge = true;
|
|
32253
|
+
if (focus.y >= full && Math.abs(g.vy[i] - g.vy[j]) < near && Math.abs(py - g.vy[i]) < near && px >= Math.min(g.vx[i], g.vx[j]) - near && px <= Math.max(g.vx[i], g.vx[j]) + near) onEdge = true;
|
|
32254
|
+
}
|
|
32255
|
+
if (!onEdge) return void 0;
|
|
32256
|
+
const fx = Math.min(1, Math.max(0, focus.x));
|
|
32257
|
+
const fy = Math.min(1, Math.max(0, focus.y));
|
|
32258
|
+
for (let m = 0; m <= g.steps; m++) {
|
|
32259
|
+
const along = m === g.steps ? 1 : (m + 0.5) / g.steps;
|
|
32260
|
+
if (insideCopy(g, fx + (1 - fx) * along, px, py, fy + (1 - fy) * along)) return g.steps - m;
|
|
32261
|
+
}
|
|
32262
|
+
return null;
|
|
32263
|
+
}
|
|
32264
|
+
function anisotropicTieStep(g, q, tie, dx, dy, px, py) {
|
|
32265
|
+
const focus = g.anisotropic.focus;
|
|
32266
|
+
const along = (tie + 0.5) / g.steps;
|
|
32267
|
+
const fx = Math.min(1, Math.max(0, focus.x));
|
|
32268
|
+
const fy = Math.min(1, Math.max(0, focus.y));
|
|
32269
|
+
const scaleX = fx + (1 - fx) * along;
|
|
32270
|
+
const scaleY = fy + (1 - fy) * along;
|
|
32271
|
+
const hit = edgeAt(g, scaleX, scaleY, px, py);
|
|
32272
|
+
const half = g.steps - tie - 0.5;
|
|
32273
|
+
if (hit?.kind === "slanted") return half;
|
|
32274
|
+
if (hit === null && Math.abs(q - tie) >= CONTAINMENT_TIE) return half;
|
|
32275
|
+
if (hit === null) return g.steps - tie - (insideCopy(g, scaleX, px, py, scaleY) ? 0 : 1);
|
|
32276
|
+
let odd = g.steps;
|
|
32277
|
+
while (odd % 2 === 0) odd /= 2;
|
|
32278
|
+
const fractional = (2 * tie + 1) % odd !== 0;
|
|
32279
|
+
const vertical = hit.kind === "vertical";
|
|
32280
|
+
if (vertical ? Math.abs(dx) > Math.abs(dy) : Math.abs(dy) > Math.abs(dx)) return g.steps - tie - (fractional ? 0 : 1);
|
|
32281
|
+
const n = g.vx.length;
|
|
32282
|
+
const ex = g.vx[(hit.edge + 1) % n] - g.vx[hit.edge];
|
|
32283
|
+
const ey = g.vy[(hit.edge + 1) % n] - g.vy[hit.edge];
|
|
32284
|
+
if (!(ex > 0 || ex === 0 && ey > 0)) return g.steps - tie - (fractional ? 0 : 1);
|
|
32285
|
+
if (dx * ex + dy * ey >= 0) return g.steps - tie - (fractional && Math.abs(dx) === Math.abs(dy) ? 0 : 1);
|
|
32286
|
+
const ax = g.cx + (g.vx[hit.edge] - g.cx) * scaleX;
|
|
32287
|
+
const ay = g.cy + (g.vy[hit.edge] - g.cy) * scaleY;
|
|
32288
|
+
const u = vertical ? (py - ay) / (ey * scaleY) : (px - ax) / (ex * scaleX);
|
|
32289
|
+
const scaled2 = u * 2 ** 24;
|
|
32290
|
+
const binary = Math.abs(scaled2 - Math.round(scaled2)) < 1e-4;
|
|
32291
|
+
return g.steps - tie - (fractional || !binary ? 0 : 1);
|
|
32292
|
+
}
|
|
32293
|
+
function copiesStepAt(g, px, py, nudge = 0) {
|
|
32294
|
+
const n = g.vx.length;
|
|
32295
|
+
let s = -1;
|
|
32296
|
+
let edge = -1;
|
|
32297
|
+
const dx = px - g.cx;
|
|
32298
|
+
const dy = py - g.cy;
|
|
32299
|
+
for (let i = 0; i < n; i++) {
|
|
32300
|
+
const ax = g.vx[i] - g.cx;
|
|
32301
|
+
const ay = g.vy[i] - g.cy;
|
|
32302
|
+
const ex = g.vx[(i + 1) % n] - g.vx[i];
|
|
32303
|
+
const ey = g.vy[(i + 1) % n] - g.vy[i];
|
|
32304
|
+
const det = ax * ey - ay * ex;
|
|
32305
|
+
if (Math.abs(det) < 1e-12) continue;
|
|
32306
|
+
const alpha = (dx * ey - dy * ex) / det;
|
|
32307
|
+
const beta = (ax * dy - ay * dx) / det;
|
|
32308
|
+
if (alpha < -1e-9 || beta < -1e-9 || beta > alpha + 1e-9 || alpha > 1 + 1e-9) continue;
|
|
32309
|
+
s = alpha;
|
|
32310
|
+
edge = i;
|
|
32311
|
+
}
|
|
32312
|
+
if (g.anisotropic) {
|
|
32313
|
+
const edge2 = s > 1 - 1e-9;
|
|
32314
|
+
const column2 = focusedEdgeStep(g, px, py);
|
|
32315
|
+
if (column2 !== void 0) return column2;
|
|
32316
|
+
const ratio = pathGradientRatio(g.anisotropic, px + nudge, py, { x: px, y: py });
|
|
32317
|
+
if (ratio === null) return null;
|
|
32318
|
+
if (edge2) return Math.max(0, g.steps * (1 - ratio));
|
|
32319
|
+
s = ratio;
|
|
32320
|
+
}
|
|
32321
|
+
if (s < 0) return null;
|
|
32322
|
+
if (g.degenerate && !insideCopy(g, 1, px, py)) return null;
|
|
32323
|
+
if (!g.anisotropic && g.focus === 0 && edge >= 0) {
|
|
32324
|
+
const m2 = floatCopyIndex(g, edge, dx, dy);
|
|
32325
|
+
if (m2 !== null) {
|
|
32326
|
+
if (m2 >= g.steps && !insideCopy(g, 1, px, py)) return null;
|
|
32327
|
+
return g.steps - Math.min(m2, g.steps);
|
|
32328
|
+
}
|
|
32329
|
+
}
|
|
32330
|
+
if (!g.anisotropic && g.focus > 0 && g.focus < 1 && edge >= 0 && !(px === g.cx && py === g.cy)) {
|
|
32331
|
+
const m2 = focusCopyIndex(g, edge, px, py);
|
|
32332
|
+
if (m2 !== null) {
|
|
32333
|
+
if (m2 >= g.steps && !insideCopy(g, 1, px, py)) return null;
|
|
32334
|
+
return g.steps - Math.min(m2, g.steps);
|
|
32335
|
+
}
|
|
32336
|
+
}
|
|
32337
|
+
const f = g.focus;
|
|
32338
|
+
const q = s <= f ? 0 : (s - f) / (1 - f) * g.steps - 0.5;
|
|
32339
|
+
if (q > 0 && Math.abs(q - Math.round(q)) < (g.anisotropic ? STRIP_TIE : TIE)) {
|
|
32340
|
+
const tie = Math.round(q);
|
|
32341
|
+
if (g.anisotropic) return anisotropicTieStep(g, q, tie, dx, dy, px, py);
|
|
32342
|
+
const decided = edge >= 0 ? tieSide(g, edge, dx, dy, tie, f) : null;
|
|
32343
|
+
if (decided !== null) return g.steps - tie - (decided ? 0 : 1);
|
|
32344
|
+
return g.steps - tie - 0.5;
|
|
32345
|
+
}
|
|
32346
|
+
const m = Math.max(0, Math.ceil(q));
|
|
32347
|
+
if (m >= g.steps && !insideCopy(g, 1, px, py)) return null;
|
|
32348
|
+
return g.steps - Math.min(m, g.steps);
|
|
32349
|
+
}
|
|
32350
|
+
|
|
32351
|
+
// src/emf-plus-path-gradient-vertices.ts
|
|
32352
|
+
var FRACTION_BITS = 16;
|
|
32353
|
+
var ONE = 2 ** FRACTION_BITS;
|
|
32354
|
+
var CEIL_EPSILON2 = 1e-9;
|
|
32355
|
+
var snap = (v) => Math.ceil(v * 16 - 1e-9) / 16;
|
|
32356
|
+
function premultiplied2(argb) {
|
|
32357
|
+
const a = argb >>> 24;
|
|
32358
|
+
return [a, (argb >>> 16 & 255) * a / 255, (argb >>> 8 & 255) * a / 255, (argb & 255) * a / 255];
|
|
32359
|
+
}
|
|
32360
|
+
function prepareVertexGradient(shape, full) {
|
|
32361
|
+
const n = shape.boundary.length;
|
|
32362
|
+
if (n < 3 || shape.preset || shape.blend || shape.boundaryArgb.length < n) {
|
|
32363
|
+
return null;
|
|
32364
|
+
}
|
|
32365
|
+
if (shape.boundaryArgb.every((color) => color === shape.boundaryArgb[0])) {
|
|
32366
|
+
return null;
|
|
32367
|
+
}
|
|
32368
|
+
const vx = new Float64Array(n);
|
|
32369
|
+
const vy = new Float64Array(n);
|
|
32370
|
+
const vc = new Float64Array(n * 4);
|
|
32371
|
+
for (let i = 0; i < n; i++) {
|
|
32372
|
+
const p = shape.boundary[i];
|
|
32373
|
+
vx[i] = snap(full[0] * p.x + full[2] * p.y + full[4]);
|
|
32374
|
+
vy[i] = snap(full[1] * p.x + full[3] * p.y + full[5]);
|
|
32375
|
+
vc.set(premultiplied2(shape.boundaryArgb[i]), i * 4);
|
|
32376
|
+
}
|
|
32377
|
+
const c = shape.center;
|
|
32378
|
+
return {
|
|
32379
|
+
cx: snap(full[0] * c.x + full[2] * c.y + full[4]),
|
|
32380
|
+
cy: snap(full[1] * c.x + full[3] * c.y + full[5]),
|
|
32381
|
+
vx,
|
|
32382
|
+
vy,
|
|
32383
|
+
vc,
|
|
32384
|
+
cc: premultiplied2(shape.centerArgb)
|
|
32385
|
+
};
|
|
32386
|
+
}
|
|
32387
|
+
function edgeChannel(ax, ay, bx, by, ca, cb, x, y) {
|
|
32388
|
+
const dx = bx - ax;
|
|
32389
|
+
const dy = by - ay;
|
|
32390
|
+
let t = 0;
|
|
32391
|
+
if (Math.abs(dx) > Math.abs(dy)) {
|
|
32392
|
+
const steps = Math.trunc(Math.abs(dx));
|
|
32393
|
+
if (steps > 0) t = Math.abs(x - Math.floor(ax)) / steps;
|
|
32394
|
+
} else {
|
|
32395
|
+
const steps = Math.trunc(Math.abs(dy));
|
|
32396
|
+
if (steps > 0) t = Math.abs(y - Math.floor(ay)) / steps;
|
|
32397
|
+
}
|
|
32398
|
+
return Math.trunc((ca + (cb - ca) * t) * ONE);
|
|
32399
|
+
}
|
|
32400
|
+
function vertexGradientColorAt(g, px, py) {
|
|
32401
|
+
const n = g.vx.length;
|
|
32402
|
+
let result = null;
|
|
32403
|
+
const tx = [0, 0, 0];
|
|
32404
|
+
const ty = [0, 0, 0];
|
|
32405
|
+
const out = [0, 0, 0, 0];
|
|
32406
|
+
for (let f = 0; f < n; f++) {
|
|
32407
|
+
const f1 = (f + 1) % n;
|
|
32408
|
+
tx[0] = g.cx;
|
|
32409
|
+
tx[1] = g.vx[f];
|
|
32410
|
+
tx[2] = g.vx[f1];
|
|
32411
|
+
ty[0] = g.cy;
|
|
32412
|
+
ty[1] = g.vy[f];
|
|
32413
|
+
ty[2] = g.vy[f1];
|
|
32414
|
+
let left = -1;
|
|
32415
|
+
let right = -1;
|
|
32416
|
+
let xl = Infinity;
|
|
32417
|
+
let xr = -Infinity;
|
|
32418
|
+
for (let i = 0; i < 3; i++) {
|
|
32419
|
+
const j = (i + 1) % 3;
|
|
32420
|
+
const ay = ty[i];
|
|
32421
|
+
const by = ty[j];
|
|
32422
|
+
if (!(ay <= py && by > py || by <= py && ay > py)) continue;
|
|
32423
|
+
const x = tx[i] + (py - ay) / (by - ay) * (tx[j] - tx[i]);
|
|
32424
|
+
if (x < xl) {
|
|
32425
|
+
xl = x;
|
|
32426
|
+
left = i;
|
|
32427
|
+
}
|
|
32428
|
+
if (x > xr) {
|
|
32429
|
+
xr = x;
|
|
32430
|
+
right = i;
|
|
32431
|
+
}
|
|
32432
|
+
}
|
|
32433
|
+
if (left < 0 || right < 0 || left === right) continue;
|
|
32434
|
+
const xs = Math.ceil(xl - CEIL_EPSILON2);
|
|
32435
|
+
const xe = Math.ceil(xr - CEIL_EPSILON2);
|
|
32436
|
+
if (px < xs || px >= xe) continue;
|
|
32437
|
+
const li = left;
|
|
32438
|
+
const lj = (left + 1) % 3;
|
|
32439
|
+
const ri = right;
|
|
32440
|
+
const rj = (right + 1) % 3;
|
|
32441
|
+
for (let q = 0; q < 4; q++) {
|
|
32442
|
+
const colors = [g.cc[q], g.vc[f * 4 + q], g.vc[f1 * 4 + q]];
|
|
32443
|
+
const cL = edgeChannel(tx[li], ty[li], tx[lj], ty[lj], colors[li], colors[lj], xs, py);
|
|
32444
|
+
const cR = edgeChannel(tx[ri], ty[ri], tx[rj], ty[rj], colors[ri], colors[rj], xe, py);
|
|
32445
|
+
const step = Math.floor((cR - cL) / (xe - xs));
|
|
32446
|
+
const v = cL + step * (px - xs);
|
|
32447
|
+
out[q] = Math.max(0, Math.min(255, Math.floor((v + ONE / 2) / ONE)));
|
|
32448
|
+
}
|
|
32449
|
+
const alpha = out[0];
|
|
32450
|
+
if (alpha === 0) {
|
|
32451
|
+
result = 0;
|
|
32452
|
+
continue;
|
|
32453
|
+
}
|
|
32454
|
+
const ch = (premult) => Math.min(255, Math.round(premult * 255 / alpha));
|
|
32455
|
+
result = (alpha << 24 | ch(out[1]) << 16 | ch(out[2]) << 8 | ch(out[3])) >>> 0;
|
|
32456
|
+
}
|
|
32457
|
+
return result;
|
|
32458
|
+
}
|
|
32459
|
+
|
|
31498
32460
|
// src/emf-plus-exact-fill.ts
|
|
31499
32461
|
var IDENTITY4 = [1, 0, 0, 1, 0, 0];
|
|
31500
32462
|
var MAX_EXACT_PIXELS = 16 * 1024 * 1024;
|
|
@@ -31573,17 +32535,110 @@ function pixelAligned(boundary, m) {
|
|
|
31573
32535
|
}
|
|
31574
32536
|
return [x0, y0, x1, y1].every((v) => Math.abs(v - Math.round(v)) < 1e-6);
|
|
31575
32537
|
}
|
|
31576
|
-
|
|
32538
|
+
var TILE_WEIGHT_STEPS = 2048;
|
|
32539
|
+
function tileIndex(i, n, mirror2) {
|
|
32540
|
+
if (!mirror2) {
|
|
32541
|
+
return (i % n + n) % n;
|
|
32542
|
+
}
|
|
32543
|
+
const m = (i % (2 * n) + 2 * n) % (2 * n);
|
|
32544
|
+
return m < n ? m : 2 * n - 1 - m;
|
|
32545
|
+
}
|
|
32546
|
+
function fractionalTileSampler(shape, wrap, full) {
|
|
32547
|
+
if (Math.abs(full[1]) > 1e-9 || Math.abs(full[2]) > 1e-9 || full[0] <= 0 || full[3] <= 0) return null;
|
|
32548
|
+
if (!shape.boundaryArgb.every((color) => color === shape.boundaryArgb[0])) return null;
|
|
32549
|
+
let x0 = Infinity;
|
|
32550
|
+
let y0 = Infinity;
|
|
32551
|
+
let x1 = -Infinity;
|
|
32552
|
+
let y1 = -Infinity;
|
|
32553
|
+
for (const point of shape.boundary) {
|
|
32554
|
+
const x = full[0] * point.x + full[4];
|
|
32555
|
+
const y = full[3] * point.y + full[5];
|
|
32556
|
+
x0 = Math.min(x0, x);
|
|
32557
|
+
y0 = Math.min(y0, y);
|
|
32558
|
+
x1 = Math.max(x1, x);
|
|
32559
|
+
y1 = Math.max(y1, y);
|
|
32560
|
+
}
|
|
32561
|
+
const round = (v) => Math.floor(v + 0.5);
|
|
32562
|
+
const width = round(x1) - round(x0);
|
|
32563
|
+
const height = round(y1) - round(y0);
|
|
32564
|
+
if (!(x1 > x0) || !(y1 > y0) || width < 1 || height < 1 || width * height > 4 * 1024 * 1024) return null;
|
|
32565
|
+
const kx = width / (x1 - x0);
|
|
32566
|
+
const ky = height / (y1 - y0);
|
|
32567
|
+
const toTile = (point) => ({
|
|
32568
|
+
x: (full[0] * point.x + full[4] - x0) * kx,
|
|
32569
|
+
y: (full[3] * point.y + full[5] - y0) * ky
|
|
32570
|
+
});
|
|
32571
|
+
const inner = pathGradientSampler({
|
|
32572
|
+
...shape,
|
|
32573
|
+
boundary: shape.boundary.map(toTile),
|
|
32574
|
+
center: toTile(shape.center),
|
|
32575
|
+
transform: null
|
|
32576
|
+
}, "clamp", IDENTITY4, false);
|
|
32577
|
+
if (!inner) return null;
|
|
32578
|
+
const mirrorX = wrap === "tile-flip-x" || wrap === "tile-flip-xy";
|
|
32579
|
+
const mirrorY = wrap === "tile-flip-y" || wrap === "tile-flip-xy";
|
|
32580
|
+
let texels = null;
|
|
32581
|
+
const texel = () => {
|
|
32582
|
+
if (texels) return texels;
|
|
32583
|
+
const rgba = new Uint8ClampedArray(width * height * 4);
|
|
32584
|
+
inner(0, 0, width, height, rgba);
|
|
32585
|
+
texels = new Float64Array(width * height * 4);
|
|
32586
|
+
for (let i = 0; i < width * height; i++) {
|
|
32587
|
+
const a = rgba[i * 4 + 3];
|
|
32588
|
+
texels[i * 4] = rgba[i * 4] * a / 255;
|
|
32589
|
+
texels[i * 4 + 1] = rgba[i * 4 + 1] * a / 255;
|
|
32590
|
+
texels[i * 4 + 2] = rgba[i * 4 + 2] * a / 255;
|
|
32591
|
+
texels[i * 4 + 3] = a;
|
|
32592
|
+
}
|
|
32593
|
+
return texels;
|
|
32594
|
+
};
|
|
32595
|
+
return (px, py, w, h, out) => {
|
|
32596
|
+
const t = texel();
|
|
32597
|
+
for (let j = 0; j < h; j++) {
|
|
32598
|
+
const v = ky * (py + j - y0);
|
|
32599
|
+
const iv = Math.floor(v);
|
|
32600
|
+
const wy = Math.floor((v - iv) * TILE_WEIGHT_STEPS + 0.5) / TILE_WEIGHT_STEPS;
|
|
32601
|
+
const r0 = tileIndex(iv, height, mirrorY) * width;
|
|
32602
|
+
const r1 = tileIndex(iv + 1, height, mirrorY) * width;
|
|
32603
|
+
for (let i = 0; i < w; i++) {
|
|
32604
|
+
const u = kx * (px + i - x0);
|
|
32605
|
+
const iu = Math.floor(u);
|
|
32606
|
+
const wx = Math.floor((u - iu) * TILE_WEIGHT_STEPS + 0.5) / TILE_WEIGHT_STEPS;
|
|
32607
|
+
const c0 = tileIndex(iu, width, mirrorX);
|
|
32608
|
+
const c1 = tileIndex(iu + 1, width, mirrorX);
|
|
32609
|
+
const o = (j * w + i) * 4;
|
|
32610
|
+
const sample2 = (k) => (1 - wx) * (1 - wy) * t[(r0 + c0) * 4 + k] + wx * (1 - wy) * t[(r0 + c1) * 4 + k] + (1 - wx) * wy * t[(r1 + c0) * 4 + k] + wx * wy * t[(r1 + c1) * 4 + k];
|
|
32611
|
+
const coverage = sample2(3);
|
|
32612
|
+
const alpha = Math.floor(coverage + 0.5);
|
|
32613
|
+
if (alpha <= 0) {
|
|
32614
|
+
out[o] = out[o + 1] = out[o + 2] = out[o + 3] = 0;
|
|
32615
|
+
continue;
|
|
32616
|
+
}
|
|
32617
|
+
const scale = coverage >= 255 ? 1 : 255 / coverage;
|
|
32618
|
+
out[o] = Math.min(255, Math.floor(sample2(0) * scale + 0.5));
|
|
32619
|
+
out[o + 1] = Math.min(255, Math.floor(sample2(1) * scale + 0.5));
|
|
32620
|
+
out[o + 2] = Math.min(255, Math.floor(sample2(2) * scale + 0.5));
|
|
32621
|
+
out[o + 3] = alpha;
|
|
32622
|
+
}
|
|
32623
|
+
}
|
|
32624
|
+
};
|
|
32625
|
+
}
|
|
32626
|
+
function pathGradientSampler(shape, wrap, device, strictOutside = true) {
|
|
31577
32627
|
const box = boundaryBox2(shape.boundary);
|
|
31578
32628
|
const full = mulMatrix(device, shape.transform ?? IDENTITY4);
|
|
31579
32629
|
const inv2 = invertAffine(full);
|
|
31580
32630
|
if (!box || !inv2) {
|
|
31581
32631
|
return null;
|
|
31582
32632
|
}
|
|
31583
|
-
|
|
32633
|
+
if (wrap !== "clamp" && !pixelAligned(shape.boundary, full)) {
|
|
32634
|
+
const tiled = fractionalTileSampler(shape, wrap, full);
|
|
32635
|
+
if (tiled) return tiled;
|
|
32636
|
+
}
|
|
31584
32637
|
const uniformSurround = shape.boundaryArgb.every((color) => color === shape.boundaryArgb[0]);
|
|
31585
|
-
const smooth = !uniformSurround && !shape.preset ||
|
|
32638
|
+
const smooth = !uniformSurround && !shape.preset || wrap !== "clamp" && !pixelAligned(shape.boundary, full);
|
|
31586
32639
|
const quantum = smooth ? 0 : pathGradientQuantum(shape.boundary, full);
|
|
32640
|
+
const vertexGradient = wrap === "clamp" || pixelAligned(shape.boundary, full) ? prepareVertexGradient(shape, full) : null;
|
|
32641
|
+
const copies = quantum > 0 ? prepareCopies(shape, full, quantum) : null;
|
|
31587
32642
|
const pxX = Math.hypot(full[0], full[1]);
|
|
31588
32643
|
const pxY = Math.hypot(full[2], full[3]);
|
|
31589
32644
|
const lagX = pxX > 0 ? 1 / pxX : 0;
|
|
@@ -31604,7 +32659,25 @@ function pathGradientSampler(shape, wrap, device) {
|
|
|
31604
32659
|
}
|
|
31605
32660
|
if (wrap === "clamp" && by >= box.y + box.h) continue;
|
|
31606
32661
|
const focusPoint = bias ? { x: bx - inv2[0] * bias, y: by - inv2[1] * bias } : void 0;
|
|
31607
|
-
|
|
32662
|
+
let c = null;
|
|
32663
|
+
let decided = false;
|
|
32664
|
+
if (vertexGradient || copies) {
|
|
32665
|
+
const fx = wrap === "clamp" ? x0 + i : full[0] * bx + full[2] * by + full[4];
|
|
32666
|
+
const fy = wrap === "clamp" ? dy : full[1] * bx + full[3] * by + full[5];
|
|
32667
|
+
const rx = Math.round(fx);
|
|
32668
|
+
const ry = Math.round(fy);
|
|
32669
|
+
if (Math.abs(fx - rx) < 1e-6 && Math.abs(fy - ry) < 1e-6) {
|
|
32670
|
+
if (vertexGradient) {
|
|
32671
|
+
c = vertexGradientColorAt(vertexGradient, rx, ry);
|
|
32672
|
+
if (c === null && strictOutside) decided = true;
|
|
32673
|
+
} else if (copies) {
|
|
32674
|
+
const step = copiesStepAt(copies, rx, ry, bias);
|
|
32675
|
+
if (step !== null) c = pathGradientStepColor(shape, step, quantum);
|
|
32676
|
+
else if (strictOutside && !copies.anisotropic) decided = true;
|
|
32677
|
+
}
|
|
32678
|
+
}
|
|
32679
|
+
}
|
|
32680
|
+
if (c === null && !decided) c = pathGradientColorAt(shape, bx, by, focusPoint, quantum);
|
|
31608
32681
|
if (c === null) {
|
|
31609
32682
|
continue;
|
|
31610
32683
|
}
|
|
@@ -32205,6 +33278,23 @@ function handleLineTo(rCtx, dataOff, recSize) {
|
|
|
32205
33278
|
}
|
|
32206
33279
|
return true;
|
|
32207
33280
|
}
|
|
33281
|
+
function cosmeticRectangleBox(rCtx, box) {
|
|
33282
|
+
const { state } = rCtx;
|
|
33283
|
+
if (rCtx.inPath || state.penStyle === 5 || state.penStyle === 6 || box.exy !== 0 || box.eyx !== 0 || box.exx === 0 || box.eyy === 0 || !penIsCosmetic(rCtx)) {
|
|
33284
|
+
return box;
|
|
33285
|
+
}
|
|
33286
|
+
const ax = Math.ceil(box.ax / 16) * 16;
|
|
33287
|
+
const ay = Math.ceil(box.ay / 16) * 16;
|
|
33288
|
+
return { ...box, ax, ay, exx: Math.ceil((box.ax + box.exx) / 16) * 16 - ax, eyy: Math.ceil((box.ay + box.eyy) / 16) * 16 - ay };
|
|
33289
|
+
}
|
|
33290
|
+
function devicePositiveBox(box) {
|
|
33291
|
+
if (!isAxisBox(box) || box.exx >= 0 && box.eyy >= 0) {
|
|
33292
|
+
return box;
|
|
33293
|
+
}
|
|
33294
|
+
const ax = box.exx < 0 ? box.ax + box.exx : box.ax;
|
|
33295
|
+
const ay = box.eyy < 0 ? box.ay + box.eyy : box.ay;
|
|
33296
|
+
return { ...box, ax, ay, exx: Math.abs(box.exx), eyy: Math.abs(box.eyy) };
|
|
33297
|
+
}
|
|
32208
33298
|
function handleRectangle(rCtx, dataOff, recSize) {
|
|
32209
33299
|
const { ctx, view, state, inPath } = rCtx;
|
|
32210
33300
|
if (recSize >= 24) {
|
|
@@ -32212,7 +33302,7 @@ function handleRectangle(rCtx, dataOff, recSize) {
|
|
|
32212
33302
|
const t = view.getInt32(dataOff + 4, true);
|
|
32213
33303
|
const r = view.getInt32(dataOff + 8, true);
|
|
32214
33304
|
const b = view.getInt32(dataOff + 12, true);
|
|
32215
|
-
const unframed = uprightFixBox(rCtx, l, t, r, b);
|
|
33305
|
+
const unframed = cosmeticRectangleBox(rCtx, uprightFixBox(rCtx, l, t, r, b));
|
|
32216
33306
|
const inset = insideFrameInset(rCtx, unframed, true, rCtx.state.arcDirection === 2);
|
|
32217
33307
|
const box = inset ? insetFixBox(unframed, inset) : unframed;
|
|
32218
33308
|
const clockwise = rCtx.state.arcDirection === 2;
|
|
@@ -32267,7 +33357,7 @@ function handleRectangle(rCtx, dataOff, recSize) {
|
|
|
32267
33357
|
c.beginPath();
|
|
32268
33358
|
c.rect(x, y, w, h);
|
|
32269
33359
|
},
|
|
32270
|
-
raster: () => rectRasterPath(box, clockwise),
|
|
33360
|
+
raster: () => rectRasterPath(devicePositiveBox(box), clockwise),
|
|
32271
33361
|
rectangle: true,
|
|
32272
33362
|
fill: true,
|
|
32273
33363
|
stroke: true,
|
|
@@ -32377,7 +33467,7 @@ function handleRoundRect(rCtx, dataOff, recSize) {
|
|
|
32377
33467
|
const devM = gdiDeviceMatrix(rCtx);
|
|
32378
33468
|
const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
|
|
32379
33469
|
const cornerFixH = inset ? Math.abs(cornerH * devM[3]) * 16 : fixExtent(rCtx, cornerH, 1);
|
|
32380
|
-
const cornerOnFrame = (
|
|
33470
|
+
const cornerOnFrame = (fix2, size, framedSize) => inset && size !== 0 ? Math.floor(Math.min(fix2, size) * framedSize / size) : fix2;
|
|
32381
33471
|
let cw = cornerOnFrame(cornerFixW, Math.abs((r - l) * devM[0]) * 16, Math.abs(framed.exx));
|
|
32382
33472
|
let ch = cornerOnFrame(cornerFixH, Math.abs((b - t) * devM[3]) * 16, Math.abs(framed.eyy));
|
|
32383
33473
|
const drawBox = inset ? framed : curvedFixBox(rCtx, l, t, r, b, true);
|
|
@@ -32441,18 +33531,21 @@ function curvedFixBox(rCtx, l, t, r, b, upright = false) {
|
|
|
32441
33531
|
return box;
|
|
32442
33532
|
}
|
|
32443
33533
|
const m = gdiDeviceMatrix(rCtx);
|
|
32444
|
-
if (
|
|
33534
|
+
if (m[1] !== 0 || m[2] !== 0) {
|
|
32445
33535
|
return box;
|
|
32446
33536
|
}
|
|
33537
|
+
const whole = box.ax % 16 === 0 && box.ay % 16 === 0 && box.exx % 16 === 0 && box.eyy % 16 === 0;
|
|
33538
|
+
const gx = whole ? 4 : 0;
|
|
33539
|
+
const gy = gx;
|
|
32447
33540
|
const sx = box.exx < 0 ? -1 : 1;
|
|
32448
33541
|
const sy = box.eyy < 0 ? -1 : 1;
|
|
32449
33542
|
return {
|
|
32450
|
-
ax: box.ax -
|
|
32451
|
-
ay: box.ay -
|
|
32452
|
-
exx: box.exx +
|
|
33543
|
+
ax: box.ax - gx * sx,
|
|
33544
|
+
ay: box.ay - gy * sy,
|
|
33545
|
+
exx: box.exx + 2 * gx * sx,
|
|
32453
33546
|
exy: 0,
|
|
32454
33547
|
eyx: 0,
|
|
32455
|
-
eyy: box.eyy +
|
|
33548
|
+
eyy: box.eyy + 2 * gy * sy
|
|
32456
33549
|
};
|
|
32457
33550
|
}
|
|
32458
33551
|
function handleEllipse(rCtx, dataOff, recSize) {
|
|
@@ -32548,34 +33641,41 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
|
|
|
32548
33641
|
}
|
|
32549
33642
|
};
|
|
32550
33643
|
const kind = isArcTo ? "arcto" : recType === EMR_PIE ? "pie" : recType === EMR_CHORD ? "chord" : "arc";
|
|
33644
|
+
const radialOnBox = (box, x, y) => {
|
|
33645
|
+
const wl = r - l;
|
|
33646
|
+
const hl = b - t;
|
|
33647
|
+
if (wl === 0 || hl === 0) {
|
|
33648
|
+
return fixPoint(rCtx, x, y);
|
|
33649
|
+
}
|
|
33650
|
+
const u = (x - l) / wl;
|
|
33651
|
+
const v = (y - t) / hl;
|
|
33652
|
+
return [box.ax + box.exx * u + box.eyx * v, box.ay + box.exy * u + box.eyy * v];
|
|
33653
|
+
};
|
|
32551
33654
|
const devM = gdiDeviceMatrix(rCtx);
|
|
32552
|
-
const
|
|
32553
|
-
const
|
|
32554
|
-
|
|
32555
|
-
|
|
32556
|
-
|
|
32557
|
-
const [
|
|
32558
|
-
|
|
32559
|
-
|
|
32560
|
-
|
|
32561
|
-
|
|
32562
|
-
|
|
33655
|
+
const mapFlips = devM[0] * devM[3] - devM[1] * devM[2] < 0;
|
|
33656
|
+
const axisMap2 = devM[1] === 0 && devM[2] === 0;
|
|
33657
|
+
const rasterArgs = (immediate = false) => {
|
|
33658
|
+
const box = inset ? framed : immediate && needsFill ? curvedFixBox(rCtx, l, t, r, b) : unframed;
|
|
33659
|
+
const boxFlips = box.exx * box.eyy - box.exy * box.eyx < 0;
|
|
33660
|
+
const mirror2 = axisMap2 && isAxisBox(box) ? { x: devM[0] < 0, y: devM[3] < 0 } : void 0;
|
|
33661
|
+
return {
|
|
33662
|
+
box,
|
|
33663
|
+
mirror: mirror2,
|
|
33664
|
+
clockwise: mirror2 ? clockwise : clockwise !== (mapFlips !== boxFlips),
|
|
33665
|
+
s: radialOnBox(box, startX, startY),
|
|
33666
|
+
// Device FIX rounding can separate distinct radial points on the
|
|
33667
|
+
// same logical ray. Preserve their proven endpoint identity.
|
|
33668
|
+
e: fullEllipse ? radialOnBox(box, startX, startY) : radialOnBox(box, endX, endY),
|
|
33669
|
+
from: currentFix(rCtx)
|
|
33670
|
+
};
|
|
32563
33671
|
};
|
|
32564
|
-
const rasterArgs = (immediate = false) => ({
|
|
32565
|
-
box: inset ? framed : immediate && needsFill ? curvedFixBox(rCtx, l, t, r, b) : unframed,
|
|
32566
|
-
s: radialOnBox(fixPoint(rCtx, startX, startY), rawFix(startX, startY)),
|
|
32567
|
-
// Device FIX rounding can separate distinct radial points on the
|
|
32568
|
-
// same logical ray. Preserve their proven endpoint identity.
|
|
32569
|
-
e: fullEllipse ? radialOnBox(fixPoint(rCtx, startX, startY), rawFix(startX, startY)) : radialOnBox(fixPoint(rCtx, endX, endY), rawFix(endX, endY)),
|
|
32570
|
-
from: currentFix(rCtx)
|
|
32571
|
-
});
|
|
32572
33672
|
if (inPath) {
|
|
32573
33673
|
if (isArcTo) {
|
|
32574
33674
|
continueFigure(rCtx);
|
|
32575
33675
|
}
|
|
32576
33676
|
build(gdiPathRecorder(rCtx));
|
|
32577
33677
|
const a = rasterArgs();
|
|
32578
|
-
arcRasterPath(a.box, a.s, a.e, clockwise, kind, a.from, rasterPathOf(rCtx));
|
|
33678
|
+
arcRasterPath(a.box, a.s, a.e, a.clockwise, kind, a.from, rasterPathOf(rCtx), a.mirror);
|
|
32579
33679
|
if (needsFill) {
|
|
32580
33680
|
rasterPathOf(rCtx).closeFigure();
|
|
32581
33681
|
}
|
|
@@ -32589,7 +33689,7 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
|
|
|
32589
33689
|
},
|
|
32590
33690
|
raster: () => {
|
|
32591
33691
|
const a = rasterArgs(true);
|
|
32592
|
-
return arcRasterPath(a.box, a.s, a.e, clockwise, kind, a.from).path;
|
|
33692
|
+
return arcRasterPath(a.box, a.s, a.e, a.clockwise, kind, a.from, void 0, a.mirror).path;
|
|
32593
33693
|
},
|
|
32594
33694
|
fill: needsFill,
|
|
32595
33695
|
stroke: true
|
|
@@ -32597,7 +33697,7 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
|
|
|
32597
33697
|
}
|
|
32598
33698
|
if (isArcTo) {
|
|
32599
33699
|
const a = rasterArgs();
|
|
32600
|
-
const end = arcRasterPath(a.box, a.s, a.e, clockwise, "arc").end;
|
|
33700
|
+
const end = arcRasterPath(a.box, a.s, a.e, a.clockwise, "arc", void 0, void 0, a.mirror).end;
|
|
32601
33701
|
const dx = Math.floor(end[0] / 16);
|
|
32602
33702
|
const dy = Math.floor(end[1] / 16);
|
|
32603
33703
|
const inv2 = invertAffine(gdiDeviceMatrix(rCtx));
|
|
@@ -32719,6 +33819,21 @@ function handleEmfGdiShapeRecord(rCtx, recType, dataOff, recSize) {
|
|
|
32719
33819
|
}
|
|
32720
33820
|
}
|
|
32721
33821
|
|
|
33822
|
+
// src/emf-gdi-chroma-tie-data.ts
|
|
33823
|
+
var CHROMA_TIE_FLIPS = {
|
|
33824
|
+
"40,0": [374, 506, 1076, 1078, 1142, 1526, 1910, 2294, 2678, 3446, 5750, 5806, 5818, 5830, 5842, 5854, 5866, 5902, 5938, 6324, 7256, 7484, 7868, 8636, 8792, 8996, 9020, 9404, 9788, 10556, 11904, 12112, 12136, 12160, 12172, 12184, 12208, 12220, 12244, 12256, 12268, 12666, 13190, 13598, 15338, 18246, 18540, 18750, 19940, 21272, 21476, 21680, 21759, 21884, 24100, 24882, 27364, 27614, 28022, 30442, 30534, 30900, 31062, 32478, 32482, 33673, 36394, 36984, 37242, 37404, 40380, 41256, 41541, 42688, 42736, 42784, 43188, 46651, 48193, 49126, 49530, 49668, 50268, 53877, 54849, 55404, 55476, 58319, 61818, 62257, 66538, 67026, 67236, 67398, 67716, 69373, 71370, 73392, 73872, 77949, 78325, 79054, 80143, 80400, 85086, 85632, 86184, 86370, 86394, 88496, 91974, 98682, 98820, 98868, 99054, 102841, 104262, 104628, 110970, 111628, 115656, 116574, 116916, 119216, 119334, 119968, 123396, 127812, 128579, 129366, 129493, 129738, 134784, 134878, 140880, 142861, 143671, 146590, 147484, 150855, 151211, 153414, 153922, 154543, 155567, 157776, 159826, 160168, 160910, 162313, 165787, 166068, 169642, 171408, 171882, 172510, 174117, 174926, 176025, 176170, 176928, 177636, 177718, 177990, 178356, 181268, 184330, 184354, 184390, 184402, 184414, 184426, 184438, 184462, 184498, 184514, 185282, 185666, 186434, 186818, 188354, 189491, 190278, 190672, 190696, 190732, 190756, 190768, 190804, 190840, 191624, 192776, 193160, 193952, 194615, 194782, 194948, 195080, 195464, 195848, 196010],
|
|
33825
|
+
"40,20": [1345, 13655, 16768, 19051, 22461, 23888, 29071, 34630, 40955, 41856, 43128, 47160, 47377, 47934, 47976, 48106, 48607, 49476, 59008, 59116, 59372, 65851, 69045, 69721, 71741, 74531, 85884, 89225, 89899, 91692, 93843, 94915, 95071, 95968, 97561, 100356, 101005, 102444, 109699, 116446, 117163, 118538, 119501, 133219, 136360, 137042, 137929, 138173, 143164, 145012, 145555, 146068, 156036, 158160, 160630, 161047, 174146, 175587, 176339, 177137],
|
|
33826
|
+
"50,20": [3435, 4690, 7934, 11527, 21838, 22211, 24980, 32745, 35495, 36570, 38851, 41578, 43128, 49195, 57142, 72649, 73084, 81747, 89022, 89826, 93145, 94307, 96679, 99174, 99185, 102486, 103896, 109861, 110110, 112698, 116081, 130842, 133613, 137784, 139643, 142939, 143358, 143734, 143834, 152125, 158072, 170378, 170422, 174146, 175547, 177966, 180424, 182339, 190180, 192424, 196256],
|
|
33827
|
+
"-40,0": [5816, 9911, 17137, 17332, 18078, 19903, 25108, 39517, 46996, 54208, 54890, 55254, 59753, 61616, 73287, 73927, 77843, 90139, 93011, 94263, 96552, 99873, 104370, 115822, 116256, 119156, 122178, 125065, 125455, 127853, 133264, 133614, 136585, 141275, 148914, 149785, 153213, 156483, 167561, 171079, 171826, 183498, 184714, 185541, 186397, 190359, 194533],
|
|
33828
|
+
"100,0": [458, 506, 543, 845, 1142, 1274, 1526, 2294, 5074, 5750, 5782, 5806, 5818, 5830, 5854, 5866, 5902, 5926, 5938, 6800, 7100, 7256, 7484, 7616, 7868, 8384, 8636, 8792, 8996, 9020, 9152, 9404, 10328, 10556, 11324, 11416, 11904, 12092, 12112, 12136, 12160, 12184, 12208, 12244, 12256, 12268, 12546, 13142, 13370, 13502, 13598, 14522, 15338, 16670, 17320, 18246, 19484, 19712, 19940, 20864, 21068, 21272, 21476, 21680, 21884, 23710, 24882, 25615, 25874, 26054, 26282, 27002, 27206, 27614, 28022, 30004, 30442, 30780, 30883, 31062, 31176, 31224, 31434, 33073, 36480, 36984, 37122, 37242, 37404, 37566, 37776, 39326, 39686, 40862, 42346, 42688, 42784, 43746, 43908, 45308, 45543, 45668, 46232, 46959, 48210, 48250, 48322, 48380, 49030, 49078, 49126, 49248, 49530, 49668, 50088, 52485, 54592, 54688, 55030, 55343, 55404, 55476, 55590, 56010, 58009, 59324, 59888, 60522, 60592, 60628, 60894, 60934, 60958, 61372, 61746, 61932, 62118, 62352, 62617, 66410, 66970, 67276, 67324, 67348, 67398, 67716, 67902, 68088, 68274, 68460, 73240, 73340, 73618, 73666, 73690, 73872, 74430, 75097, 77750, 79094, 79618, 79686, 80052, 80400, 80690, 81053, 84630, 85308, 85632, 86184, 86370, 86394, 86742, 86928, 89565, 91974, 92478, 92526, 92898, 93084, 97548, 97782, 98610, 98682, 98820, 98868, 99426, 99612, 100368, 103704, 104124, 104262, 104628, 104952, 105162, 105210, 105396, 105768, 106117, 107011, 110614, 110686, 110712, 110970, 111040, 111294, 111504, 111738, 111924, 112828, 113676, 114388, 115341, 115393, 116574, 116916, 116956, 116992, 117636, 117846, 122298, 122464, 122968, 123266, 123298, 123334, 123650, 123724, 123978, 124188, 125029, 125924, 128054, 128514, 129238, 129262, 129286, 129310, 129366, 129640, 129712, 130196, 134784, 136054, 136080, 136538, 137182, 141253, 141946, 142018, 142292, 142396, 143060, 143828, 145207, 145667, 145693, 146155, 147484, 147922, 148226, 148264, 148288, 148312, 148392, 148634, 148738, 149402, 152235, 153414, 153874, 153922, 154264, 154568, 155106, 155744, 156104, 156308, 156512, 156716, 156858, 158768, 159360, 159826, 160168, 160216, 160264, 160606, 160910, 161020, 162086, 162242, 162398, 162446, 162650, 165540, 166068, 166168, 166558, 167252, 168584, 171720, 171882, 172510, 172948, 174926, 175538, 176306, 177852, 177990, 178356, 181064, 181268, 181676, 181997, 182648, 183008, 183936, 184330, 184354, 184390, 184402, 184414, 184438, 184462, 184514, 185194, 185282, 185632, 185666, 186434, 188354, 189758, 189890, 190278, 190410, 190672, 190684, 190696, 190732, 190768, 190804, 190816, 190840, 191624, 191926, 192776, 193160, 193802, 193952, 195080, 195165, 195332, 195464, 195692, 195848],
|
|
33829
|
+
"-100,0": [8492, 8494, 18577, 69397, 74091, 76386, 76390, 120219, 122518, 127206, 127210, 173433, 182718, 188113, 188115, 188117],
|
|
33830
|
+
"20,0": [374, 758, 1142, 1526, 2294, 2678, 4598, 5782, 5806, 5818, 5830, 5842, 5878, 5926, 5938, 6857, 7100, 7256, 7484, 7868, 8144, 8636, 9020, 9404, 10556, 11324, 11904, 12092, 12112, 12136, 12160, 12184, 12208, 12232, 12244, 12256, 12268, 12408, 15256, 15338, 16012, 19736, 22402, 24192, 24490, 24720, 30900, 31062, 33949, 36540, 37242, 43461, 45209, 45343, 47763, 49530, 50829, 51159, 52932, 54027, 54376, 55056, 55110, 55476, 59280, 59784, 60294, 61056, 61170, 65557, 65771, 67398, 71574, 73872, 78008, 79686, 80052, 83615, 86184, 86370, 88236, 88957, 90159, 90896, 90972, 91188, 92340, 92657, 93560, 94764, 95047, 95257, 95760, 98682, 98796, 102636, 103746, 104262, 104628, 108240, 110418, 110970, 113753, 116916, 121939, 122283, 122285, 123481, 126166, 126786, 127848, 128811, 129546, 133194, 137205, 139249, 140100, 140104, 143450, 143585, 144257, 148826, 153414, 157182, 159486, 160495, 160975, 161749, 164341, 166068, 166168, 168189, 169944, 171030, 171630, 173895, 175302, 175860, 176838, 178356, 184104, 184330, 184342, 184354, 184366, 184390, 184402, 184414, 184426, 184438, 184462, 184474, 184486, 184514, 185282, 185666, 185765, 187202, 188354, 188776, 190038, 190672, 190696, 190732, 190768, 190792, 190804, 190816, 190840, 191302, 191624, 192392, 192776, 193160, 194369, 194696, 195003, 195464, 195848],
|
|
33831
|
+
"70,0": [254, 458, 1142, 1274, 1526, 2246, 2294, 2348, 2450, 2654, 2858, 3062, 4598, 5750, 5782, 5806, 5830, 5842, 5854, 5866, 5902, 5926, 5938, 6300, 7100, 7256, 7484, 7616, 7868, 8384, 8636, 8792, 8996, 9020, 9404, 9470, 9497, 9788, 10328, 10556, 11021, 11324, 11416, 11904, 12092, 12112, 12136, 12184, 12244, 12256, 12268, 12546, 13370, 13598, 15134, 15338, 16670, 18540, 19532, 19712, 19940, 21068, 21272, 21476, 21884, 24192, 24720, 24841, 26282, 27410, 27614, 28180, 29026, 30004, 30442, 30534, 30900, 31062, 31224, 31434, 34160, 35373, 36480, 36984, 37242, 37404, 37566, 39890, 42688, 42784, 46640, 48380, 49030, 49078, 49126, 49248, 49530, 49668, 50088, 50659, 54592, 54664, 54688, 55476, 55590, 56010, 60766, 60958, 60982, 61372, 61560, 61746, 61932, 62617, 65226, 67348, 67398, 67716, 68088, 68274, 69492, 69557, 70194, 73107, 73578, 73714, 74244, 75841, 76888, 79686, 80400, 83650, 84127, 84200, 86184, 86370, 86394, 86742, 86845, 86928, 88496, 90155, 90522, 90549, 91974, 92478, 92526, 92898, 93084, 94736, 95937, 96873, 97782, 98682, 98820, 98868, 103659, 104262, 104628, 104952, 105162, 105210, 105396, 107075, 108234, 110686, 110712, 110970, 111294, 111504, 111628, 111738, 116332, 116574, 116916, 116992, 117636, 121933, 122621, 122968, 123024, 123334, 123396, 127016, 127044, 129262, 129286, 129310, 129366, 129712, 134394, 134784, 136054, 136080, 140378, 142018, 142292, 144762, 145335, 145710, 147484, 147922, 148226, 148312, 148392, 150262, 153414, 153874, 153922, 154568, 155744, 159360, 159826, 160168, 160216, 160264, 160606, 160910, 161076, 162242, 162446, 162650, 163690, 164494, 166068, 166168, 166558, 166606, 167252, 167848, 168584, 170886, 171648, 171882, 172510, 172948, 174722, 174926, 176306, 177852, 177990, 178356, 181064, 181268, 183008, 184330, 184354, 184390, 184402, 184414, 184426, 184438, 184462, 184498, 184514, 185194, 185282, 185632, 185666, 185714, 186434, 187202, 189033, 189051, 189758, 189890, 190278, 190672, 190696, 190732, 190792, 190804, 190816, 190840, 191624, 192776, 193160, 193952, 195464, 195563, 195692, 195848],
|
|
33832
|
+
"0,30": [1721, 4912, 17621, 23134, 24625, 24929, 33960, 36358, 38321, 38379, 40933, 42823, 43299, 45130, 45943, 49299, 52890, 53885, 57288, 57436, 59699, 61699, 64420, 65176, 65236, 72099, 72211, 72381, 83500, 85501, 88189, 89169, 92103, 93701, 95610, 95681, 108288, 108606, 114622, 117231, 119626, 123617, 127534, 133819, 136508, 136984, 139544, 143792, 145778, 147469, 149239, 153446, 153562, 154152, 159126, 166024, 175800, 176759, 180377, 181528, 182453, 183108, 192812],
|
|
33833
|
+
"0,-50": [1993, 2566, 7118, 7355, 11339, 12468, 15355, 19766, 19939, 26761, 31589, 32405, 35291, 38652, 41997, 50880, 52335, 53022, 53093, 55240, 72257, 72491, 75259, 75267, 80408, 83070, 83658, 83938, 85802, 86633, 90942, 99179, 101706, 102357, 106183, 108569, 117985, 120676, 140059, 141222, 143338, 147505, 147553, 150898, 152640, 156175, 156373, 156839, 158346, 159040, 163988, 171036, 176002, 179175, 179438, 192876, 194345, 194768, 194848],
|
|
33834
|
+
"0,60": [2079, 10520, 24043, 34818, 38212, 39257, 41632, 41905, 48383, 50923, 58894, 59675, 61206, 64816, 65028, 66919, 71898, 77171, 77667, 82511, 82591, 90280, 94741, 98446, 99892, 99982, 103615, 105816, 111088, 115141, 115170, 126478, 127086, 129937, 130463, 131475, 133798, 134795, 134807, 136638, 138053, 139328, 140657, 143569, 145200, 146837, 147691, 147766, 149712, 151474, 168315, 171698, 173961, 177231, 182638, 184786, 185640, 188116, 192273, 196154]
|
|
33835
|
+
};
|
|
33836
|
+
|
|
32722
33837
|
// src/emf-gdi-illuminant-data.ts
|
|
32723
33838
|
var ILLUMINANT_CUBE_DATA = {
|
|
32724
33839
|
1: "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",
|
|
@@ -32900,7 +34015,33 @@ function adjustChroma(r, g, b, scale, angle) {
|
|
|
32900
34015
|
}
|
|
32901
34016
|
return out;
|
|
32902
34017
|
}
|
|
32903
|
-
|
|
34018
|
+
var chromaTieTables = /* @__PURE__ */ new Map();
|
|
34019
|
+
function chromaTieTable(ca) {
|
|
34020
|
+
if (ca.illuminant !== 0 && ca.illuminant !== 6) return null;
|
|
34021
|
+
const key = `${ca.colorfulness},${ca.redGreenTint}`;
|
|
34022
|
+
let table2 = chromaTieTables.get(key);
|
|
34023
|
+
if (table2 === void 0) {
|
|
34024
|
+
const flips = CHROMA_TIE_FLIPS[key];
|
|
34025
|
+
table2 = null;
|
|
34026
|
+
if (flips) {
|
|
34027
|
+
table2 = new Int8Array(32768 * 3);
|
|
34028
|
+
for (const f of flips) table2[f >> 1] = f & 1 ? 1 : -1;
|
|
34029
|
+
}
|
|
34030
|
+
chromaTieTables.set(key, table2);
|
|
34031
|
+
}
|
|
34032
|
+
return table2;
|
|
34033
|
+
}
|
|
34034
|
+
function paletteEntry(v) {
|
|
34035
|
+
const n = Math.round(v * 31 / 255);
|
|
34036
|
+
return PALETTE[n] === v ? n : -1;
|
|
34037
|
+
}
|
|
34038
|
+
function tieIndex(c) {
|
|
34039
|
+
const r = paletteEntry(c[0]);
|
|
34040
|
+
const g = paletteEntry(c[1]);
|
|
34041
|
+
const b = paletteEntry(c[2]);
|
|
34042
|
+
return r < 0 || g < 0 || b < 0 ? -1 : (r * 32 + g) * 32 + b;
|
|
34043
|
+
}
|
|
34044
|
+
function colorAdjustmentMapper(ca, options2) {
|
|
32904
34045
|
const illuminant = illuminantCube(ca.illuminant);
|
|
32905
34046
|
const matrix = ILLUMINANT_MATRICES[ca.illuminant];
|
|
32906
34047
|
const gammas = [ca.redGamma / 1e4, ca.greenGamma / 1e4, ca.blueGamma / 1e4];
|
|
@@ -32913,6 +34054,7 @@ function colorAdjustmentMapper(ca) {
|
|
|
32913
34054
|
const angle = TINT_RADIANS * ca.redGreenTint / 100;
|
|
32914
34055
|
const log = (ca.flags & CA_LOG_FILTER) !== 0;
|
|
32915
34056
|
const negative = (ca.flags & CA_NEGATIVE) !== 0;
|
|
34057
|
+
const ties = chroma && options2?.chromaTies !== false ? chromaTieTable(ca) : null;
|
|
32916
34058
|
const curve = (value, channel) => {
|
|
32917
34059
|
let v = 255 * (clamp255(value) / 255) ** gammas[channel];
|
|
32918
34060
|
v = (v - black) / span * 255;
|
|
@@ -32932,6 +34074,7 @@ function colorAdjustmentMapper(ca) {
|
|
|
32932
34074
|
return (rgb2) => {
|
|
32933
34075
|
let c = [rgb2 >> 16 & 255, rgb2 >> 8 & 255, rgb2 & 255];
|
|
32934
34076
|
if (chroma) {
|
|
34077
|
+
const tie = ties ? tieIndex(c) : -1;
|
|
32935
34078
|
c = c.map(exactPaletteLevel);
|
|
32936
34079
|
if (matrix) {
|
|
32937
34080
|
const [r, g, b] = c;
|
|
@@ -32939,6 +34082,7 @@ function colorAdjustmentMapper(ca) {
|
|
|
32939
34082
|
}
|
|
32940
34083
|
c = adjustChroma(c[0], c[1], c[2], scale, angle);
|
|
32941
34084
|
c = c.map(roundHalfUp);
|
|
34085
|
+
if (ties && tie >= 0) c = c.map((v, k) => v + ties[tie * 3 + k]);
|
|
32942
34086
|
} else if (illuminant) {
|
|
32943
34087
|
const mapped = lookupIlluminant(illuminant, c[0] / 255, c[1] / 255, c[2] / 255);
|
|
32944
34088
|
c = [mapped[0] * 255, mapped[1] * 255, mapped[2] * 255];
|
|
@@ -33022,6 +34166,50 @@ function ditherQuantize(v, threshold) {
|
|
|
33022
34166
|
return paletteLevel(n < 0 ? 0 : n > 31 ? 31 : n);
|
|
33023
34167
|
}
|
|
33024
34168
|
|
|
34169
|
+
// src/emf-gdi-halftone-branch.ts
|
|
34170
|
+
function halftoneColorKey(r, g, b) {
|
|
34171
|
+
return b === r ? 16777216 | b >> 2 << 8 | g >> 2 : b | g << 8 | r << 16;
|
|
34172
|
+
}
|
|
34173
|
+
function halftoneBranch(rgb2, w, h) {
|
|
34174
|
+
if (w <= 0 || h <= 0) return "replicate";
|
|
34175
|
+
const n = w * h;
|
|
34176
|
+
if (n <= 2304) return "replicate";
|
|
34177
|
+
const keyAt = (i) => halftoneColorKey(rgb2[i * 3], rgb2[i * 3 + 1], rgb2[i * 3 + 2]);
|
|
34178
|
+
const seen = /* @__PURE__ */ new Set();
|
|
34179
|
+
if (n > 16384) {
|
|
34180
|
+
for (let y = 0; y < h; y += 6) {
|
|
34181
|
+
for (let x = 0; x < w; x++) seen.add(keyAt(y * w + x));
|
|
34182
|
+
if (seen.size >= 20) return "filter";
|
|
34183
|
+
}
|
|
34184
|
+
return "replicate";
|
|
34185
|
+
}
|
|
34186
|
+
const rows = Math.floor(2304 / w) + 1;
|
|
34187
|
+
if (h < rows) return "replicate";
|
|
34188
|
+
const exact = h === rows;
|
|
34189
|
+
const limit = exact ? 289 + Math.floor((rows * w - 2304) / 8) : 145 + Math.floor((rows * w - 2304) / 16);
|
|
34190
|
+
let colors = 0;
|
|
34191
|
+
let duplicateRows = 0;
|
|
34192
|
+
let coloredPixels = 0;
|
|
34193
|
+
let gaveUp = false;
|
|
34194
|
+
for (let y = 0; y < h; y++) {
|
|
34195
|
+
let added = 0;
|
|
34196
|
+
for (let x = 0; x < w; x++) {
|
|
34197
|
+
const key = keyAt(y * w + x);
|
|
34198
|
+
if (!seen.has(key)) {
|
|
34199
|
+
seen.add(key);
|
|
34200
|
+
added++;
|
|
34201
|
+
}
|
|
34202
|
+
}
|
|
34203
|
+
colors += added;
|
|
34204
|
+
if (!gaveUp && colors >= limit) return "filter";
|
|
34205
|
+
if (added === 0) duplicateRows++;
|
|
34206
|
+
else coloredPixels += w;
|
|
34207
|
+
if (colors >= 20 && coloredPixels > 2304 && !(exact && gaveUp)) return "filter";
|
|
34208
|
+
if (exact ? colors + duplicateRows * w >= limit - 1 : colors + (duplicateRows + 1) * w >= n - 2305 + limit) gaveUp = true;
|
|
34209
|
+
}
|
|
34210
|
+
return "replicate";
|
|
34211
|
+
}
|
|
34212
|
+
|
|
33025
34213
|
// src/emf-gdi-stretch.ts
|
|
33026
34214
|
var BLACKONWHITE = 1;
|
|
33027
34215
|
var WHITEONBLACK = 2;
|
|
@@ -33154,119 +34342,24 @@ function halftoneReduceTaps(srcLen, dstLen, reverse) {
|
|
|
33154
34342
|
if (reverse) taps.reverse();
|
|
33155
34343
|
return taps;
|
|
33156
34344
|
}
|
|
33157
|
-
var ENLARGE_INNER = [
|
|
33158
|
-
1e3,
|
|
33159
|
-
992.47,
|
|
33160
|
-
984.9399,
|
|
33161
|
-
977.4099,
|
|
33162
|
-
969.8798,
|
|
33163
|
-
962.3498,
|
|
33164
|
-
954.8198,
|
|
33165
|
-
947.2897,
|
|
33166
|
-
939.7597,
|
|
33167
|
-
932.2296,
|
|
33168
|
-
924.6996,
|
|
33169
|
-
917.1695,
|
|
33170
|
-
909.6395,
|
|
33171
|
-
902.1095,
|
|
33172
|
-
894.5665,
|
|
33173
|
-
886.8087,
|
|
33174
|
-
879.045,
|
|
33175
|
-
871.2813,
|
|
33176
|
-
863.4349,
|
|
33177
|
-
855.5885,
|
|
33178
|
-
847.7421,
|
|
33179
|
-
839.8269,
|
|
33180
|
-
831.9046,
|
|
33181
|
-
823.912,
|
|
33182
|
-
815.9193,
|
|
33183
|
-
807.9266,
|
|
33184
|
-
799.847,
|
|
33185
|
-
791.7283,
|
|
33186
|
-
783.6096,
|
|
33187
|
-
775.449,
|
|
33188
|
-
767.3204,
|
|
33189
|
-
758.9233,
|
|
33190
|
-
750.5263,
|
|
33191
|
-
742.4271,
|
|
33192
|
-
734.0547,
|
|
33193
|
-
725.6823,
|
|
33194
|
-
717.232,
|
|
33195
|
-
708.7675,
|
|
33196
|
-
700.2393,
|
|
33197
|
-
691.7111,
|
|
33198
|
-
683.0734,
|
|
33199
|
-
674.4357,
|
|
33200
|
-
665.7105,
|
|
33201
|
-
656.9854,
|
|
33202
|
-
648.2603,
|
|
33203
|
-
639.3747,
|
|
33204
|
-
630.4873,
|
|
33205
|
-
621.5157,
|
|
33206
|
-
612.5442
|
|
33207
|
-
];
|
|
33208
|
-
var ENLARGE_OUTER = [
|
|
33209
|
-
375.1388,
|
|
33210
|
-
364.2093,
|
|
33211
|
-
353.2797,
|
|
33212
|
-
342.4714,
|
|
33213
|
-
331.7615,
|
|
33214
|
-
321.1462,
|
|
33215
|
-
310.6456,
|
|
33216
|
-
300.2252,
|
|
33217
|
-
289.9229,
|
|
33218
|
-
279.7227,
|
|
33219
|
-
269.6439,
|
|
33220
|
-
259.6535,
|
|
33221
|
-
249.7825,
|
|
33222
|
-
240.0362,
|
|
33223
|
-
230.3856,
|
|
33224
|
-
220.8799,
|
|
33225
|
-
211.4594,
|
|
33226
|
-
202.1844,
|
|
33227
|
-
192.9996,
|
|
33228
|
-
183.9679,
|
|
33229
|
-
175.1064,
|
|
33230
|
-
166.2864,
|
|
33231
|
-
157.6436,
|
|
33232
|
-
149.1447,
|
|
33233
|
-
140.7609,
|
|
33234
|
-
132.5474,
|
|
33235
|
-
124.4802,
|
|
33236
|
-
116.5636,
|
|
33237
|
-
108.778,
|
|
33238
|
-
101.1602,
|
|
33239
|
-
93.7098,
|
|
33240
|
-
86.4419,
|
|
33241
|
-
79.3251,
|
|
33242
|
-
72.4091,
|
|
33243
|
-
65.6853,
|
|
33244
|
-
59.1472,
|
|
33245
|
-
52.812,
|
|
33246
|
-
46.6978,
|
|
33247
|
-
40.8001,
|
|
33248
|
-
35.1449,
|
|
33249
|
-
29.7494,
|
|
33250
|
-
24.6096,
|
|
33251
|
-
19.7977,
|
|
33252
|
-
15.2801,
|
|
33253
|
-
11.1442,
|
|
33254
|
-
7.3916,
|
|
33255
|
-
4.1415,
|
|
33256
|
-
1.4039,
|
|
33257
|
-
0
|
|
33258
|
-
];
|
|
33259
|
-
var ENLARGE_HALF = 500.0106;
|
|
33260
|
-
var ENLARGE_KNOTS = 96;
|
|
33261
34345
|
function enlargeKernel(u) {
|
|
33262
34346
|
if (u >= 1) return 0;
|
|
33263
|
-
|
|
33264
|
-
|
|
33265
|
-
|
|
33266
|
-
const i = Math.min(table2.length - 2, Math.floor(edge + 1e-9));
|
|
33267
|
-
return table2[i] + (table2[i + 1] - table2[i]) * (edge - i);
|
|
34347
|
+
const x = 1 - u;
|
|
34348
|
+
if (Math.abs(u - 0.5) < 1e-9) return x;
|
|
34349
|
+
return Math.pow(x, u < 0.5 ? Math.SQRT1_2 : Math.SQRT2);
|
|
33268
34350
|
}
|
|
33269
34351
|
function halftoneEnlargeTaps(src, dst) {
|
|
34352
|
+
return halftoneEnlargeCumulative(src, dst).map((row2) => {
|
|
34353
|
+
let prev = 0;
|
|
34354
|
+
return row2.map(([j, cum], i) => {
|
|
34355
|
+
const c = i === row2.length - 1 ? 8192 : Math.ceil(cum - 1e-7);
|
|
34356
|
+
const share = c - prev;
|
|
34357
|
+
prev = c;
|
|
34358
|
+
return [j, share / 8192];
|
|
34359
|
+
});
|
|
34360
|
+
});
|
|
34361
|
+
}
|
|
34362
|
+
function halftoneEnlargeCumulative(src, dst) {
|
|
33270
34363
|
const ratio = dst / src;
|
|
33271
34364
|
const reach = Math.ceil(ratio) - 1;
|
|
33272
34365
|
const fir = [];
|
|
@@ -33287,7 +34380,7 @@ function halftoneEnlargeTaps(src, dst) {
|
|
|
33287
34380
|
}
|
|
33288
34381
|
cover.push(run);
|
|
33289
34382
|
}
|
|
33290
|
-
const
|
|
34383
|
+
const rows = [];
|
|
33291
34384
|
for (let x = 0; x < dst; x++) {
|
|
33292
34385
|
const weights = /* @__PURE__ */ new Map();
|
|
33293
34386
|
for (let k = -reach; k <= reach; k++) {
|
|
@@ -33298,18 +34391,13 @@ function halftoneEnlargeTaps(src, dst) {
|
|
|
33298
34391
|
}
|
|
33299
34392
|
}
|
|
33300
34393
|
const sorted = [...weights.entries()].sort((a, b) => a[0] - b[0]);
|
|
33301
|
-
let prev = 0;
|
|
33302
34394
|
let cum = 0;
|
|
33303
|
-
|
|
33304
|
-
|
|
33305
|
-
|
|
33306
|
-
|
|
33307
|
-
row2.push([sorted[i][0], (c - prev) / 8192]);
|
|
33308
|
-
prev = c;
|
|
33309
|
-
}
|
|
33310
|
-
taps.push(row2);
|
|
34395
|
+
rows.push(sorted.map(([j, v]) => {
|
|
34396
|
+
cum += v * 8192;
|
|
34397
|
+
return [j, cum];
|
|
34398
|
+
}));
|
|
33311
34399
|
}
|
|
33312
|
-
return
|
|
34400
|
+
return rows;
|
|
33313
34401
|
}
|
|
33314
34402
|
function ditherPixels(px, w, h, dither, flipX, flipY, phaseX, phaseY) {
|
|
33315
34403
|
for (let y = 0; y < h; y++) {
|
|
@@ -33386,6 +34474,20 @@ function halftoneDespeckle(px, w, h) {
|
|
|
33386
34474
|
}
|
|
33387
34475
|
}
|
|
33388
34476
|
}
|
|
34477
|
+
function halftoneSharpen(px, w, h) {
|
|
34478
|
+
const src = px.slice();
|
|
34479
|
+
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];
|
|
34480
|
+
for (let y = 0; y < h; y++) {
|
|
34481
|
+
for (let x = 0; x < w; x++) {
|
|
34482
|
+
for (let c = 0; c < 3; c++) {
|
|
34483
|
+
const v = at(x, y, c);
|
|
34484
|
+
const sum = at(x - 1, y, c) + at(x + 1, y, c) + at(x, y - 1, c) + at(x, y + 1, c);
|
|
34485
|
+
const out = v + Math.floor((4 * v - sum) / 8);
|
|
34486
|
+
px[(y * w + x) * 3 + c] = out < 0 ? 0 : out > 255 ? 255 : out;
|
|
34487
|
+
}
|
|
34488
|
+
}
|
|
34489
|
+
}
|
|
34490
|
+
}
|
|
33389
34491
|
function halftonePairDespeckle(px, w, h, rows) {
|
|
33390
34492
|
const n = rows ? w : h;
|
|
33391
34493
|
const at = (k, side) => (rows ? side * w + k : k * w + side) * 3;
|
|
@@ -33448,6 +34550,239 @@ function halftoneReduceBoth(rect, sw, sh, dw, dh, flipX, flipY) {
|
|
|
33448
34550
|
}
|
|
33449
34551
|
return out;
|
|
33450
34552
|
}
|
|
34553
|
+
function halftoneReduceOneAxis(rect, sw, sh, dw, dh, flipX, flipY) {
|
|
34554
|
+
const vertical = dh < sh;
|
|
34555
|
+
const taps = vertical ? halftoneReduceTaps(sh, dh, flipY) : halftoneReduceTaps(sw, dw, flipX);
|
|
34556
|
+
const reduced = new Float64Array(dw * dh * 3);
|
|
34557
|
+
for (let y = 0; y < dh; y++) {
|
|
34558
|
+
for (let x = 0; x < dw; x++) {
|
|
34559
|
+
const run = vertical ? taps[y] : taps[x];
|
|
34560
|
+
const keep = vertical ? flipX ? dw - 1 - x : x : flipY ? dh - 1 - y : y;
|
|
34561
|
+
let total = 0;
|
|
34562
|
+
for (const [, w] of run) total += w;
|
|
34563
|
+
for (let c = 0; c < 3; c++) {
|
|
34564
|
+
let sum = 0;
|
|
34565
|
+
for (const [k, w] of run) sum += rect[((vertical ? k : keep) * sw + (vertical ? keep : k)) * 3 + c] * w;
|
|
34566
|
+
reduced[(y * dw + x) * 3 + c] = sum / total;
|
|
34567
|
+
}
|
|
34568
|
+
}
|
|
34569
|
+
}
|
|
34570
|
+
const out = new Int32Array(dw * dh * 3);
|
|
34571
|
+
const at = (x, y, c) => reduced[(Math.max(0, Math.min(dh - 1, y)) * dw + Math.max(0, Math.min(dw - 1, x))) * 3 + c];
|
|
34572
|
+
for (let y = 0; y < dh; y++) {
|
|
34573
|
+
for (let x = 0; x < dw; x++) {
|
|
34574
|
+
for (let c = 0; c < 3; c++) {
|
|
34575
|
+
const v = at(x, y, c);
|
|
34576
|
+
const sum = vertical ? at(x, y - 1, c) + at(x, y + 1, c) : at(x - 1, y, c) + at(x + 1, y, c);
|
|
34577
|
+
out[(y * dw + x) * 3 + c] = Math.max(0, Math.min(255, Math.floor(v + (2 * v - sum) / 4)));
|
|
34578
|
+
}
|
|
34579
|
+
}
|
|
34580
|
+
}
|
|
34581
|
+
return out;
|
|
34582
|
+
}
|
|
34583
|
+
var FILTER_WEIGHTS = {
|
|
34584
|
+
1: [[5, 22, 5, 32]],
|
|
34585
|
+
2: [[4, 12, 0, 16], [0, 12, 4, 16]],
|
|
34586
|
+
3: [[6, 10, 0, 16], [1, 14, 1, 16], [0, 10, 6, 16]],
|
|
34587
|
+
4: [[6, 10, 0, 16], [3, 12, 1, 16], [1, 12, 3, 16], [0, 10, 6, 16]],
|
|
34588
|
+
5: [[13, 19, 0, 32], [6, 25, 1, 32], [3, 26, 3, 32], [1, 25, 6, 32], [0, 19, 13, 32]]
|
|
34589
|
+
};
|
|
34590
|
+
function filterAxisTaps(src, dst) {
|
|
34591
|
+
const factor = dst / src;
|
|
34592
|
+
if (factor === 2) {
|
|
34593
|
+
const rows = FILTER_WEIGHTS[2].map(([a, b, c]) => [a * 512, b * 512, c * 512]);
|
|
34594
|
+
return Array.from({ length: dst }, (_, i) => {
|
|
34595
|
+
const k = Math.floor(i / 2);
|
|
34596
|
+
const [a, b, c] = rows[i % 2];
|
|
34597
|
+
return [[Math.max(0, k - 1), a], [k, b], [Math.min(src - 1, k + 1), c]];
|
|
34598
|
+
});
|
|
34599
|
+
}
|
|
34600
|
+
return halftoneEnlargeTaps(src, dst).map((row2) => row2.map(([j, v]) => [j, Math.round(v * 8192)]));
|
|
34601
|
+
}
|
|
34602
|
+
function halftoneFilterOneAxis(rgb2, w, h, W, H, below) {
|
|
34603
|
+
const horizontal = W > w;
|
|
34604
|
+
const n = horizontal ? w : h;
|
|
34605
|
+
const sharp = new Int32Array(rgb2.length);
|
|
34606
|
+
const at = (x, y, c) => y >= h && below ? below[Math.max(0, Math.min(w - 1, x)) * 3 + c] : rgb2[(Math.max(0, Math.min(h - 1, y)) * w + Math.max(0, Math.min(w - 1, x))) * 3 + c];
|
|
34607
|
+
for (let y = 0; y < h; y++) {
|
|
34608
|
+
for (let x = 0; x < w; x++) {
|
|
34609
|
+
for (let c = 0; c < 3; c++) {
|
|
34610
|
+
const v = at(x, y, c);
|
|
34611
|
+
const sum = horizontal ? at(x - 1, y, c) + at(x + 1, y, c) : at(x, y - 1, c) + at(x, y + 1, c);
|
|
34612
|
+
const out2 = v + Math.floor((2 * v - sum) / 4);
|
|
34613
|
+
sharp[(y * w + x) * 3 + c] = out2 < 0 ? 0 : out2 > 255 ? 255 : out2;
|
|
34614
|
+
}
|
|
34615
|
+
}
|
|
34616
|
+
}
|
|
34617
|
+
const taps = filterAxisTaps(n, horizontal ? W : H);
|
|
34618
|
+
const out = new Int32Array(W * H * 3);
|
|
34619
|
+
for (let y = 0; y < H; y++) {
|
|
34620
|
+
for (let x = 0; x < W; x++) {
|
|
34621
|
+
for (let c = 0; c < 3; c++) {
|
|
34622
|
+
let sum = 0;
|
|
34623
|
+
if (horizontal) for (const [j, weight] of taps[x]) sum += weight * sharp[(y * w + j) * 3 + c];
|
|
34624
|
+
else for (const [j, weight] of taps[y]) sum += weight * sharp[(j * w + x) * 3 + c];
|
|
34625
|
+
out[(y * W + x) * 3 + c] = Math.floor((sum + 4096) / 8192);
|
|
34626
|
+
}
|
|
34627
|
+
}
|
|
34628
|
+
}
|
|
34629
|
+
return out;
|
|
34630
|
+
}
|
|
34631
|
+
function filterRuns(src, dst) {
|
|
34632
|
+
const k = Array.from({ length: dst }, (_, i) => halftoneNearest(i, src, dst));
|
|
34633
|
+
const length = /* @__PURE__ */ new Map();
|
|
34634
|
+
for (const v of k) length.set(v, (length.get(v) ?? 0) + 1);
|
|
34635
|
+
const placed = /* @__PURE__ */ new Map();
|
|
34636
|
+
return k.map((v) => {
|
|
34637
|
+
const p = placed.get(v) ?? 0;
|
|
34638
|
+
placed.set(v, p + 1);
|
|
34639
|
+
return { k: v, weights: FILTER_WEIGHTS[length.get(v)][p] };
|
|
34640
|
+
});
|
|
34641
|
+
}
|
|
34642
|
+
function halftoneFilterSupported(w, h, W, H) {
|
|
34643
|
+
return w > 0 && h > 0 && W >= w && H >= h && (W > w || H > h);
|
|
34644
|
+
}
|
|
34645
|
+
function ditherFilteredSource(rect, SW, SH, W, H, dither, flipY) {
|
|
34646
|
+
if (W > 5 * SW || H > 5 * SH) {
|
|
34647
|
+
const further = new Int32Array((SH + 1) * SW * 3);
|
|
34648
|
+
further.set(rect);
|
|
34649
|
+
further.set(rect.subarray((SH - 1) * SW * 3), SH * SW * 3);
|
|
34650
|
+
ditherPixels(
|
|
34651
|
+
further,
|
|
34652
|
+
SW,
|
|
34653
|
+
SH + 1,
|
|
34654
|
+
dither,
|
|
34655
|
+
false,
|
|
34656
|
+
false,
|
|
34657
|
+
void 0,
|
|
34658
|
+
Int32Array.from({ length: SH + 1 }, (_, j) => flipY ? H - 1 - j : j)
|
|
34659
|
+
);
|
|
34660
|
+
return further;
|
|
34661
|
+
}
|
|
34662
|
+
const extended = new Int32Array((SH + 4) * SW * 3);
|
|
34663
|
+
extended.set(rect.subarray(0, SW * 3), 0);
|
|
34664
|
+
extended.set(rect.subarray(0, SW * 3), SW * 3);
|
|
34665
|
+
extended.set(rect, 2 * SW * 3);
|
|
34666
|
+
extended.set(rect.subarray((SH - 1) * SW * 3), (SH + 2) * SW * 3);
|
|
34667
|
+
extended.set(rect.subarray((SH - 1) * SW * 3), (SH + 3) * SW * 3);
|
|
34668
|
+
ditherPixels(
|
|
34669
|
+
extended,
|
|
34670
|
+
SW,
|
|
34671
|
+
SH + 4,
|
|
34672
|
+
{ startX: dither.startX, startY: (dither.startY + (flipY ? 63 : 2)) % 65 },
|
|
34673
|
+
false,
|
|
34674
|
+
false,
|
|
34675
|
+
void 0,
|
|
34676
|
+
Int32Array.from({ length: SH + 4 }, (_, e) => flipY ? H - e + 1 : e - 2)
|
|
34677
|
+
);
|
|
34678
|
+
return extended;
|
|
34679
|
+
}
|
|
34680
|
+
function halftoneFilterEnlarge(rgb2, w, h, W, H, extended) {
|
|
34681
|
+
if (W === w || H === h) return halftoneFilterOneAxis(rgb2, w, h, W, H, extended && extended.length === (h + 1) * w * 3 ? extended.subarray(h * w * 3) : void 0);
|
|
34682
|
+
const clamp2 = (v) => v < 0 ? 0 : v > 255 ? 255 : v;
|
|
34683
|
+
const general = W > 5 * w || H > 5 * h;
|
|
34684
|
+
const out = new Int32Array(W * H * 3);
|
|
34685
|
+
if (general) {
|
|
34686
|
+
const sharp2 = rgb2.slice();
|
|
34687
|
+
if (extended) {
|
|
34688
|
+
const at2 = (x, y, c) => extended[(Math.max(0, Math.min(h, y)) * w + Math.max(0, Math.min(w - 1, x))) * 3 + c];
|
|
34689
|
+
for (let y = 0; y < h; y++) {
|
|
34690
|
+
for (let x = 0; x < w; x++) {
|
|
34691
|
+
for (let c = 0; c < 3; c++) {
|
|
34692
|
+
const v = at2(x, y, c);
|
|
34693
|
+
const sum = at2(x - 1, y, c) + at2(x + 1, y, c) + at2(x, y - 1, c) + at2(x, y + 1, c);
|
|
34694
|
+
sharp2[(y * w + x) * 3 + c] = clamp2(v + Math.floor((4 * v - sum) / 8));
|
|
34695
|
+
}
|
|
34696
|
+
}
|
|
34697
|
+
}
|
|
34698
|
+
} else {
|
|
34699
|
+
halftoneSharpen(sharp2, w, h);
|
|
34700
|
+
}
|
|
34701
|
+
const xt = filterAxisTaps(w, W);
|
|
34702
|
+
const yt = filterAxisTaps(h, H);
|
|
34703
|
+
const middle2 = new Int32Array(W * h * 3);
|
|
34704
|
+
for (let y = 0; y < h; y++) {
|
|
34705
|
+
for (let x = 0; x < W; x++) {
|
|
34706
|
+
for (let c = 0; c < 3; c++) {
|
|
34707
|
+
let sum = 0;
|
|
34708
|
+
for (const [j, weight] of xt[x]) sum += weight * sharp2[(y * w + j) * 3 + c];
|
|
34709
|
+
middle2[(y * W + x) * 3 + c] = Math.floor((sum + 4096) / 8192);
|
|
34710
|
+
}
|
|
34711
|
+
}
|
|
34712
|
+
}
|
|
34713
|
+
for (let y = 0; y < H; y++) {
|
|
34714
|
+
for (let x = 0; x < W; x++) {
|
|
34715
|
+
for (let c = 0; c < 3; c++) {
|
|
34716
|
+
let sum = 0;
|
|
34717
|
+
for (const [j, weight] of yt[y]) sum += weight * middle2[(j * W + x) * 3 + c];
|
|
34718
|
+
out[(y * W + x) * 3 + c] = clamp2(Math.floor((sum + 4096) / 8192));
|
|
34719
|
+
}
|
|
34720
|
+
}
|
|
34721
|
+
}
|
|
34722
|
+
return out;
|
|
34723
|
+
}
|
|
34724
|
+
const rows = h + 2;
|
|
34725
|
+
const sharp = new Int32Array(w * rows * 3);
|
|
34726
|
+
let padded;
|
|
34727
|
+
if (extended && extended.length === (h + 4) * w * 3) padded = extended;
|
|
34728
|
+
else {
|
|
34729
|
+
padded = new Int32Array(w * (h + 4) * 3);
|
|
34730
|
+
if (extended && extended.length === rows * w * 3) {
|
|
34731
|
+
padded.set(extended.subarray(w * 3, 2 * w * 3), 0);
|
|
34732
|
+
padded.set(extended, w * 3);
|
|
34733
|
+
padded.set(extended.subarray(h * w * 3, (h + 1) * w * 3), (h + 3) * w * 3);
|
|
34734
|
+
} else {
|
|
34735
|
+
padded.set(rgb2.subarray(0, w * 3), 0);
|
|
34736
|
+
padded.set(rgb2.subarray(0, w * 3), w * 3);
|
|
34737
|
+
padded.set(rgb2, 2 * w * 3);
|
|
34738
|
+
padded.set(rgb2.subarray((h - 1) * w * 3), (h + 2) * w * 3);
|
|
34739
|
+
padded.set(rgb2.subarray((h - 1) * w * 3), (h + 3) * w * 3);
|
|
34740
|
+
}
|
|
34741
|
+
}
|
|
34742
|
+
const source = padded;
|
|
34743
|
+
const at = (x, y, c) => source[((y + 1) * w + Math.max(0, Math.min(w - 1, x))) * 3 + c];
|
|
34744
|
+
for (let y = 0; y < rows; y++) {
|
|
34745
|
+
for (let x = 0; x < w; x++) {
|
|
34746
|
+
for (let c = 0; c < 3; c++) {
|
|
34747
|
+
const v = at(x, y, c);
|
|
34748
|
+
const sum = at(x - 1, y, c) + at(x + 1, y, c) + at(x, y - 1, c) + at(x, y + 1, c);
|
|
34749
|
+
sharp[(y * w + x) * 3 + c] = clamp2(v + Math.floor((4 * v - sum) / 8));
|
|
34750
|
+
}
|
|
34751
|
+
}
|
|
34752
|
+
}
|
|
34753
|
+
const xr = filterRuns(w, W);
|
|
34754
|
+
const yr = filterRuns(h, H);
|
|
34755
|
+
const middle = new Int32Array(w * 3);
|
|
34756
|
+
for (let y = 0; y < H; y++) {
|
|
34757
|
+
const near = yr[y].k + 1;
|
|
34758
|
+
const [a, b, c, total] = yr[y].weights;
|
|
34759
|
+
const before = (near - 1) * w * 3;
|
|
34760
|
+
const here = near * w * 3;
|
|
34761
|
+
const after = (near + 1) * w * 3;
|
|
34762
|
+
for (let i = 0; i < w * 3; i++) {
|
|
34763
|
+
middle[i] = Math.floor((a * sharp[before + i] + b * sharp[here + i] + c * sharp[after + i] + total / 2) / total);
|
|
34764
|
+
}
|
|
34765
|
+
for (let x = 0; x < W; x++) {
|
|
34766
|
+
const k = xr[x].k;
|
|
34767
|
+
const [a2, b2, c2, total2] = xr[x].weights;
|
|
34768
|
+
const left = Math.max(0, k - 1);
|
|
34769
|
+
const right = Math.min(w - 1, k + 1);
|
|
34770
|
+
for (let c3 = 0; c3 < 3; c3++) {
|
|
34771
|
+
out[(y * W + x) * 3 + c3] = Math.floor((a2 * middle[left * 3 + c3] + b2 * middle[k * 3 + c3] + c2 * middle[right * 3 + c3] + total2 / 2) / total2);
|
|
34772
|
+
}
|
|
34773
|
+
}
|
|
34774
|
+
}
|
|
34775
|
+
return out;
|
|
34776
|
+
}
|
|
34777
|
+
function halftoneMixedEngine(rect, SW, SH, W, H) {
|
|
34778
|
+
const halved = W > SW && H * 2 <= SH || H > SH && W * 2 <= SW;
|
|
34779
|
+
const cap = H < SH && 3 * H + 2 <= 2 * SH || W < SW && 3 * W + 2 <= 2 * SW;
|
|
34780
|
+
if (halved || cap) return "reduced";
|
|
34781
|
+
const small = SW * SH <= 2304;
|
|
34782
|
+
if (!small && halftoneBranch(rect, SW, SH) === "filter") return "reduced";
|
|
34783
|
+
if (W * H < SW * SH) return small ? "despeckled" : "reduced";
|
|
34784
|
+
return "nearest";
|
|
34785
|
+
}
|
|
33451
34786
|
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSampling = false, directDib = false, dither, curves) {
|
|
33452
34787
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
33453
34788
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
@@ -33492,14 +34827,76 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
33492
34827
|
const reducing = W < SW && H < SH;
|
|
33493
34828
|
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
33494
34829
|
const dithered = !!dither && !!adjust && !adjustAfterSampling;
|
|
33495
|
-
const
|
|
33496
|
-
const
|
|
33497
|
-
|
|
34830
|
+
const mixedPlain = mixed && (!adjust || adjustAfterSampling || dithered);
|
|
34831
|
+
const engine = mixedPlain ? halftoneMixedEngine(rect, SW, SH, W, H) : "nearest";
|
|
34832
|
+
const nearestMixed = mixedPlain && engine === "nearest" && (W < SW && W * 2 > SW || H < SH && H * 2 > SH);
|
|
34833
|
+
const nativeMixed = mixedPlain && engine !== "nearest";
|
|
34834
|
+
const despeckles = SW * SH <= 2304 || SW * SH > 16384;
|
|
34835
|
+
const oneAxisReduce = W < SW && H === SH || H < SH && W === SW;
|
|
34836
|
+
const reduceDespeckle = (reducing || oneAxisReduce) && despeckles && !directDib && !(W < SW && 3 * W + 2 <= 2 * SW) && !(H < SH && 3 * H + 2 <= 2 * SH) && (SW * SH <= 2304 || halftoneBranch(rect, SW, SH) === "replicate");
|
|
34837
|
+
if (oneAxisReduce && (!adjust || adjustAfterSampling || dithered)) {
|
|
34838
|
+
if (reduceDespeckle) halftoneDespeckle(rect, SW, SH);
|
|
34839
|
+
const reduced = halftoneReduceOneAxis(rect, SW, SH, W, H, flipX, flipY);
|
|
34840
|
+
if (dithered) {
|
|
34841
|
+
ditherPixels(reduced, W, H, dither);
|
|
34842
|
+
adjust(reduced);
|
|
34843
|
+
if (curves) curves(reduced);
|
|
34844
|
+
} else if (adjust) adjust(reduced);
|
|
34845
|
+
for (let i = 0, o = 0; i < W * H; i++, o += 3) {
|
|
34846
|
+
data[i * 4] = reduced[o];
|
|
34847
|
+
data[i * 4 + 1] = reduced[o + 1];
|
|
34848
|
+
data[i * 4 + 2] = reduced[o + 2];
|
|
34849
|
+
data[i * 4 + 3] = 255;
|
|
34850
|
+
}
|
|
34851
|
+
return { width: W, height: H, data };
|
|
34852
|
+
}
|
|
34853
|
+
if (enlarging && halftoneFilterSupported(SW, SH, W, H) && (!adjust || adjustAfterSampling || dithered) && halftoneBranch(rect, SW, SH) === "filter") {
|
|
34854
|
+
let extended;
|
|
34855
|
+
let source = rect;
|
|
34856
|
+
if (dithered) {
|
|
34857
|
+
if (W === SW || H === SH) {
|
|
34858
|
+
if (H > SH) {
|
|
34859
|
+
extended = new Int32Array((SH + 1) * SW * 3);
|
|
34860
|
+
extended.set(rect);
|
|
34861
|
+
extended.set(rect.subarray((SH - 1) * SW * 3), SH * SW * 3);
|
|
34862
|
+
ditherPixels(extended, SW, SH + 1, dither, false, false, void 0, Int32Array.from({ length: SH + 1 }, (_, j) => flipY ? H - 1 - j : j));
|
|
34863
|
+
adjust(extended);
|
|
34864
|
+
source = extended.subarray(0, SW * SH * 3);
|
|
34865
|
+
} else {
|
|
34866
|
+
source = rect.slice();
|
|
34867
|
+
ditherPixels(source, SW, SH, dither, false, false, void 0, Int32Array.from({ length: SH }, (_, j) => flipY ? H - 1 - j : j));
|
|
34868
|
+
adjust(source);
|
|
34869
|
+
}
|
|
34870
|
+
} else {
|
|
34871
|
+
extended = ditherFilteredSource(rect, SW, SH, W, H, dither, flipY);
|
|
34872
|
+
adjust(extended);
|
|
34873
|
+
}
|
|
34874
|
+
}
|
|
34875
|
+
const filtered = halftoneFilterEnlarge(source, SW, SH, W, H, extended);
|
|
34876
|
+
if (flipX || flipY) {
|
|
34877
|
+
const mirror2 = filtered.slice();
|
|
34878
|
+
for (let y = 0; y < H; y++) {
|
|
34879
|
+
for (let x = 0; x < W; x++) {
|
|
34880
|
+
const from = ((flipY ? H - 1 - y : y) * W + (flipX ? W - 1 - x : x)) * 3;
|
|
34881
|
+
filtered.set(mirror2.subarray(from, from + 3), (y * W + x) * 3);
|
|
34882
|
+
}
|
|
34883
|
+
}
|
|
34884
|
+
}
|
|
34885
|
+
if (adjust && adjustAfterSampling) adjust(filtered);
|
|
34886
|
+
if (curves && dithered) curves(filtered);
|
|
34887
|
+
for (let i = 0, o = 0; i < W * H; i++, o += 3) {
|
|
34888
|
+
data[i * 4] = filtered[o];
|
|
34889
|
+
data[i * 4 + 1] = filtered[o + 1];
|
|
34890
|
+
data[i * 4 + 2] = filtered[o + 2];
|
|
34891
|
+
data[i * 4 + 3] = 255;
|
|
34892
|
+
}
|
|
34893
|
+
return { width: W, height: H, data };
|
|
34894
|
+
}
|
|
34895
|
+
if (((enlarging || nearestMixed || engine === "despeckled") && despeckles || reducing && reduceDespeckle) && !directDib && !pairRows && !pairColumns) {
|
|
33498
34896
|
halftoneDespeckle(rect, SW, SH);
|
|
33499
34897
|
}
|
|
33500
|
-
const
|
|
33501
|
-
const
|
|
33502
|
-
const extendRow = ditherAtSource && nativeMixed && W < SW && H > SH && !flipY;
|
|
34898
|
+
const ditherAtSource = dithered && (W >= SW && H >= SH || nativeMixed && W * H >= SW * SH);
|
|
34899
|
+
const extendRow = ditherAtSource && nativeMixed && W < SW && H > SH;
|
|
33503
34900
|
if (extendRow) {
|
|
33504
34901
|
const bigger = new Int32Array((SH + 1) * SW * 3);
|
|
33505
34902
|
bigger.set(rect);
|
|
@@ -33515,7 +34912,7 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSamplin
|
|
|
33515
34912
|
false,
|
|
33516
34913
|
false,
|
|
33517
34914
|
void 0,
|
|
33518
|
-
flipY ? Int32Array.from({ length: SH }, (_, j) => H - 1 - j) : void 0
|
|
34915
|
+
flipY ? Int32Array.from({ length: extendRow ? SH + 1 : SH }, (_, j) => H - 1 - j) : void 0
|
|
33519
34916
|
);
|
|
33520
34917
|
}
|
|
33521
34918
|
if (adjust && !adjustAfterSampling && (!dithered || ditherAtSource)) {
|
|
@@ -35843,11 +37240,13 @@ function handleExtSelectClipRgn(rCtx, dataOff, recSize) {
|
|
|
35843
37240
|
const top = view.getInt32(rOff + 4, true);
|
|
35844
37241
|
const right = view.getInt32(rOff + 8, true);
|
|
35845
37242
|
const bottom = view.getInt32(rOff + 12, true);
|
|
37243
|
+
const x = gdiDeviceToCanvasX(rCtx, left);
|
|
37244
|
+
const y = gdiDeviceToCanvasY(rCtx, top);
|
|
35846
37245
|
rects.push({
|
|
35847
|
-
x
|
|
35848
|
-
y
|
|
35849
|
-
w:
|
|
35850
|
-
h:
|
|
37246
|
+
x,
|
|
37247
|
+
y,
|
|
37248
|
+
w: gdiDeviceToCanvasX(rCtx, right) - x,
|
|
37249
|
+
h: gdiDeviceToCanvasY(rCtx, bottom) - y
|
|
35851
37250
|
});
|
|
35852
37251
|
}
|
|
35853
37252
|
if (rects.length === 0) {
|
|
@@ -35862,7 +37261,11 @@ function handleOffsetClipRgn(rCtx, dataOff, recSize) {
|
|
|
35862
37261
|
const dx = rCtx.view.getInt32(dataOff, true);
|
|
35863
37262
|
const dy = rCtx.view.getInt32(dataOff + 4, true);
|
|
35864
37263
|
if (rCtx.clipRegion) {
|
|
35865
|
-
|
|
37264
|
+
const px = gdiDevicePixelX(rCtx);
|
|
37265
|
+
const py = gdiDevicePixelY(rCtx);
|
|
37266
|
+
const ox = Math.round(gmw(rCtx, dx) / px) * px;
|
|
37267
|
+
const oy = Math.round(gmh(rCtx, dy) / py) * py;
|
|
37268
|
+
rCtx.clipRegion = translateClipRegion(rCtx.clipRegion, ox, oy);
|
|
35866
37269
|
reapplyClipRegion(rCtx, rCtx.clipRegion);
|
|
35867
37270
|
}
|
|
35868
37271
|
}
|
|
@@ -36620,9 +38023,9 @@ function handlePolyDraw(rCtx, offset, dataOff, recSize, pointSize) {
|
|
|
36620
38023
|
ensureOpen();
|
|
36621
38024
|
const pts = [0, 1, 2].map((k) => readPt(i + k));
|
|
36622
38025
|
const dev = pts.map(([x, y]) => gmapPoint(rCtx, x, y));
|
|
36623
|
-
const
|
|
38026
|
+
const fix2 = pts.map(([x, y]) => fixPoint(rCtx, x, y));
|
|
36624
38027
|
canvas?.bezierCurveTo(dev[0].x, dev[0].y, dev[1].x, dev[1].y, dev[2].x, dev[2].y);
|
|
36625
|
-
raster?.bezierTo(
|
|
38028
|
+
raster?.bezierTo(fix2[0][0], fix2[0][1], fix2[1][0], fix2[1][1], fix2[2][0], fix2[2][1]);
|
|
36626
38029
|
i += 2;
|
|
36627
38030
|
} else {
|
|
36628
38031
|
continue;
|
|
@@ -38021,22 +39424,22 @@ function strokeGdiplus(rCtx, pen, nib, sampler, buildPath, device, size, mode, c
|
|
|
38021
39424
|
const m = frame2.toDevice;
|
|
38022
39425
|
return poly.flatMap((p) => [toPlusFix(m[0] * p.x + m[2] * p.y + m[4]), toPlusFix(m[1] * p.x + m[3] * p.y + m[5])]);
|
|
38023
39426
|
};
|
|
38024
|
-
let
|
|
39427
|
+
let fix2;
|
|
38025
39428
|
if (hasCustomCap(pen)) {
|
|
38026
|
-
|
|
39429
|
+
fix2 = customCapOutline(figures, width, devicePen, pen).map(toFix);
|
|
38027
39430
|
} else if (width <= NOMINAL_PEN_MAX && !devicePen.dash && !(((pen.startCap ?? 0) | (pen.endCap ?? 0) | (pen.dashCap ?? 0)) & 240)) {
|
|
38028
39431
|
return strokeNominal(rCtx, pen, sampler, buildPath, device, size, antialias, closedFigure);
|
|
38029
39432
|
} else {
|
|
38030
|
-
|
|
39433
|
+
fix2 = widenFigures(figures, devicePen).map(toFix);
|
|
38031
39434
|
}
|
|
38032
|
-
const box = figuresBox(
|
|
39435
|
+
const box = figuresBox(fix2, size);
|
|
38033
39436
|
if (!box) {
|
|
38034
39437
|
return true;
|
|
38035
39438
|
}
|
|
38036
39439
|
if (box.w * box.h > 16e6) {
|
|
38037
39440
|
return false;
|
|
38038
39441
|
}
|
|
38039
|
-
const coverage = rasterizePlusFill(
|
|
39442
|
+
const coverage = rasterizePlusFill(fix2, false, antialias, isHalfPixelOffset(rCtx.pixelOffsetMode ?? 0), box);
|
|
38040
39443
|
return compositeBrushCoverage(rCtx, sampler, box, coverage, 1, true);
|
|
38041
39444
|
}
|
|
38042
39445
|
function strokeNominal(rCtx, pen, sampler, buildPath, device, size, antialias, closedFigure) {
|
|
@@ -38171,7 +39574,7 @@ function deviceQuad(wt, s, pts) {
|
|
|
38171
39574
|
}
|
|
38172
39575
|
return out;
|
|
38173
39576
|
}
|
|
38174
|
-
function imageResampleSpec(rCtx, dataOff, isMetafile, toWorld) {
|
|
39577
|
+
function imageResampleSpec(rCtx, dataOff, isMetafile, toWorld, points) {
|
|
38175
39578
|
const { view } = rCtx;
|
|
38176
39579
|
const kernel = resampleKernelFor(rCtx.interpolationMode ?? 0);
|
|
38177
39580
|
if (isMetafile || view.getUint32(dataOff + 4, true) !== UNIT_PIXEL2) {
|
|
@@ -38192,10 +39595,11 @@ function imageResampleSpec(rCtx, dataOff, isMetafile, toWorld) {
|
|
|
38192
39595
|
toDevice: mulMatrix(plusWorldMatrix(rCtx), toWorld(srcX, srcY, srcW, srcH)),
|
|
38193
39596
|
kernel,
|
|
38194
39597
|
halfPixelOffset: isHalfPixelOffset(rCtx.pixelOffsetMode ?? 0),
|
|
39598
|
+
...points ? { pointsForm: true } : {},
|
|
38195
39599
|
...imageAttributesWrap(rCtx, view.getUint32(dataOff, true))
|
|
38196
39600
|
};
|
|
38197
39601
|
}
|
|
38198
|
-
function drawOrDeferImage(rCtx, imgObj, dataOff, dx, dy, dw, dh, toWorld, effect = null) {
|
|
39602
|
+
function drawOrDeferImage(rCtx, imgObj, dataOff, dx, dy, dw, dh, toWorld, effect = null, points = false) {
|
|
38199
39603
|
if (!imgObj.data) {
|
|
38200
39604
|
return;
|
|
38201
39605
|
}
|
|
@@ -38208,7 +39612,7 @@ function drawOrDeferImage(rCtx, imgObj, dataOff, dx, dy, dw, dh, toWorld, effect
|
|
|
38208
39612
|
dh,
|
|
38209
39613
|
transform: plusWorldMatrix(rCtx),
|
|
38210
39614
|
isMetafile,
|
|
38211
|
-
resample: imageResampleSpec(rCtx, dataOff, isMetafile, toWorld)
|
|
39615
|
+
resample: imageResampleSpec(rCtx, dataOff, isMetafile, toWorld, points)
|
|
38212
39616
|
};
|
|
38213
39617
|
const { view } = rCtx;
|
|
38214
39618
|
const source = {
|
|
@@ -38677,7 +40081,7 @@ function handleEmfPlusTextImageRecord(rCtx, recType, recFlags, dataOff, recDataS
|
|
|
38677
40081
|
const c = (p3x - p1x) / sh;
|
|
38678
40082
|
const d = (p3y - p1y) / sh;
|
|
38679
40083
|
return [a, b, c, d, p1x - a * sx - c * sy, p1y - b * sx - d * sy];
|
|
38680
|
-
}, effect);
|
|
40084
|
+
}, effect, true);
|
|
38681
40085
|
} else {
|
|
38682
40086
|
imgObj && imgObj.kind === "plus-image" && imgObj.data;
|
|
38683
40087
|
}
|
|
@@ -40886,15 +42290,15 @@ function compatBox(p, l, t, r, b, opts = {}) {
|
|
|
40886
42290
|
return box;
|
|
40887
42291
|
}
|
|
40888
42292
|
function fixBoxOf(box, cornerExact, keepInverted = false) {
|
|
40889
|
-
const
|
|
42293
|
+
const fix2 = keepInverted ? axisBox(box.x0, box.y0, box.x1, box.y1) : axisBox(box.x0, box.y0, Math.max(box.x0, box.x1), Math.max(box.y0, box.y1));
|
|
40890
42294
|
if (box.halfX) {
|
|
40891
|
-
|
|
40892
|
-
|
|
42295
|
+
fix2.halfX = true;
|
|
42296
|
+
fix2.halfXCompat = true;
|
|
40893
42297
|
}
|
|
40894
42298
|
if (cornerExact) {
|
|
40895
|
-
|
|
42299
|
+
fix2.cornerExact = cornerExact;
|
|
40896
42300
|
}
|
|
40897
|
-
return
|
|
42301
|
+
return fix2;
|
|
40898
42302
|
}
|
|
40899
42303
|
function canvasRect(box) {
|
|
40900
42304
|
return { x: box.x0 / 16, y: box.y0 / 16, w: Math.max(0, box.x1 - box.x0) / 16, h: Math.max(0, box.y1 - box.y0) / 16 };
|