emf-converter 4.4.1 → 4.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +83 -16
- package/dist/browser.mjs +83 -16
- package/dist/index.js +83 -16
- package/dist/index.mjs +83 -16
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -10332,6 +10332,16 @@ function decodeImageCodecFallback(bytes) {
|
|
|
10332
10332
|
if (!f || !validSize(f.image.descriptor.width, f.image.descriptor.height)) return null;
|
|
10333
10333
|
const frame2 = (0, import_gifuct_js.decompressFrame)(f, gif.gct, true);
|
|
10334
10334
|
const data = new Uint8ClampedArray(width * height * 4);
|
|
10335
|
+
const transparent = frame2.transparentIndex !== void 0;
|
|
10336
|
+
const background = transparent ? frame2.colorTable[frame2.transparentIndex] : gif.gct?.[gif.lsd.backgroundColorIndex];
|
|
10337
|
+
if (background) {
|
|
10338
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
10339
|
+
data[i] = background[0];
|
|
10340
|
+
data[i + 1] = background[1];
|
|
10341
|
+
data[i + 2] = background[2];
|
|
10342
|
+
data[i + 3] = transparent ? 0 : 255;
|
|
10343
|
+
}
|
|
10344
|
+
}
|
|
10335
10345
|
const { top, left, width: fw, height: fh } = frame2.dims;
|
|
10336
10346
|
for (let y = 0; y < fh && top + y < height; y++) {
|
|
10337
10347
|
const n = Math.min(fw, width - left);
|
|
@@ -10975,7 +10985,7 @@ function flattenBezierPath(pts) {
|
|
|
10975
10985
|
}
|
|
10976
10986
|
return out;
|
|
10977
10987
|
}
|
|
10978
|
-
function roundRectCorners(l, t, r, b, cw, ch) {
|
|
10988
|
+
function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
|
|
10979
10989
|
const w = r - l;
|
|
10980
10990
|
const h = b - t;
|
|
10981
10991
|
let ew = Math.min(Math.abs(cw), w);
|
|
@@ -10987,7 +10997,9 @@ function roundRectCorners(l, t, r, b, cw, ch) {
|
|
|
10987
10997
|
const hy = Math.floor(h / 2) - Math.floor((h - eh) / 2);
|
|
10988
10998
|
const topX = Math.floor(r - ew / 2);
|
|
10989
10999
|
const hx = r - topX;
|
|
10990
|
-
const
|
|
11000
|
+
const verticalControl = compatible ? Math.round(KAPPA * hy) : Math.floor(KAPPA * hy);
|
|
11001
|
+
const horizontalControl = Math.ceil(KAPPA * hx);
|
|
11002
|
+
const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
|
|
10991
11003
|
const mx = (x) => l + r - x;
|
|
10992
11004
|
const my = (y) => t + b - y;
|
|
10993
11005
|
return [
|
|
@@ -28487,9 +28499,9 @@ function boxFrame(box) {
|
|
|
28487
28499
|
const h = Math.round(Math.hypot(box.eyx, box.eyy));
|
|
28488
28500
|
return { l: 0, t: 0, r: w, b: h };
|
|
28489
28501
|
}
|
|
28490
|
-
function roundRectDeviceBeziers(box, cw, ch, clockwise = false) {
|
|
28502
|
+
function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = false) {
|
|
28491
28503
|
const f = boxFrame(box);
|
|
28492
|
-
const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch);
|
|
28504
|
+
const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible);
|
|
28493
28505
|
const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
|
|
28494
28506
|
const pts = [];
|
|
28495
28507
|
for (let i = 0; i < q.length; i += 2) {
|
|
@@ -28497,9 +28509,9 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false) {
|
|
|
28497
28509
|
}
|
|
28498
28510
|
return pts;
|
|
28499
28511
|
}
|
|
28500
|
-
function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false) {
|
|
28512
|
+
function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false, compatible = false) {
|
|
28501
28513
|
if (rectangle) return rectRasterPath(box, clockwise);
|
|
28502
|
-
const pts = roundRectDeviceBeziers(box, cw, ch, clockwise);
|
|
28514
|
+
const pts = roundRectDeviceBeziers(box, cw, ch, clockwise, compatible);
|
|
28503
28515
|
const path = new GdiRasterPath();
|
|
28504
28516
|
for (let c = 0; c < 4; c++) {
|
|
28505
28517
|
const o = c * 8;
|
|
@@ -30077,6 +30089,9 @@ function handleEmfGdiShapeRecord(rCtx, recType, dataOff, recSize) {
|
|
|
30077
30089
|
var CA_NEGATIVE = 1;
|
|
30078
30090
|
var CA_LOG_FILTER = 2;
|
|
30079
30091
|
var COLOR_ADJUSTMENT_SIZE = 24;
|
|
30092
|
+
function isChannelOnlyColorAdjustment(ca) {
|
|
30093
|
+
return !!ca && (ca.flags & ~CA_LOG_FILTER) === 0 && (ca.illuminant === 0 || ca.illuminant === 6) && ca.referenceBlack === 0 && ca.referenceWhite === 1e4 && ca.contrast === 0 && ca.brightness === 0 && ca.colorfulness === 0 && ca.redGreenTint === 0;
|
|
30094
|
+
}
|
|
30080
30095
|
function readColorAdjustment(view, off) {
|
|
30081
30096
|
const ca = {
|
|
30082
30097
|
flags: view.getUint16(off + 2, true),
|
|
@@ -30132,6 +30147,19 @@ function fromLightness(l) {
|
|
|
30132
30147
|
}
|
|
30133
30148
|
var clamp012 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
30134
30149
|
function colorAdjustmentMapper(ca) {
|
|
30150
|
+
if (ca.referenceBlack === 0 && ca.referenceWhite === 1e4 && ca.contrast === 0 && ca.brightness === 0 && ca.colorfulness === 0 && ca.redGreenTint === 0) {
|
|
30151
|
+
const tables = [ca.redGamma, ca.greenGamma, ca.blueGamma].map((gamma) => {
|
|
30152
|
+
const table = new Uint8Array(256);
|
|
30153
|
+
for (let i = 0; i < 256; i++) {
|
|
30154
|
+
const input = (ca.flags & CA_NEGATIVE) !== 0 ? 255 - i : i;
|
|
30155
|
+
let value = (input / 255) ** (gamma / 1e4);
|
|
30156
|
+
if ((ca.flags & CA_LOG_FILTER) !== 0) value = Math.log2(1 + 7 * value) / 3;
|
|
30157
|
+
table[i] = Math.round(value * 255);
|
|
30158
|
+
}
|
|
30159
|
+
return table;
|
|
30160
|
+
});
|
|
30161
|
+
return (rgb2) => tables[0][rgb2 >> 16 & 255] << 16 | tables[1][rgb2 >> 8 & 255] << 8 | tables[2][rgb2 & 255];
|
|
30162
|
+
}
|
|
30135
30163
|
const black = ca.referenceBlack / 1e4;
|
|
30136
30164
|
const span = Math.max(1e-6, ca.referenceWhite / 1e4 - black);
|
|
30137
30165
|
const gammas = [ca.redGamma / 1e4, ca.greenGamma / 1e4, ca.blueGamma / 1e4];
|
|
@@ -30155,7 +30183,7 @@ function colorAdjustmentMapper(ca) {
|
|
|
30155
30183
|
const out = (v, c) => {
|
|
30156
30184
|
v = clamp012(fromLightness(slope * lightness(clamp012(v)) + offset)) ** (1 / gammas[c]);
|
|
30157
30185
|
if (log) {
|
|
30158
|
-
v = Math.
|
|
30186
|
+
v = Math.log2(1 + 7 * v) / 3;
|
|
30159
30187
|
}
|
|
30160
30188
|
return Math.round(v * 255);
|
|
30161
30189
|
};
|
|
@@ -30379,7 +30407,7 @@ function halftoneSharpen(px, w, h) {
|
|
|
30379
30407
|
}
|
|
30380
30408
|
}
|
|
30381
30409
|
}
|
|
30382
|
-
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
30410
|
+
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSampling = false, directDib = false) {
|
|
30383
30411
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
30384
30412
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
30385
30413
|
const SW = Math.round(Math.abs(sw));
|
|
@@ -30409,14 +30437,28 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
|
30409
30437
|
}
|
|
30410
30438
|
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
30411
30439
|
const reducing = W < SW && H < SH;
|
|
30412
|
-
|
|
30440
|
+
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
30441
|
+
if (enlarging && !directDib) {
|
|
30413
30442
|
halftoneDespeckle(rect, SW, SH);
|
|
30414
30443
|
}
|
|
30415
|
-
if (adjust) {
|
|
30444
|
+
if (adjust && !adjustAfterSampling) {
|
|
30416
30445
|
adjust(rect);
|
|
30417
30446
|
}
|
|
30418
30447
|
const cols = halftoneAxis(0, SW, W, flipX);
|
|
30419
30448
|
const rows = halftoneAxis(0, SH, H, flipY);
|
|
30449
|
+
if (mixed) {
|
|
30450
|
+
const linear = (taps, src2, dst, reverse) => {
|
|
30451
|
+
if (dst <= src2) return;
|
|
30452
|
+
for (let i = 0; i < dst; i++) {
|
|
30453
|
+
const position = Math.max(0, Math.min(src2 - 1, (i + 0.5) * src2 / dst - 0.5));
|
|
30454
|
+
const left = Math.floor(position), fraction = position - left;
|
|
30455
|
+
const at = (k) => reverse ? src2 - 1 - k : k;
|
|
30456
|
+
taps[i] = [[at(left), 1 - fraction], [at(Math.min(src2 - 1, left + 1)), fraction]];
|
|
30457
|
+
}
|
|
30458
|
+
};
|
|
30459
|
+
linear(cols, SW, W, flipX);
|
|
30460
|
+
linear(rows, SH, H, flipY);
|
|
30461
|
+
}
|
|
30420
30462
|
const out = new Int32Array(W * H * 3);
|
|
30421
30463
|
for (let y = 0; y < H; y++) {
|
|
30422
30464
|
const ys = rows[y];
|
|
@@ -30437,14 +30479,28 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
|
30437
30479
|
}
|
|
30438
30480
|
}
|
|
30439
30481
|
const o = (y * W + x) * 3;
|
|
30440
|
-
out[o] = Math.floor((2 * r + total) / (2 * total));
|
|
30441
|
-
out[o + 1] = Math.floor((2 * g + total) / (2 * total));
|
|
30442
|
-
out[o + 2] = Math.floor((2 * b + total) / (2 * total));
|
|
30482
|
+
out[o] = mixed ? Math.ceil(r / total - 0.5) : Math.floor((2 * r + total) / (2 * total));
|
|
30483
|
+
out[o + 1] = mixed ? Math.ceil(g / total - 0.5) : Math.floor((2 * g + total) / (2 * total));
|
|
30484
|
+
out[o + 2] = mixed ? Math.ceil(b / total - 0.5) : Math.floor((2 * b + total) / (2 * total));
|
|
30443
30485
|
}
|
|
30444
30486
|
}
|
|
30445
30487
|
if (reducing) {
|
|
30446
30488
|
halftoneSharpen(out, W, H);
|
|
30447
30489
|
}
|
|
30490
|
+
if (mixed) {
|
|
30491
|
+
const source = out.slice();
|
|
30492
|
+
const at = (x, y, c) => source[(Math.max(0, Math.min(H - 1, y)) * W + Math.max(0, Math.min(W - 1, x))) * 3 + c];
|
|
30493
|
+
for (let y = 0; y < H; y++) {
|
|
30494
|
+
for (let x = 0; x < W; x++) {
|
|
30495
|
+
for (let c = 0; c < 3; c++) {
|
|
30496
|
+
const v = at(x, y, c);
|
|
30497
|
+
const sum = W < SW ? at(x - 1, y, c) + at(x + 1, y, c) : at(x, y - 1, c) + at(x, y + 1, c);
|
|
30498
|
+
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, v + Math.floor((2 * v - sum) / 4)));
|
|
30499
|
+
}
|
|
30500
|
+
}
|
|
30501
|
+
}
|
|
30502
|
+
}
|
|
30503
|
+
if (adjust && adjustAfterSampling) adjust(out);
|
|
30448
30504
|
for (let i = 0, o = 0; i < W * H; i++, o += 3) {
|
|
30449
30505
|
data[i * 4] = out[o];
|
|
30450
30506
|
data[i * 4 + 1] = out[o + 1];
|
|
@@ -30476,7 +30532,18 @@ function patternOperand(rCtx, brush) {
|
|
|
30476
30532
|
function drawSourceMapped(target, decoded, req, offsetX, offsetY, mode) {
|
|
30477
30533
|
const dLeft = Math.min(req.dx, req.dx + req.dw) - offsetX;
|
|
30478
30534
|
const dTop = Math.min(req.dy, req.dy + req.dh) - offsetY;
|
|
30479
|
-
const px = mode === HALFTONE ? stretchHalftone(
|
|
30535
|
+
const px = mode === HALFTONE ? stretchHalftone(
|
|
30536
|
+
decoded.pixels,
|
|
30537
|
+
req.sx,
|
|
30538
|
+
req.sy,
|
|
30539
|
+
req.sw,
|
|
30540
|
+
req.sh,
|
|
30541
|
+
req.dw,
|
|
30542
|
+
req.dh,
|
|
30543
|
+
decoded.adjust,
|
|
30544
|
+
decoded.adjustAfterSampling,
|
|
30545
|
+
req.dibOrigin === "bottom-left"
|
|
30546
|
+
) : stretchGdi(decoded.pixels, req.sx, req.sy, req.sw, req.sh, req.dw, req.dh, mode);
|
|
30480
30547
|
if (px.width === 0 || px.height === 0) {
|
|
30481
30548
|
return;
|
|
30482
30549
|
}
|
|
@@ -30511,7 +30578,7 @@ function decodeSource(rCtx, req) {
|
|
|
30511
30578
|
sy = image.height - sy - req.sh;
|
|
30512
30579
|
}
|
|
30513
30580
|
return {
|
|
30514
|
-
decoded: { pixels: image, adjust },
|
|
30581
|
+
decoded: { pixels: image, adjust, adjustAfterSampling: isChannelOnlyColorAdjustment(ca) },
|
|
30515
30582
|
req: { ...req, sy }
|
|
30516
30583
|
};
|
|
30517
30584
|
}
|
|
@@ -37535,7 +37602,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
|
|
|
37535
37602
|
c.ellipse(cr.x + ex, cr.y + ey, ex, ey, 0, 2 * q, 3 * q);
|
|
37536
37603
|
c.closePath();
|
|
37537
37604
|
},
|
|
37538
|
-
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0),
|
|
37605
|
+
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, true),
|
|
37539
37606
|
roundPen: true,
|
|
37540
37607
|
fill: true,
|
|
37541
37608
|
stroke: true
|
package/dist/browser.mjs
CHANGED
|
@@ -10330,6 +10330,16 @@ function decodeImageCodecFallback(bytes) {
|
|
|
10330
10330
|
if (!f || !validSize(f.image.descriptor.width, f.image.descriptor.height)) return null;
|
|
10331
10331
|
const frame2 = (0, import_gifuct_js.decompressFrame)(f, gif.gct, true);
|
|
10332
10332
|
const data = new Uint8ClampedArray(width * height * 4);
|
|
10333
|
+
const transparent = frame2.transparentIndex !== void 0;
|
|
10334
|
+
const background = transparent ? frame2.colorTable[frame2.transparentIndex] : gif.gct?.[gif.lsd.backgroundColorIndex];
|
|
10335
|
+
if (background) {
|
|
10336
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
10337
|
+
data[i] = background[0];
|
|
10338
|
+
data[i + 1] = background[1];
|
|
10339
|
+
data[i + 2] = background[2];
|
|
10340
|
+
data[i + 3] = transparent ? 0 : 255;
|
|
10341
|
+
}
|
|
10342
|
+
}
|
|
10333
10343
|
const { top, left, width: fw, height: fh } = frame2.dims;
|
|
10334
10344
|
for (let y = 0; y < fh && top + y < height; y++) {
|
|
10335
10345
|
const n = Math.min(fw, width - left);
|
|
@@ -10973,7 +10983,7 @@ function flattenBezierPath(pts) {
|
|
|
10973
10983
|
}
|
|
10974
10984
|
return out;
|
|
10975
10985
|
}
|
|
10976
|
-
function roundRectCorners(l, t, r, b, cw, ch) {
|
|
10986
|
+
function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
|
|
10977
10987
|
const w = r - l;
|
|
10978
10988
|
const h = b - t;
|
|
10979
10989
|
let ew = Math.min(Math.abs(cw), w);
|
|
@@ -10985,7 +10995,9 @@ function roundRectCorners(l, t, r, b, cw, ch) {
|
|
|
10985
10995
|
const hy = Math.floor(h / 2) - Math.floor((h - eh) / 2);
|
|
10986
10996
|
const topX = Math.floor(r - ew / 2);
|
|
10987
10997
|
const hx = r - topX;
|
|
10988
|
-
const
|
|
10998
|
+
const verticalControl = compatible ? Math.round(KAPPA * hy) : Math.floor(KAPPA * hy);
|
|
10999
|
+
const horizontalControl = Math.ceil(KAPPA * hx);
|
|
11000
|
+
const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
|
|
10989
11001
|
const mx = (x) => l + r - x;
|
|
10990
11002
|
const my = (y) => t + b - y;
|
|
10991
11003
|
return [
|
|
@@ -28485,9 +28497,9 @@ function boxFrame(box) {
|
|
|
28485
28497
|
const h = Math.round(Math.hypot(box.eyx, box.eyy));
|
|
28486
28498
|
return { l: 0, t: 0, r: w, b: h };
|
|
28487
28499
|
}
|
|
28488
|
-
function roundRectDeviceBeziers(box, cw, ch, clockwise = false) {
|
|
28500
|
+
function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = false) {
|
|
28489
28501
|
const f = boxFrame(box);
|
|
28490
|
-
const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch);
|
|
28502
|
+
const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible);
|
|
28491
28503
|
const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
|
|
28492
28504
|
const pts = [];
|
|
28493
28505
|
for (let i = 0; i < q.length; i += 2) {
|
|
@@ -28495,9 +28507,9 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false) {
|
|
|
28495
28507
|
}
|
|
28496
28508
|
return pts;
|
|
28497
28509
|
}
|
|
28498
|
-
function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false) {
|
|
28510
|
+
function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false, compatible = false) {
|
|
28499
28511
|
if (rectangle) return rectRasterPath(box, clockwise);
|
|
28500
|
-
const pts = roundRectDeviceBeziers(box, cw, ch, clockwise);
|
|
28512
|
+
const pts = roundRectDeviceBeziers(box, cw, ch, clockwise, compatible);
|
|
28501
28513
|
const path = new GdiRasterPath();
|
|
28502
28514
|
for (let c = 0; c < 4; c++) {
|
|
28503
28515
|
const o = c * 8;
|
|
@@ -30075,6 +30087,9 @@ function handleEmfGdiShapeRecord(rCtx, recType, dataOff, recSize) {
|
|
|
30075
30087
|
var CA_NEGATIVE = 1;
|
|
30076
30088
|
var CA_LOG_FILTER = 2;
|
|
30077
30089
|
var COLOR_ADJUSTMENT_SIZE = 24;
|
|
30090
|
+
function isChannelOnlyColorAdjustment(ca) {
|
|
30091
|
+
return !!ca && (ca.flags & ~CA_LOG_FILTER) === 0 && (ca.illuminant === 0 || ca.illuminant === 6) && ca.referenceBlack === 0 && ca.referenceWhite === 1e4 && ca.contrast === 0 && ca.brightness === 0 && ca.colorfulness === 0 && ca.redGreenTint === 0;
|
|
30092
|
+
}
|
|
30078
30093
|
function readColorAdjustment(view, off) {
|
|
30079
30094
|
const ca = {
|
|
30080
30095
|
flags: view.getUint16(off + 2, true),
|
|
@@ -30130,6 +30145,19 @@ function fromLightness(l) {
|
|
|
30130
30145
|
}
|
|
30131
30146
|
var clamp012 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
30132
30147
|
function colorAdjustmentMapper(ca) {
|
|
30148
|
+
if (ca.referenceBlack === 0 && ca.referenceWhite === 1e4 && ca.contrast === 0 && ca.brightness === 0 && ca.colorfulness === 0 && ca.redGreenTint === 0) {
|
|
30149
|
+
const tables = [ca.redGamma, ca.greenGamma, ca.blueGamma].map((gamma) => {
|
|
30150
|
+
const table = new Uint8Array(256);
|
|
30151
|
+
for (let i = 0; i < 256; i++) {
|
|
30152
|
+
const input = (ca.flags & CA_NEGATIVE) !== 0 ? 255 - i : i;
|
|
30153
|
+
let value = (input / 255) ** (gamma / 1e4);
|
|
30154
|
+
if ((ca.flags & CA_LOG_FILTER) !== 0) value = Math.log2(1 + 7 * value) / 3;
|
|
30155
|
+
table[i] = Math.round(value * 255);
|
|
30156
|
+
}
|
|
30157
|
+
return table;
|
|
30158
|
+
});
|
|
30159
|
+
return (rgb2) => tables[0][rgb2 >> 16 & 255] << 16 | tables[1][rgb2 >> 8 & 255] << 8 | tables[2][rgb2 & 255];
|
|
30160
|
+
}
|
|
30133
30161
|
const black = ca.referenceBlack / 1e4;
|
|
30134
30162
|
const span = Math.max(1e-6, ca.referenceWhite / 1e4 - black);
|
|
30135
30163
|
const gammas = [ca.redGamma / 1e4, ca.greenGamma / 1e4, ca.blueGamma / 1e4];
|
|
@@ -30153,7 +30181,7 @@ function colorAdjustmentMapper(ca) {
|
|
|
30153
30181
|
const out = (v, c) => {
|
|
30154
30182
|
v = clamp012(fromLightness(slope * lightness(clamp012(v)) + offset)) ** (1 / gammas[c]);
|
|
30155
30183
|
if (log) {
|
|
30156
|
-
v = Math.
|
|
30184
|
+
v = Math.log2(1 + 7 * v) / 3;
|
|
30157
30185
|
}
|
|
30158
30186
|
return Math.round(v * 255);
|
|
30159
30187
|
};
|
|
@@ -30377,7 +30405,7 @@ function halftoneSharpen(px, w, h) {
|
|
|
30377
30405
|
}
|
|
30378
30406
|
}
|
|
30379
30407
|
}
|
|
30380
|
-
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
30408
|
+
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSampling = false, directDib = false) {
|
|
30381
30409
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
30382
30410
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
30383
30411
|
const SW = Math.round(Math.abs(sw));
|
|
@@ -30407,14 +30435,28 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
|
30407
30435
|
}
|
|
30408
30436
|
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
30409
30437
|
const reducing = W < SW && H < SH;
|
|
30410
|
-
|
|
30438
|
+
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
30439
|
+
if (enlarging && !directDib) {
|
|
30411
30440
|
halftoneDespeckle(rect, SW, SH);
|
|
30412
30441
|
}
|
|
30413
|
-
if (adjust) {
|
|
30442
|
+
if (adjust && !adjustAfterSampling) {
|
|
30414
30443
|
adjust(rect);
|
|
30415
30444
|
}
|
|
30416
30445
|
const cols = halftoneAxis(0, SW, W, flipX);
|
|
30417
30446
|
const rows = halftoneAxis(0, SH, H, flipY);
|
|
30447
|
+
if (mixed) {
|
|
30448
|
+
const linear = (taps, src2, dst, reverse) => {
|
|
30449
|
+
if (dst <= src2) return;
|
|
30450
|
+
for (let i = 0; i < dst; i++) {
|
|
30451
|
+
const position = Math.max(0, Math.min(src2 - 1, (i + 0.5) * src2 / dst - 0.5));
|
|
30452
|
+
const left = Math.floor(position), fraction = position - left;
|
|
30453
|
+
const at = (k) => reverse ? src2 - 1 - k : k;
|
|
30454
|
+
taps[i] = [[at(left), 1 - fraction], [at(Math.min(src2 - 1, left + 1)), fraction]];
|
|
30455
|
+
}
|
|
30456
|
+
};
|
|
30457
|
+
linear(cols, SW, W, flipX);
|
|
30458
|
+
linear(rows, SH, H, flipY);
|
|
30459
|
+
}
|
|
30418
30460
|
const out = new Int32Array(W * H * 3);
|
|
30419
30461
|
for (let y = 0; y < H; y++) {
|
|
30420
30462
|
const ys = rows[y];
|
|
@@ -30435,14 +30477,28 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
|
30435
30477
|
}
|
|
30436
30478
|
}
|
|
30437
30479
|
const o = (y * W + x) * 3;
|
|
30438
|
-
out[o] = Math.floor((2 * r + total) / (2 * total));
|
|
30439
|
-
out[o + 1] = Math.floor((2 * g + total) / (2 * total));
|
|
30440
|
-
out[o + 2] = Math.floor((2 * b + total) / (2 * total));
|
|
30480
|
+
out[o] = mixed ? Math.ceil(r / total - 0.5) : Math.floor((2 * r + total) / (2 * total));
|
|
30481
|
+
out[o + 1] = mixed ? Math.ceil(g / total - 0.5) : Math.floor((2 * g + total) / (2 * total));
|
|
30482
|
+
out[o + 2] = mixed ? Math.ceil(b / total - 0.5) : Math.floor((2 * b + total) / (2 * total));
|
|
30441
30483
|
}
|
|
30442
30484
|
}
|
|
30443
30485
|
if (reducing) {
|
|
30444
30486
|
halftoneSharpen(out, W, H);
|
|
30445
30487
|
}
|
|
30488
|
+
if (mixed) {
|
|
30489
|
+
const source = out.slice();
|
|
30490
|
+
const at = (x, y, c) => source[(Math.max(0, Math.min(H - 1, y)) * W + Math.max(0, Math.min(W - 1, x))) * 3 + c];
|
|
30491
|
+
for (let y = 0; y < H; y++) {
|
|
30492
|
+
for (let x = 0; x < W; x++) {
|
|
30493
|
+
for (let c = 0; c < 3; c++) {
|
|
30494
|
+
const v = at(x, y, c);
|
|
30495
|
+
const sum = W < SW ? at(x - 1, y, c) + at(x + 1, y, c) : at(x, y - 1, c) + at(x, y + 1, c);
|
|
30496
|
+
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, v + Math.floor((2 * v - sum) / 4)));
|
|
30497
|
+
}
|
|
30498
|
+
}
|
|
30499
|
+
}
|
|
30500
|
+
}
|
|
30501
|
+
if (adjust && adjustAfterSampling) adjust(out);
|
|
30446
30502
|
for (let i = 0, o = 0; i < W * H; i++, o += 3) {
|
|
30447
30503
|
data[i * 4] = out[o];
|
|
30448
30504
|
data[i * 4 + 1] = out[o + 1];
|
|
@@ -30474,7 +30530,18 @@ function patternOperand(rCtx, brush) {
|
|
|
30474
30530
|
function drawSourceMapped(target, decoded, req, offsetX, offsetY, mode) {
|
|
30475
30531
|
const dLeft = Math.min(req.dx, req.dx + req.dw) - offsetX;
|
|
30476
30532
|
const dTop = Math.min(req.dy, req.dy + req.dh) - offsetY;
|
|
30477
|
-
const px = mode === HALFTONE ? stretchHalftone(
|
|
30533
|
+
const px = mode === HALFTONE ? stretchHalftone(
|
|
30534
|
+
decoded.pixels,
|
|
30535
|
+
req.sx,
|
|
30536
|
+
req.sy,
|
|
30537
|
+
req.sw,
|
|
30538
|
+
req.sh,
|
|
30539
|
+
req.dw,
|
|
30540
|
+
req.dh,
|
|
30541
|
+
decoded.adjust,
|
|
30542
|
+
decoded.adjustAfterSampling,
|
|
30543
|
+
req.dibOrigin === "bottom-left"
|
|
30544
|
+
) : stretchGdi(decoded.pixels, req.sx, req.sy, req.sw, req.sh, req.dw, req.dh, mode);
|
|
30478
30545
|
if (px.width === 0 || px.height === 0) {
|
|
30479
30546
|
return;
|
|
30480
30547
|
}
|
|
@@ -30509,7 +30576,7 @@ function decodeSource(rCtx, req) {
|
|
|
30509
30576
|
sy = image.height - sy - req.sh;
|
|
30510
30577
|
}
|
|
30511
30578
|
return {
|
|
30512
|
-
decoded: { pixels: image, adjust },
|
|
30579
|
+
decoded: { pixels: image, adjust, adjustAfterSampling: isChannelOnlyColorAdjustment(ca) },
|
|
30513
30580
|
req: { ...req, sy }
|
|
30514
30581
|
};
|
|
30515
30582
|
}
|
|
@@ -37533,7 +37600,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
|
|
|
37533
37600
|
c.ellipse(cr.x + ex, cr.y + ey, ex, ey, 0, 2 * q, 3 * q);
|
|
37534
37601
|
c.closePath();
|
|
37535
37602
|
},
|
|
37536
|
-
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0),
|
|
37603
|
+
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, true),
|
|
37537
37604
|
roundPen: true,
|
|
37538
37605
|
fill: true,
|
|
37539
37606
|
stroke: true
|
package/dist/index.js
CHANGED
|
@@ -10332,6 +10332,16 @@ function decodeImageCodecFallback(bytes) {
|
|
|
10332
10332
|
if (!f || !validSize(f.image.descriptor.width, f.image.descriptor.height)) return null;
|
|
10333
10333
|
const frame2 = (0, import_gifuct_js.decompressFrame)(f, gif.gct, true);
|
|
10334
10334
|
const data = new Uint8ClampedArray(width * height * 4);
|
|
10335
|
+
const transparent = frame2.transparentIndex !== void 0;
|
|
10336
|
+
const background = transparent ? frame2.colorTable[frame2.transparentIndex] : gif.gct?.[gif.lsd.backgroundColorIndex];
|
|
10337
|
+
if (background) {
|
|
10338
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
10339
|
+
data[i] = background[0];
|
|
10340
|
+
data[i + 1] = background[1];
|
|
10341
|
+
data[i + 2] = background[2];
|
|
10342
|
+
data[i + 3] = transparent ? 0 : 255;
|
|
10343
|
+
}
|
|
10344
|
+
}
|
|
10335
10345
|
const { top, left, width: fw, height: fh } = frame2.dims;
|
|
10336
10346
|
for (let y = 0; y < fh && top + y < height; y++) {
|
|
10337
10347
|
const n = Math.min(fw, width - left);
|
|
@@ -10976,7 +10986,7 @@ function flattenBezierPath(pts) {
|
|
|
10976
10986
|
}
|
|
10977
10987
|
return out;
|
|
10978
10988
|
}
|
|
10979
|
-
function roundRectCorners(l, t, r, b, cw, ch) {
|
|
10989
|
+
function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
|
|
10980
10990
|
const w = r - l;
|
|
10981
10991
|
const h = b - t;
|
|
10982
10992
|
let ew = Math.min(Math.abs(cw), w);
|
|
@@ -10988,7 +10998,9 @@ function roundRectCorners(l, t, r, b, cw, ch) {
|
|
|
10988
10998
|
const hy = Math.floor(h / 2) - Math.floor((h - eh) / 2);
|
|
10989
10999
|
const topX = Math.floor(r - ew / 2);
|
|
10990
11000
|
const hx = r - topX;
|
|
10991
|
-
const
|
|
11001
|
+
const verticalControl = compatible ? Math.round(KAPPA * hy) : Math.floor(KAPPA * hy);
|
|
11002
|
+
const horizontalControl = Math.ceil(KAPPA * hx);
|
|
11003
|
+
const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
|
|
10992
11004
|
const mx = (x) => l + r - x;
|
|
10993
11005
|
const my = (y) => t + b - y;
|
|
10994
11006
|
return [
|
|
@@ -28488,9 +28500,9 @@ function boxFrame(box) {
|
|
|
28488
28500
|
const h = Math.round(Math.hypot(box.eyx, box.eyy));
|
|
28489
28501
|
return { l: 0, t: 0, r: w, b: h };
|
|
28490
28502
|
}
|
|
28491
|
-
function roundRectDeviceBeziers(box, cw, ch, clockwise = false) {
|
|
28503
|
+
function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = false) {
|
|
28492
28504
|
const f = boxFrame(box);
|
|
28493
|
-
const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch);
|
|
28505
|
+
const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible);
|
|
28494
28506
|
const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
|
|
28495
28507
|
const pts = [];
|
|
28496
28508
|
for (let i = 0; i < q.length; i += 2) {
|
|
@@ -28498,9 +28510,9 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false) {
|
|
|
28498
28510
|
}
|
|
28499
28511
|
return pts;
|
|
28500
28512
|
}
|
|
28501
|
-
function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false) {
|
|
28513
|
+
function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false, compatible = false) {
|
|
28502
28514
|
if (rectangle) return rectRasterPath(box, clockwise);
|
|
28503
|
-
const pts = roundRectDeviceBeziers(box, cw, ch, clockwise);
|
|
28515
|
+
const pts = roundRectDeviceBeziers(box, cw, ch, clockwise, compatible);
|
|
28504
28516
|
const path = new GdiRasterPath();
|
|
28505
28517
|
for (let c = 0; c < 4; c++) {
|
|
28506
28518
|
const o = c * 8;
|
|
@@ -30078,6 +30090,9 @@ function handleEmfGdiShapeRecord(rCtx, recType, dataOff, recSize) {
|
|
|
30078
30090
|
var CA_NEGATIVE = 1;
|
|
30079
30091
|
var CA_LOG_FILTER = 2;
|
|
30080
30092
|
var COLOR_ADJUSTMENT_SIZE = 24;
|
|
30093
|
+
function isChannelOnlyColorAdjustment(ca) {
|
|
30094
|
+
return !!ca && (ca.flags & ~CA_LOG_FILTER) === 0 && (ca.illuminant === 0 || ca.illuminant === 6) && ca.referenceBlack === 0 && ca.referenceWhite === 1e4 && ca.contrast === 0 && ca.brightness === 0 && ca.colorfulness === 0 && ca.redGreenTint === 0;
|
|
30095
|
+
}
|
|
30081
30096
|
function readColorAdjustment(view, off) {
|
|
30082
30097
|
const ca = {
|
|
30083
30098
|
flags: view.getUint16(off + 2, true),
|
|
@@ -30133,6 +30148,19 @@ function fromLightness(l) {
|
|
|
30133
30148
|
}
|
|
30134
30149
|
var clamp012 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
30135
30150
|
function colorAdjustmentMapper(ca) {
|
|
30151
|
+
if (ca.referenceBlack === 0 && ca.referenceWhite === 1e4 && ca.contrast === 0 && ca.brightness === 0 && ca.colorfulness === 0 && ca.redGreenTint === 0) {
|
|
30152
|
+
const tables = [ca.redGamma, ca.greenGamma, ca.blueGamma].map((gamma) => {
|
|
30153
|
+
const table = new Uint8Array(256);
|
|
30154
|
+
for (let i = 0; i < 256; i++) {
|
|
30155
|
+
const input = (ca.flags & CA_NEGATIVE) !== 0 ? 255 - i : i;
|
|
30156
|
+
let value = (input / 255) ** (gamma / 1e4);
|
|
30157
|
+
if ((ca.flags & CA_LOG_FILTER) !== 0) value = Math.log2(1 + 7 * value) / 3;
|
|
30158
|
+
table[i] = Math.round(value * 255);
|
|
30159
|
+
}
|
|
30160
|
+
return table;
|
|
30161
|
+
});
|
|
30162
|
+
return (rgb2) => tables[0][rgb2 >> 16 & 255] << 16 | tables[1][rgb2 >> 8 & 255] << 8 | tables[2][rgb2 & 255];
|
|
30163
|
+
}
|
|
30136
30164
|
const black = ca.referenceBlack / 1e4;
|
|
30137
30165
|
const span = Math.max(1e-6, ca.referenceWhite / 1e4 - black);
|
|
30138
30166
|
const gammas = [ca.redGamma / 1e4, ca.greenGamma / 1e4, ca.blueGamma / 1e4];
|
|
@@ -30156,7 +30184,7 @@ function colorAdjustmentMapper(ca) {
|
|
|
30156
30184
|
const out = (v, c) => {
|
|
30157
30185
|
v = clamp012(fromLightness(slope * lightness(clamp012(v)) + offset)) ** (1 / gammas[c]);
|
|
30158
30186
|
if (log) {
|
|
30159
|
-
v = Math.
|
|
30187
|
+
v = Math.log2(1 + 7 * v) / 3;
|
|
30160
30188
|
}
|
|
30161
30189
|
return Math.round(v * 255);
|
|
30162
30190
|
};
|
|
@@ -30380,7 +30408,7 @@ function halftoneSharpen(px, w, h) {
|
|
|
30380
30408
|
}
|
|
30381
30409
|
}
|
|
30382
30410
|
}
|
|
30383
|
-
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
30411
|
+
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSampling = false, directDib = false) {
|
|
30384
30412
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
30385
30413
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
30386
30414
|
const SW = Math.round(Math.abs(sw));
|
|
@@ -30410,14 +30438,28 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
|
30410
30438
|
}
|
|
30411
30439
|
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
30412
30440
|
const reducing = W < SW && H < SH;
|
|
30413
|
-
|
|
30441
|
+
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
30442
|
+
if (enlarging && !directDib) {
|
|
30414
30443
|
halftoneDespeckle(rect, SW, SH);
|
|
30415
30444
|
}
|
|
30416
|
-
if (adjust) {
|
|
30445
|
+
if (adjust && !adjustAfterSampling) {
|
|
30417
30446
|
adjust(rect);
|
|
30418
30447
|
}
|
|
30419
30448
|
const cols = halftoneAxis(0, SW, W, flipX);
|
|
30420
30449
|
const rows = halftoneAxis(0, SH, H, flipY);
|
|
30450
|
+
if (mixed) {
|
|
30451
|
+
const linear = (taps, src2, dst, reverse) => {
|
|
30452
|
+
if (dst <= src2) return;
|
|
30453
|
+
for (let i = 0; i < dst; i++) {
|
|
30454
|
+
const position = Math.max(0, Math.min(src2 - 1, (i + 0.5) * src2 / dst - 0.5));
|
|
30455
|
+
const left = Math.floor(position), fraction = position - left;
|
|
30456
|
+
const at = (k) => reverse ? src2 - 1 - k : k;
|
|
30457
|
+
taps[i] = [[at(left), 1 - fraction], [at(Math.min(src2 - 1, left + 1)), fraction]];
|
|
30458
|
+
}
|
|
30459
|
+
};
|
|
30460
|
+
linear(cols, SW, W, flipX);
|
|
30461
|
+
linear(rows, SH, H, flipY);
|
|
30462
|
+
}
|
|
30421
30463
|
const out = new Int32Array(W * H * 3);
|
|
30422
30464
|
for (let y = 0; y < H; y++) {
|
|
30423
30465
|
const ys = rows[y];
|
|
@@ -30438,14 +30480,28 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
|
30438
30480
|
}
|
|
30439
30481
|
}
|
|
30440
30482
|
const o = (y * W + x) * 3;
|
|
30441
|
-
out[o] = Math.floor((2 * r + total) / (2 * total));
|
|
30442
|
-
out[o + 1] = Math.floor((2 * g + total) / (2 * total));
|
|
30443
|
-
out[o + 2] = Math.floor((2 * b + total) / (2 * total));
|
|
30483
|
+
out[o] = mixed ? Math.ceil(r / total - 0.5) : Math.floor((2 * r + total) / (2 * total));
|
|
30484
|
+
out[o + 1] = mixed ? Math.ceil(g / total - 0.5) : Math.floor((2 * g + total) / (2 * total));
|
|
30485
|
+
out[o + 2] = mixed ? Math.ceil(b / total - 0.5) : Math.floor((2 * b + total) / (2 * total));
|
|
30444
30486
|
}
|
|
30445
30487
|
}
|
|
30446
30488
|
if (reducing) {
|
|
30447
30489
|
halftoneSharpen(out, W, H);
|
|
30448
30490
|
}
|
|
30491
|
+
if (mixed) {
|
|
30492
|
+
const source = out.slice();
|
|
30493
|
+
const at = (x, y, c) => source[(Math.max(0, Math.min(H - 1, y)) * W + Math.max(0, Math.min(W - 1, x))) * 3 + c];
|
|
30494
|
+
for (let y = 0; y < H; y++) {
|
|
30495
|
+
for (let x = 0; x < W; x++) {
|
|
30496
|
+
for (let c = 0; c < 3; c++) {
|
|
30497
|
+
const v = at(x, y, c);
|
|
30498
|
+
const sum = W < SW ? at(x - 1, y, c) + at(x + 1, y, c) : at(x, y - 1, c) + at(x, y + 1, c);
|
|
30499
|
+
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, v + Math.floor((2 * v - sum) / 4)));
|
|
30500
|
+
}
|
|
30501
|
+
}
|
|
30502
|
+
}
|
|
30503
|
+
}
|
|
30504
|
+
if (adjust && adjustAfterSampling) adjust(out);
|
|
30449
30505
|
for (let i = 0, o = 0; i < W * H; i++, o += 3) {
|
|
30450
30506
|
data[i * 4] = out[o];
|
|
30451
30507
|
data[i * 4 + 1] = out[o + 1];
|
|
@@ -30477,7 +30533,18 @@ function patternOperand(rCtx, brush) {
|
|
|
30477
30533
|
function drawSourceMapped(target, decoded, req, offsetX, offsetY, mode) {
|
|
30478
30534
|
const dLeft = Math.min(req.dx, req.dx + req.dw) - offsetX;
|
|
30479
30535
|
const dTop = Math.min(req.dy, req.dy + req.dh) - offsetY;
|
|
30480
|
-
const px = mode === HALFTONE ? stretchHalftone(
|
|
30536
|
+
const px = mode === HALFTONE ? stretchHalftone(
|
|
30537
|
+
decoded.pixels,
|
|
30538
|
+
req.sx,
|
|
30539
|
+
req.sy,
|
|
30540
|
+
req.sw,
|
|
30541
|
+
req.sh,
|
|
30542
|
+
req.dw,
|
|
30543
|
+
req.dh,
|
|
30544
|
+
decoded.adjust,
|
|
30545
|
+
decoded.adjustAfterSampling,
|
|
30546
|
+
req.dibOrigin === "bottom-left"
|
|
30547
|
+
) : stretchGdi(decoded.pixels, req.sx, req.sy, req.sw, req.sh, req.dw, req.dh, mode);
|
|
30481
30548
|
if (px.width === 0 || px.height === 0) {
|
|
30482
30549
|
return;
|
|
30483
30550
|
}
|
|
@@ -30512,7 +30579,7 @@ function decodeSource(rCtx, req) {
|
|
|
30512
30579
|
sy = image.height - sy - req.sh;
|
|
30513
30580
|
}
|
|
30514
30581
|
return {
|
|
30515
|
-
decoded: { pixels: image, adjust },
|
|
30582
|
+
decoded: { pixels: image, adjust, adjustAfterSampling: isChannelOnlyColorAdjustment(ca) },
|
|
30516
30583
|
req: { ...req, sy }
|
|
30517
30584
|
};
|
|
30518
30585
|
}
|
|
@@ -37536,7 +37603,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
|
|
|
37536
37603
|
c.ellipse(cr.x + ex, cr.y + ey, ex, ey, 0, 2 * q, 3 * q);
|
|
37537
37604
|
c.closePath();
|
|
37538
37605
|
},
|
|
37539
|
-
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0),
|
|
37606
|
+
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, true),
|
|
37540
37607
|
roundPen: true,
|
|
37541
37608
|
fill: true,
|
|
37542
37609
|
stroke: true
|
package/dist/index.mjs
CHANGED
|
@@ -10330,6 +10330,16 @@ function decodeImageCodecFallback(bytes) {
|
|
|
10330
10330
|
if (!f || !validSize(f.image.descriptor.width, f.image.descriptor.height)) return null;
|
|
10331
10331
|
const frame2 = (0, import_gifuct_js.decompressFrame)(f, gif.gct, true);
|
|
10332
10332
|
const data = new Uint8ClampedArray(width * height * 4);
|
|
10333
|
+
const transparent = frame2.transparentIndex !== void 0;
|
|
10334
|
+
const background = transparent ? frame2.colorTable[frame2.transparentIndex] : gif.gct?.[gif.lsd.backgroundColorIndex];
|
|
10335
|
+
if (background) {
|
|
10336
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
10337
|
+
data[i] = background[0];
|
|
10338
|
+
data[i + 1] = background[1];
|
|
10339
|
+
data[i + 2] = background[2];
|
|
10340
|
+
data[i + 3] = transparent ? 0 : 255;
|
|
10341
|
+
}
|
|
10342
|
+
}
|
|
10333
10343
|
const { top, left, width: fw, height: fh } = frame2.dims;
|
|
10334
10344
|
for (let y = 0; y < fh && top + y < height; y++) {
|
|
10335
10345
|
const n = Math.min(fw, width - left);
|
|
@@ -10974,7 +10984,7 @@ function flattenBezierPath(pts) {
|
|
|
10974
10984
|
}
|
|
10975
10985
|
return out;
|
|
10976
10986
|
}
|
|
10977
|
-
function roundRectCorners(l, t, r, b, cw, ch) {
|
|
10987
|
+
function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
|
|
10978
10988
|
const w = r - l;
|
|
10979
10989
|
const h = b - t;
|
|
10980
10990
|
let ew = Math.min(Math.abs(cw), w);
|
|
@@ -10986,7 +10996,9 @@ function roundRectCorners(l, t, r, b, cw, ch) {
|
|
|
10986
10996
|
const hy = Math.floor(h / 2) - Math.floor((h - eh) / 2);
|
|
10987
10997
|
const topX = Math.floor(r - ew / 2);
|
|
10988
10998
|
const hx = r - topX;
|
|
10989
|
-
const
|
|
10999
|
+
const verticalControl = compatible ? Math.round(KAPPA * hy) : Math.floor(KAPPA * hy);
|
|
11000
|
+
const horizontalControl = Math.ceil(KAPPA * hx);
|
|
11001
|
+
const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
|
|
10990
11002
|
const mx = (x) => l + r - x;
|
|
10991
11003
|
const my = (y) => t + b - y;
|
|
10992
11004
|
return [
|
|
@@ -28486,9 +28498,9 @@ function boxFrame(box) {
|
|
|
28486
28498
|
const h = Math.round(Math.hypot(box.eyx, box.eyy));
|
|
28487
28499
|
return { l: 0, t: 0, r: w, b: h };
|
|
28488
28500
|
}
|
|
28489
|
-
function roundRectDeviceBeziers(box, cw, ch, clockwise = false) {
|
|
28501
|
+
function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = false) {
|
|
28490
28502
|
const f = boxFrame(box);
|
|
28491
|
-
const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch);
|
|
28503
|
+
const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible);
|
|
28492
28504
|
const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
|
|
28493
28505
|
const pts = [];
|
|
28494
28506
|
for (let i = 0; i < q.length; i += 2) {
|
|
@@ -28496,9 +28508,9 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false) {
|
|
|
28496
28508
|
}
|
|
28497
28509
|
return pts;
|
|
28498
28510
|
}
|
|
28499
|
-
function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false) {
|
|
28511
|
+
function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false, compatible = false) {
|
|
28500
28512
|
if (rectangle) return rectRasterPath(box, clockwise);
|
|
28501
|
-
const pts = roundRectDeviceBeziers(box, cw, ch, clockwise);
|
|
28513
|
+
const pts = roundRectDeviceBeziers(box, cw, ch, clockwise, compatible);
|
|
28502
28514
|
const path = new GdiRasterPath();
|
|
28503
28515
|
for (let c = 0; c < 4; c++) {
|
|
28504
28516
|
const o = c * 8;
|
|
@@ -30076,6 +30088,9 @@ function handleEmfGdiShapeRecord(rCtx, recType, dataOff, recSize) {
|
|
|
30076
30088
|
var CA_NEGATIVE = 1;
|
|
30077
30089
|
var CA_LOG_FILTER = 2;
|
|
30078
30090
|
var COLOR_ADJUSTMENT_SIZE = 24;
|
|
30091
|
+
function isChannelOnlyColorAdjustment(ca) {
|
|
30092
|
+
return !!ca && (ca.flags & ~CA_LOG_FILTER) === 0 && (ca.illuminant === 0 || ca.illuminant === 6) && ca.referenceBlack === 0 && ca.referenceWhite === 1e4 && ca.contrast === 0 && ca.brightness === 0 && ca.colorfulness === 0 && ca.redGreenTint === 0;
|
|
30093
|
+
}
|
|
30079
30094
|
function readColorAdjustment(view, off) {
|
|
30080
30095
|
const ca = {
|
|
30081
30096
|
flags: view.getUint16(off + 2, true),
|
|
@@ -30131,6 +30146,19 @@ function fromLightness(l) {
|
|
|
30131
30146
|
}
|
|
30132
30147
|
var clamp012 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
30133
30148
|
function colorAdjustmentMapper(ca) {
|
|
30149
|
+
if (ca.referenceBlack === 0 && ca.referenceWhite === 1e4 && ca.contrast === 0 && ca.brightness === 0 && ca.colorfulness === 0 && ca.redGreenTint === 0) {
|
|
30150
|
+
const tables = [ca.redGamma, ca.greenGamma, ca.blueGamma].map((gamma) => {
|
|
30151
|
+
const table = new Uint8Array(256);
|
|
30152
|
+
for (let i = 0; i < 256; i++) {
|
|
30153
|
+
const input = (ca.flags & CA_NEGATIVE) !== 0 ? 255 - i : i;
|
|
30154
|
+
let value = (input / 255) ** (gamma / 1e4);
|
|
30155
|
+
if ((ca.flags & CA_LOG_FILTER) !== 0) value = Math.log2(1 + 7 * value) / 3;
|
|
30156
|
+
table[i] = Math.round(value * 255);
|
|
30157
|
+
}
|
|
30158
|
+
return table;
|
|
30159
|
+
});
|
|
30160
|
+
return (rgb2) => tables[0][rgb2 >> 16 & 255] << 16 | tables[1][rgb2 >> 8 & 255] << 8 | tables[2][rgb2 & 255];
|
|
30161
|
+
}
|
|
30134
30162
|
const black = ca.referenceBlack / 1e4;
|
|
30135
30163
|
const span = Math.max(1e-6, ca.referenceWhite / 1e4 - black);
|
|
30136
30164
|
const gammas = [ca.redGamma / 1e4, ca.greenGamma / 1e4, ca.blueGamma / 1e4];
|
|
@@ -30154,7 +30182,7 @@ function colorAdjustmentMapper(ca) {
|
|
|
30154
30182
|
const out = (v, c) => {
|
|
30155
30183
|
v = clamp012(fromLightness(slope * lightness(clamp012(v)) + offset)) ** (1 / gammas[c]);
|
|
30156
30184
|
if (log) {
|
|
30157
|
-
v = Math.
|
|
30185
|
+
v = Math.log2(1 + 7 * v) / 3;
|
|
30158
30186
|
}
|
|
30159
30187
|
return Math.round(v * 255);
|
|
30160
30188
|
};
|
|
@@ -30378,7 +30406,7 @@ function halftoneSharpen(px, w, h) {
|
|
|
30378
30406
|
}
|
|
30379
30407
|
}
|
|
30380
30408
|
}
|
|
30381
|
-
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
30409
|
+
function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust, adjustAfterSampling = false, directDib = false) {
|
|
30382
30410
|
const W = Math.max(0, Math.round(Math.abs(dw)));
|
|
30383
30411
|
const H = Math.max(0, Math.round(Math.abs(dh)));
|
|
30384
30412
|
const SW = Math.round(Math.abs(sw));
|
|
@@ -30408,14 +30436,28 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
|
30408
30436
|
}
|
|
30409
30437
|
const enlarging = W >= SW && H >= SH && (W > SW || H > SH);
|
|
30410
30438
|
const reducing = W < SW && H < SH;
|
|
30411
|
-
|
|
30439
|
+
const mixed = W > SW && H < SH || W < SW && H > SH;
|
|
30440
|
+
if (enlarging && !directDib) {
|
|
30412
30441
|
halftoneDespeckle(rect, SW, SH);
|
|
30413
30442
|
}
|
|
30414
|
-
if (adjust) {
|
|
30443
|
+
if (adjust && !adjustAfterSampling) {
|
|
30415
30444
|
adjust(rect);
|
|
30416
30445
|
}
|
|
30417
30446
|
const cols = halftoneAxis(0, SW, W, flipX);
|
|
30418
30447
|
const rows = halftoneAxis(0, SH, H, flipY);
|
|
30448
|
+
if (mixed) {
|
|
30449
|
+
const linear = (taps, src2, dst, reverse) => {
|
|
30450
|
+
if (dst <= src2) return;
|
|
30451
|
+
for (let i = 0; i < dst; i++) {
|
|
30452
|
+
const position = Math.max(0, Math.min(src2 - 1, (i + 0.5) * src2 / dst - 0.5));
|
|
30453
|
+
const left = Math.floor(position), fraction = position - left;
|
|
30454
|
+
const at = (k) => reverse ? src2 - 1 - k : k;
|
|
30455
|
+
taps[i] = [[at(left), 1 - fraction], [at(Math.min(src2 - 1, left + 1)), fraction]];
|
|
30456
|
+
}
|
|
30457
|
+
};
|
|
30458
|
+
linear(cols, SW, W, flipX);
|
|
30459
|
+
linear(rows, SH, H, flipY);
|
|
30460
|
+
}
|
|
30419
30461
|
const out = new Int32Array(W * H * 3);
|
|
30420
30462
|
for (let y = 0; y < H; y++) {
|
|
30421
30463
|
const ys = rows[y];
|
|
@@ -30436,14 +30478,28 @@ function stretchHalftone(src, sx, sy, sw, sh, dw, dh, adjust) {
|
|
|
30436
30478
|
}
|
|
30437
30479
|
}
|
|
30438
30480
|
const o = (y * W + x) * 3;
|
|
30439
|
-
out[o] = Math.floor((2 * r + total) / (2 * total));
|
|
30440
|
-
out[o + 1] = Math.floor((2 * g + total) / (2 * total));
|
|
30441
|
-
out[o + 2] = Math.floor((2 * b + total) / (2 * total));
|
|
30481
|
+
out[o] = mixed ? Math.ceil(r / total - 0.5) : Math.floor((2 * r + total) / (2 * total));
|
|
30482
|
+
out[o + 1] = mixed ? Math.ceil(g / total - 0.5) : Math.floor((2 * g + total) / (2 * total));
|
|
30483
|
+
out[o + 2] = mixed ? Math.ceil(b / total - 0.5) : Math.floor((2 * b + total) / (2 * total));
|
|
30442
30484
|
}
|
|
30443
30485
|
}
|
|
30444
30486
|
if (reducing) {
|
|
30445
30487
|
halftoneSharpen(out, W, H);
|
|
30446
30488
|
}
|
|
30489
|
+
if (mixed) {
|
|
30490
|
+
const source = out.slice();
|
|
30491
|
+
const at = (x, y, c) => source[(Math.max(0, Math.min(H - 1, y)) * W + Math.max(0, Math.min(W - 1, x))) * 3 + c];
|
|
30492
|
+
for (let y = 0; y < H; y++) {
|
|
30493
|
+
for (let x = 0; x < W; x++) {
|
|
30494
|
+
for (let c = 0; c < 3; c++) {
|
|
30495
|
+
const v = at(x, y, c);
|
|
30496
|
+
const sum = W < SW ? at(x - 1, y, c) + at(x + 1, y, c) : at(x, y - 1, c) + at(x, y + 1, c);
|
|
30497
|
+
out[(y * W + x) * 3 + c] = Math.max(0, Math.min(255, v + Math.floor((2 * v - sum) / 4)));
|
|
30498
|
+
}
|
|
30499
|
+
}
|
|
30500
|
+
}
|
|
30501
|
+
}
|
|
30502
|
+
if (adjust && adjustAfterSampling) adjust(out);
|
|
30447
30503
|
for (let i = 0, o = 0; i < W * H; i++, o += 3) {
|
|
30448
30504
|
data[i * 4] = out[o];
|
|
30449
30505
|
data[i * 4 + 1] = out[o + 1];
|
|
@@ -30475,7 +30531,18 @@ function patternOperand(rCtx, brush) {
|
|
|
30475
30531
|
function drawSourceMapped(target, decoded, req, offsetX, offsetY, mode) {
|
|
30476
30532
|
const dLeft = Math.min(req.dx, req.dx + req.dw) - offsetX;
|
|
30477
30533
|
const dTop = Math.min(req.dy, req.dy + req.dh) - offsetY;
|
|
30478
|
-
const px = mode === HALFTONE ? stretchHalftone(
|
|
30534
|
+
const px = mode === HALFTONE ? stretchHalftone(
|
|
30535
|
+
decoded.pixels,
|
|
30536
|
+
req.sx,
|
|
30537
|
+
req.sy,
|
|
30538
|
+
req.sw,
|
|
30539
|
+
req.sh,
|
|
30540
|
+
req.dw,
|
|
30541
|
+
req.dh,
|
|
30542
|
+
decoded.adjust,
|
|
30543
|
+
decoded.adjustAfterSampling,
|
|
30544
|
+
req.dibOrigin === "bottom-left"
|
|
30545
|
+
) : stretchGdi(decoded.pixels, req.sx, req.sy, req.sw, req.sh, req.dw, req.dh, mode);
|
|
30479
30546
|
if (px.width === 0 || px.height === 0) {
|
|
30480
30547
|
return;
|
|
30481
30548
|
}
|
|
@@ -30510,7 +30577,7 @@ function decodeSource(rCtx, req) {
|
|
|
30510
30577
|
sy = image.height - sy - req.sh;
|
|
30511
30578
|
}
|
|
30512
30579
|
return {
|
|
30513
|
-
decoded: { pixels: image, adjust },
|
|
30580
|
+
decoded: { pixels: image, adjust, adjustAfterSampling: isChannelOnlyColorAdjustment(ca) },
|
|
30514
30581
|
req: { ...req, sy }
|
|
30515
30582
|
};
|
|
30516
30583
|
}
|
|
@@ -37534,7 +37601,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
|
|
|
37534
37601
|
c.ellipse(cr.x + ex, cr.y + ey, ex, ey, 0, 2 * q, 3 * q);
|
|
37535
37602
|
c.closePath();
|
|
37536
37603
|
},
|
|
37537
|
-
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0),
|
|
37604
|
+
raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, true),
|
|
37538
37605
|
roundPen: true,
|
|
37539
37606
|
fill: true,
|
|
37540
37607
|
stroke: true
|