emf-converter 4.4.3 → 4.4.5

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 CHANGED
@@ -10985,7 +10985,7 @@ function flattenBezierPath(pts) {
10985
10985
  }
10986
10986
  return out;
10987
10987
  }
10988
- function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
10988
+ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = false) {
10989
10989
  const w = r - l;
10990
10990
  const h = b - t;
10991
10991
  let ew = Math.min(Math.abs(cw), w);
@@ -10994,10 +10994,10 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
10994
10994
  ew = 0;
10995
10995
  eh = 0;
10996
10996
  }
10997
- const hy = Math.floor(h / 2) - Math.floor((h - eh) / 2);
10998
- const topX = Math.floor(r - ew / 2);
10997
+ const hy = compatible ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
10998
+ const topX = compatible ? Math.round(r - ew / 2) : Math.floor(r - ew / 2);
10999
10999
  const hx = r - topX;
11000
- const verticalControl = compatible ? Math.round(KAPPA * hy) : Math.floor(KAPPA * hy);
11000
+ const verticalControl = compatible && clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11001
11001
  const horizontalControl = Math.ceil(KAPPA * hx);
11002
11002
  const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
11003
11003
  const mx = (x) => l + r - x;
@@ -15700,10 +15700,9 @@ function blurKernel(radius) {
15700
15700
  k[0] = 1;
15701
15701
  return k;
15702
15702
  }
15703
- const sigma = radius / 1.98;
15704
15703
  let sum = 0;
15705
15704
  for (let i = -taps; i <= taps; i++) {
15706
- const w = Math.exp(-(i * i) / (2 * sigma * sigma));
15705
+ const w = Math.exp(-1.96 * i * i / (radius * radius));
15707
15706
  k[i + taps] = w;
15708
15707
  sum += w;
15709
15708
  }
@@ -15724,6 +15723,8 @@ function mirror(p, n) {
15724
15723
  function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15725
15724
  const k = blurKernel(radius);
15726
15725
  const taps = (k.length - 1) / 2;
15726
+ const horizontalIndex = radius <= 16 && radius >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
15727
+ const verticalIndex = radius <= 16 && radius >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
15727
15728
  const out = new Float64Array(w * h * 4);
15728
15729
  for (let y = 0; y < h; y++) {
15729
15730
  const row = y * w * 4;
@@ -15733,7 +15734,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15733
15734
  let s2 = 0;
15734
15735
  let s3 = 0;
15735
15736
  for (let j = -taps; j <= taps; j++) {
15736
- const p = row + mirror(x + j, w) * 4;
15737
+ const p = row + horizontalIndex(x + j) * 4;
15737
15738
  const kw = k[j + taps];
15738
15739
  s0 += kw * src[p];
15739
15740
  s1 += kw * src[p + 1];
@@ -15741,38 +15742,37 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15741
15742
  s3 += kw * src[p + 3];
15742
15743
  }
15743
15744
  const o = row + x * 4;
15744
- out[o] = s0;
15745
- out[o + 1] = s1;
15746
- out[o + 2] = s2;
15747
- out[o + 3] = s3;
15745
+ out[o] = Math.round(s0);
15746
+ out[o + 1] = Math.round(s1);
15747
+ out[o + 2] = Math.round(s2);
15748
+ out[o + 3] = Math.round(s3);
15748
15749
  }
15749
15750
  }
15750
15751
  if (taps > 0 && vRow >= 0 && vRow < h) {
15751
- const col = new Float64Array(w * 4);
15752
- for (let j = -taps; j <= taps; j++) {
15753
- const yy = vRow + j;
15754
- if (vZeroAbove && yy < vRow) {
15755
- continue;
15756
- }
15757
- const base = mirror(yy, h) * w * 4;
15758
- for (let i = 0; i < w * 4; i++) {
15759
- col[i] += k[j + taps] * out[base + i];
15752
+ const horizontal = out.slice();
15753
+ const endRow = Math.min(h, vRow + (radius <= 16 ? Math.ceil(h / w) : 1));
15754
+ for (let row = vRow; row < endRow; row++) {
15755
+ const col = new Float64Array(w * 4);
15756
+ for (let j = -taps; j <= taps; j++) {
15757
+ const yy = row + j;
15758
+ if (vZeroAbove && yy < vRow) {
15759
+ continue;
15760
+ }
15761
+ const base = verticalIndex(yy) * w * 4;
15762
+ for (let i = 0; i < w * 4; i++) {
15763
+ col[i] += k[j + taps] * horizontal[base + i];
15764
+ }
15760
15765
  }
15766
+ out.set(col, row * w * 4);
15761
15767
  }
15762
- out.set(col, vRow * w * 4);
15763
15768
  }
15764
15769
  return out;
15765
15770
  }
15766
15771
  function applyBlur(src, w, h, radius) {
15767
15772
  return Uint8ClampedArray.from(gdipBlur(src, w, h, radius), Math.round);
15768
15773
  }
15769
- var SHARPEN_FALLOFF = Math.log2(96 / 25);
15770
- function sharpenGain(radius, amount) {
15771
- const x = amount / 100;
15772
- if (radius <= 3) {
15773
- return x * 2 * radius / 3;
15774
- }
15775
- return x * 2 * (3 / radius) ** SHARPEN_FALLOFF;
15774
+ function sharpenGain(_radius, amount) {
15775
+ return roundHalfDown(64 * amount / (250 - 2 * amount)) / 64;
15776
15776
  }
15777
15777
  function applySharpen(src, w, h, radius, amount) {
15778
15778
  const blurred = gdipBlur(src, w, h, radius);
@@ -28501,7 +28501,7 @@ function boxFrame(box) {
28501
28501
  }
28502
28502
  function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = false) {
28503
28503
  const f = boxFrame(box);
28504
- const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible);
28504
+ const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible, clockwise);
28505
28505
  const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
28506
28506
  const pts = [];
28507
28507
  for (let i = 0; i < q.length; i += 2) {
@@ -37561,12 +37561,16 @@ function wmfRectangle(p, l, t, r, b) {
37561
37561
  axisRect: { interior: rectInterior(p, box) }
37562
37562
  });
37563
37563
  }
37564
- function compatCorner(p, w, h) {
37564
+ function compatCorner(p, w, h, box) {
37565
37565
  const m = gdiDeviceMatrix(p.rCtx);
37566
37566
  const cw = Math.round(Math.abs(w * m[0]) * 16);
37567
37567
  const ch = Math.round(Math.abs(h * m[3]) * 16);
37568
37568
  const ux = 16 * p.kx;
37569
37569
  const uy = 16 * p.ky;
37570
+ if (!penIsNull(p) && penIsCosmetic(p.rCtx)) {
37571
+ const width = box.x1 - box.x0, height = box.y1 - box.y0;
37572
+ return [Math.min(cw, width + ux) * width / (width + ux), Math.min(ch, height + uy) * height / (height + uy)];
37573
+ }
37570
37574
  if (!penIsNull(p) && !penIsCosmetic(p.rCtx)) {
37571
37575
  return [Math.round(Math.floor(cw / (2 * ux)) * 2 * ux), Math.round(Math.floor(ch / (2 * uy)) * 2 * uy)];
37572
37576
  }
@@ -37577,7 +37581,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
37577
37581
  if (box.x1 < box.x0 || box.y1 < box.y0) {
37578
37582
  return;
37579
37583
  }
37580
- const [cw, ch] = compatCorner(p, w, h);
37584
+ const [cw, ch] = compatCorner(p, w, h, box);
37581
37585
  const cr = canvasRect(box);
37582
37586
  paintGdiShape(p.rCtx, {
37583
37587
  build: (c) => {
@@ -37602,7 +37606,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
37602
37606
  c.ellipse(cr.x + ex, cr.y + ey, ex, ey, 0, 2 * q, 3 * q);
37603
37607
  c.closePath();
37604
37608
  },
37605
- raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, true),
37609
+ raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, !penIsNull(p) && penIsCosmetic(p.rCtx)),
37606
37610
  roundPen: true,
37607
37611
  fill: true,
37608
37612
  stroke: true
package/dist/browser.mjs CHANGED
@@ -10983,7 +10983,7 @@ function flattenBezierPath(pts) {
10983
10983
  }
10984
10984
  return out;
10985
10985
  }
10986
- function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
10986
+ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = false) {
10987
10987
  const w = r - l;
10988
10988
  const h = b - t;
10989
10989
  let ew = Math.min(Math.abs(cw), w);
@@ -10992,10 +10992,10 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
10992
10992
  ew = 0;
10993
10993
  eh = 0;
10994
10994
  }
10995
- const hy = Math.floor(h / 2) - Math.floor((h - eh) / 2);
10996
- const topX = Math.floor(r - ew / 2);
10995
+ const hy = compatible ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
10996
+ const topX = compatible ? Math.round(r - ew / 2) : Math.floor(r - ew / 2);
10997
10997
  const hx = r - topX;
10998
- const verticalControl = compatible ? Math.round(KAPPA * hy) : Math.floor(KAPPA * hy);
10998
+ const verticalControl = compatible && clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
10999
10999
  const horizontalControl = Math.ceil(KAPPA * hx);
11000
11000
  const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
11001
11001
  const mx = (x) => l + r - x;
@@ -15698,10 +15698,9 @@ function blurKernel(radius) {
15698
15698
  k[0] = 1;
15699
15699
  return k;
15700
15700
  }
15701
- const sigma = radius / 1.98;
15702
15701
  let sum = 0;
15703
15702
  for (let i = -taps; i <= taps; i++) {
15704
- const w = Math.exp(-(i * i) / (2 * sigma * sigma));
15703
+ const w = Math.exp(-1.96 * i * i / (radius * radius));
15705
15704
  k[i + taps] = w;
15706
15705
  sum += w;
15707
15706
  }
@@ -15722,6 +15721,8 @@ function mirror(p, n) {
15722
15721
  function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15723
15722
  const k = blurKernel(radius);
15724
15723
  const taps = (k.length - 1) / 2;
15724
+ const horizontalIndex = radius <= 16 && radius >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
15725
+ const verticalIndex = radius <= 16 && radius >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
15725
15726
  const out = new Float64Array(w * h * 4);
15726
15727
  for (let y = 0; y < h; y++) {
15727
15728
  const row = y * w * 4;
@@ -15731,7 +15732,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15731
15732
  let s2 = 0;
15732
15733
  let s3 = 0;
15733
15734
  for (let j = -taps; j <= taps; j++) {
15734
- const p = row + mirror(x + j, w) * 4;
15735
+ const p = row + horizontalIndex(x + j) * 4;
15735
15736
  const kw = k[j + taps];
15736
15737
  s0 += kw * src[p];
15737
15738
  s1 += kw * src[p + 1];
@@ -15739,38 +15740,37 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15739
15740
  s3 += kw * src[p + 3];
15740
15741
  }
15741
15742
  const o = row + x * 4;
15742
- out[o] = s0;
15743
- out[o + 1] = s1;
15744
- out[o + 2] = s2;
15745
- out[o + 3] = s3;
15743
+ out[o] = Math.round(s0);
15744
+ out[o + 1] = Math.round(s1);
15745
+ out[o + 2] = Math.round(s2);
15746
+ out[o + 3] = Math.round(s3);
15746
15747
  }
15747
15748
  }
15748
15749
  if (taps > 0 && vRow >= 0 && vRow < h) {
15749
- const col = new Float64Array(w * 4);
15750
- for (let j = -taps; j <= taps; j++) {
15751
- const yy = vRow + j;
15752
- if (vZeroAbove && yy < vRow) {
15753
- continue;
15754
- }
15755
- const base = mirror(yy, h) * w * 4;
15756
- for (let i = 0; i < w * 4; i++) {
15757
- col[i] += k[j + taps] * out[base + i];
15750
+ const horizontal = out.slice();
15751
+ const endRow = Math.min(h, vRow + (radius <= 16 ? Math.ceil(h / w) : 1));
15752
+ for (let row = vRow; row < endRow; row++) {
15753
+ const col = new Float64Array(w * 4);
15754
+ for (let j = -taps; j <= taps; j++) {
15755
+ const yy = row + j;
15756
+ if (vZeroAbove && yy < vRow) {
15757
+ continue;
15758
+ }
15759
+ const base = verticalIndex(yy) * w * 4;
15760
+ for (let i = 0; i < w * 4; i++) {
15761
+ col[i] += k[j + taps] * horizontal[base + i];
15762
+ }
15758
15763
  }
15764
+ out.set(col, row * w * 4);
15759
15765
  }
15760
- out.set(col, vRow * w * 4);
15761
15766
  }
15762
15767
  return out;
15763
15768
  }
15764
15769
  function applyBlur(src, w, h, radius) {
15765
15770
  return Uint8ClampedArray.from(gdipBlur(src, w, h, radius), Math.round);
15766
15771
  }
15767
- var SHARPEN_FALLOFF = Math.log2(96 / 25);
15768
- function sharpenGain(radius, amount) {
15769
- const x = amount / 100;
15770
- if (radius <= 3) {
15771
- return x * 2 * radius / 3;
15772
- }
15773
- return x * 2 * (3 / radius) ** SHARPEN_FALLOFF;
15772
+ function sharpenGain(_radius, amount) {
15773
+ return roundHalfDown(64 * amount / (250 - 2 * amount)) / 64;
15774
15774
  }
15775
15775
  function applySharpen(src, w, h, radius, amount) {
15776
15776
  const blurred = gdipBlur(src, w, h, radius);
@@ -28499,7 +28499,7 @@ function boxFrame(box) {
28499
28499
  }
28500
28500
  function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = false) {
28501
28501
  const f = boxFrame(box);
28502
- const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible);
28502
+ const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible, clockwise);
28503
28503
  const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
28504
28504
  const pts = [];
28505
28505
  for (let i = 0; i < q.length; i += 2) {
@@ -37559,12 +37559,16 @@ function wmfRectangle(p, l, t, r, b) {
37559
37559
  axisRect: { interior: rectInterior(p, box) }
37560
37560
  });
37561
37561
  }
37562
- function compatCorner(p, w, h) {
37562
+ function compatCorner(p, w, h, box) {
37563
37563
  const m = gdiDeviceMatrix(p.rCtx);
37564
37564
  const cw = Math.round(Math.abs(w * m[0]) * 16);
37565
37565
  const ch = Math.round(Math.abs(h * m[3]) * 16);
37566
37566
  const ux = 16 * p.kx;
37567
37567
  const uy = 16 * p.ky;
37568
+ if (!penIsNull(p) && penIsCosmetic(p.rCtx)) {
37569
+ const width = box.x1 - box.x0, height = box.y1 - box.y0;
37570
+ return [Math.min(cw, width + ux) * width / (width + ux), Math.min(ch, height + uy) * height / (height + uy)];
37571
+ }
37568
37572
  if (!penIsNull(p) && !penIsCosmetic(p.rCtx)) {
37569
37573
  return [Math.round(Math.floor(cw / (2 * ux)) * 2 * ux), Math.round(Math.floor(ch / (2 * uy)) * 2 * uy)];
37570
37574
  }
@@ -37575,7 +37579,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
37575
37579
  if (box.x1 < box.x0 || box.y1 < box.y0) {
37576
37580
  return;
37577
37581
  }
37578
- const [cw, ch] = compatCorner(p, w, h);
37582
+ const [cw, ch] = compatCorner(p, w, h, box);
37579
37583
  const cr = canvasRect(box);
37580
37584
  paintGdiShape(p.rCtx, {
37581
37585
  build: (c) => {
@@ -37600,7 +37604,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
37600
37604
  c.ellipse(cr.x + ex, cr.y + ey, ex, ey, 0, 2 * q, 3 * q);
37601
37605
  c.closePath();
37602
37606
  },
37603
- raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, true),
37607
+ raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, !penIsNull(p) && penIsCosmetic(p.rCtx)),
37604
37608
  roundPen: true,
37605
37609
  fill: true,
37606
37610
  stroke: true
package/dist/index.js CHANGED
@@ -10986,7 +10986,7 @@ function flattenBezierPath(pts) {
10986
10986
  }
10987
10987
  return out;
10988
10988
  }
10989
- function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
10989
+ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = false) {
10990
10990
  const w = r - l;
10991
10991
  const h = b - t;
10992
10992
  let ew = Math.min(Math.abs(cw), w);
@@ -10995,10 +10995,10 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
10995
10995
  ew = 0;
10996
10996
  eh = 0;
10997
10997
  }
10998
- const hy = Math.floor(h / 2) - Math.floor((h - eh) / 2);
10999
- const topX = Math.floor(r - ew / 2);
10998
+ const hy = compatible ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
10999
+ const topX = compatible ? Math.round(r - ew / 2) : Math.floor(r - ew / 2);
11000
11000
  const hx = r - topX;
11001
- const verticalControl = compatible ? Math.round(KAPPA * hy) : Math.floor(KAPPA * hy);
11001
+ const verticalControl = compatible && clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11002
11002
  const horizontalControl = Math.ceil(KAPPA * hx);
11003
11003
  const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
11004
11004
  const mx = (x) => l + r - x;
@@ -15701,10 +15701,9 @@ function blurKernel(radius) {
15701
15701
  k[0] = 1;
15702
15702
  return k;
15703
15703
  }
15704
- const sigma = radius / 1.98;
15705
15704
  let sum = 0;
15706
15705
  for (let i = -taps; i <= taps; i++) {
15707
- const w = Math.exp(-(i * i) / (2 * sigma * sigma));
15706
+ const w = Math.exp(-1.96 * i * i / (radius * radius));
15708
15707
  k[i + taps] = w;
15709
15708
  sum += w;
15710
15709
  }
@@ -15725,6 +15724,8 @@ function mirror(p, n) {
15725
15724
  function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15726
15725
  const k = blurKernel(radius);
15727
15726
  const taps = (k.length - 1) / 2;
15727
+ const horizontalIndex = radius <= 16 && radius >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
15728
+ const verticalIndex = radius <= 16 && radius >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
15728
15729
  const out = new Float64Array(w * h * 4);
15729
15730
  for (let y = 0; y < h; y++) {
15730
15731
  const row = y * w * 4;
@@ -15734,7 +15735,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15734
15735
  let s2 = 0;
15735
15736
  let s3 = 0;
15736
15737
  for (let j = -taps; j <= taps; j++) {
15737
- const p = row + mirror(x + j, w) * 4;
15738
+ const p = row + horizontalIndex(x + j) * 4;
15738
15739
  const kw = k[j + taps];
15739
15740
  s0 += kw * src[p];
15740
15741
  s1 += kw * src[p + 1];
@@ -15742,38 +15743,37 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15742
15743
  s3 += kw * src[p + 3];
15743
15744
  }
15744
15745
  const o = row + x * 4;
15745
- out[o] = s0;
15746
- out[o + 1] = s1;
15747
- out[o + 2] = s2;
15748
- out[o + 3] = s3;
15746
+ out[o] = Math.round(s0);
15747
+ out[o + 1] = Math.round(s1);
15748
+ out[o + 2] = Math.round(s2);
15749
+ out[o + 3] = Math.round(s3);
15749
15750
  }
15750
15751
  }
15751
15752
  if (taps > 0 && vRow >= 0 && vRow < h) {
15752
- const col = new Float64Array(w * 4);
15753
- for (let j = -taps; j <= taps; j++) {
15754
- const yy = vRow + j;
15755
- if (vZeroAbove && yy < vRow) {
15756
- continue;
15757
- }
15758
- const base = mirror(yy, h) * w * 4;
15759
- for (let i = 0; i < w * 4; i++) {
15760
- col[i] += k[j + taps] * out[base + i];
15753
+ const horizontal = out.slice();
15754
+ const endRow = Math.min(h, vRow + (radius <= 16 ? Math.ceil(h / w) : 1));
15755
+ for (let row = vRow; row < endRow; row++) {
15756
+ const col = new Float64Array(w * 4);
15757
+ for (let j = -taps; j <= taps; j++) {
15758
+ const yy = row + j;
15759
+ if (vZeroAbove && yy < vRow) {
15760
+ continue;
15761
+ }
15762
+ const base = verticalIndex(yy) * w * 4;
15763
+ for (let i = 0; i < w * 4; i++) {
15764
+ col[i] += k[j + taps] * horizontal[base + i];
15765
+ }
15761
15766
  }
15767
+ out.set(col, row * w * 4);
15762
15768
  }
15763
- out.set(col, vRow * w * 4);
15764
15769
  }
15765
15770
  return out;
15766
15771
  }
15767
15772
  function applyBlur(src, w, h, radius) {
15768
15773
  return Uint8ClampedArray.from(gdipBlur(src, w, h, radius), Math.round);
15769
15774
  }
15770
- var SHARPEN_FALLOFF = Math.log2(96 / 25);
15771
- function sharpenGain(radius, amount) {
15772
- const x = amount / 100;
15773
- if (radius <= 3) {
15774
- return x * 2 * radius / 3;
15775
- }
15776
- return x * 2 * (3 / radius) ** SHARPEN_FALLOFF;
15775
+ function sharpenGain(_radius, amount) {
15776
+ return roundHalfDown(64 * amount / (250 - 2 * amount)) / 64;
15777
15777
  }
15778
15778
  function applySharpen(src, w, h, radius, amount) {
15779
15779
  const blurred = gdipBlur(src, w, h, radius);
@@ -28502,7 +28502,7 @@ function boxFrame(box) {
28502
28502
  }
28503
28503
  function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = false) {
28504
28504
  const f = boxFrame(box);
28505
- const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible);
28505
+ const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible, clockwise);
28506
28506
  const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
28507
28507
  const pts = [];
28508
28508
  for (let i = 0; i < q.length; i += 2) {
@@ -37562,12 +37562,16 @@ function wmfRectangle(p, l, t, r, b) {
37562
37562
  axisRect: { interior: rectInterior(p, box) }
37563
37563
  });
37564
37564
  }
37565
- function compatCorner(p, w, h) {
37565
+ function compatCorner(p, w, h, box) {
37566
37566
  const m = gdiDeviceMatrix(p.rCtx);
37567
37567
  const cw = Math.round(Math.abs(w * m[0]) * 16);
37568
37568
  const ch = Math.round(Math.abs(h * m[3]) * 16);
37569
37569
  const ux = 16 * p.kx;
37570
37570
  const uy = 16 * p.ky;
37571
+ if (!penIsNull(p) && penIsCosmetic(p.rCtx)) {
37572
+ const width = box.x1 - box.x0, height = box.y1 - box.y0;
37573
+ return [Math.min(cw, width + ux) * width / (width + ux), Math.min(ch, height + uy) * height / (height + uy)];
37574
+ }
37571
37575
  if (!penIsNull(p) && !penIsCosmetic(p.rCtx)) {
37572
37576
  return [Math.round(Math.floor(cw / (2 * ux)) * 2 * ux), Math.round(Math.floor(ch / (2 * uy)) * 2 * uy)];
37573
37577
  }
@@ -37578,7 +37582,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
37578
37582
  if (box.x1 < box.x0 || box.y1 < box.y0) {
37579
37583
  return;
37580
37584
  }
37581
- const [cw, ch] = compatCorner(p, w, h);
37585
+ const [cw, ch] = compatCorner(p, w, h, box);
37582
37586
  const cr = canvasRect(box);
37583
37587
  paintGdiShape(p.rCtx, {
37584
37588
  build: (c) => {
@@ -37603,7 +37607,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
37603
37607
  c.ellipse(cr.x + ex, cr.y + ey, ex, ey, 0, 2 * q, 3 * q);
37604
37608
  c.closePath();
37605
37609
  },
37606
- raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, true),
37610
+ raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, !penIsNull(p) && penIsCosmetic(p.rCtx)),
37607
37611
  roundPen: true,
37608
37612
  fill: true,
37609
37613
  stroke: true
package/dist/index.mjs CHANGED
@@ -10984,7 +10984,7 @@ function flattenBezierPath(pts) {
10984
10984
  }
10985
10985
  return out;
10986
10986
  }
10987
- function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
10987
+ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = false) {
10988
10988
  const w = r - l;
10989
10989
  const h = b - t;
10990
10990
  let ew = Math.min(Math.abs(cw), w);
@@ -10993,10 +10993,10 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false) {
10993
10993
  ew = 0;
10994
10994
  eh = 0;
10995
10995
  }
10996
- const hy = Math.floor(h / 2) - Math.floor((h - eh) / 2);
10997
- const topX = Math.floor(r - ew / 2);
10996
+ const hy = compatible ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
10997
+ const topX = compatible ? Math.round(r - ew / 2) : Math.floor(r - ew / 2);
10998
10998
  const hx = r - topX;
10999
- const verticalControl = compatible ? Math.round(KAPPA * hy) : Math.floor(KAPPA * hy);
10999
+ const verticalControl = compatible && clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11000
11000
  const horizontalControl = Math.ceil(KAPPA * hx);
11001
11001
  const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
11002
11002
  const mx = (x) => l + r - x;
@@ -15699,10 +15699,9 @@ function blurKernel(radius) {
15699
15699
  k[0] = 1;
15700
15700
  return k;
15701
15701
  }
15702
- const sigma = radius / 1.98;
15703
15702
  let sum = 0;
15704
15703
  for (let i = -taps; i <= taps; i++) {
15705
- const w = Math.exp(-(i * i) / (2 * sigma * sigma));
15704
+ const w = Math.exp(-1.96 * i * i / (radius * radius));
15706
15705
  k[i + taps] = w;
15707
15706
  sum += w;
15708
15707
  }
@@ -15723,6 +15722,8 @@ function mirror(p, n) {
15723
15722
  function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15724
15723
  const k = blurKernel(radius);
15725
15724
  const taps = (k.length - 1) / 2;
15725
+ const horizontalIndex = radius <= 16 && radius >= w ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
15726
+ const verticalIndex = radius <= 16 && radius >= h ? (y) => Math.max(0, Math.min(h - 1, y)) : (y) => mirror(y, h);
15726
15727
  const out = new Float64Array(w * h * 4);
15727
15728
  for (let y = 0; y < h; y++) {
15728
15729
  const row = y * w * 4;
@@ -15732,7 +15733,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15732
15733
  let s2 = 0;
15733
15734
  let s3 = 0;
15734
15735
  for (let j = -taps; j <= taps; j++) {
15735
- const p = row + mirror(x + j, w) * 4;
15736
+ const p = row + horizontalIndex(x + j) * 4;
15736
15737
  const kw = k[j + taps];
15737
15738
  s0 += kw * src[p];
15738
15739
  s1 += kw * src[p + 1];
@@ -15740,38 +15741,37 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false) {
15740
15741
  s3 += kw * src[p + 3];
15741
15742
  }
15742
15743
  const o = row + x * 4;
15743
- out[o] = s0;
15744
- out[o + 1] = s1;
15745
- out[o + 2] = s2;
15746
- out[o + 3] = s3;
15744
+ out[o] = Math.round(s0);
15745
+ out[o + 1] = Math.round(s1);
15746
+ out[o + 2] = Math.round(s2);
15747
+ out[o + 3] = Math.round(s3);
15747
15748
  }
15748
15749
  }
15749
15750
  if (taps > 0 && vRow >= 0 && vRow < h) {
15750
- const col = new Float64Array(w * 4);
15751
- for (let j = -taps; j <= taps; j++) {
15752
- const yy = vRow + j;
15753
- if (vZeroAbove && yy < vRow) {
15754
- continue;
15755
- }
15756
- const base = mirror(yy, h) * w * 4;
15757
- for (let i = 0; i < w * 4; i++) {
15758
- col[i] += k[j + taps] * out[base + i];
15751
+ const horizontal = out.slice();
15752
+ const endRow = Math.min(h, vRow + (radius <= 16 ? Math.ceil(h / w) : 1));
15753
+ for (let row = vRow; row < endRow; row++) {
15754
+ const col = new Float64Array(w * 4);
15755
+ for (let j = -taps; j <= taps; j++) {
15756
+ const yy = row + j;
15757
+ if (vZeroAbove && yy < vRow) {
15758
+ continue;
15759
+ }
15760
+ const base = verticalIndex(yy) * w * 4;
15761
+ for (let i = 0; i < w * 4; i++) {
15762
+ col[i] += k[j + taps] * horizontal[base + i];
15763
+ }
15759
15764
  }
15765
+ out.set(col, row * w * 4);
15760
15766
  }
15761
- out.set(col, vRow * w * 4);
15762
15767
  }
15763
15768
  return out;
15764
15769
  }
15765
15770
  function applyBlur(src, w, h, radius) {
15766
15771
  return Uint8ClampedArray.from(gdipBlur(src, w, h, radius), Math.round);
15767
15772
  }
15768
- var SHARPEN_FALLOFF = Math.log2(96 / 25);
15769
- function sharpenGain(radius, amount) {
15770
- const x = amount / 100;
15771
- if (radius <= 3) {
15772
- return x * 2 * radius / 3;
15773
- }
15774
- return x * 2 * (3 / radius) ** SHARPEN_FALLOFF;
15773
+ function sharpenGain(_radius, amount) {
15774
+ return roundHalfDown(64 * amount / (250 - 2 * amount)) / 64;
15775
15775
  }
15776
15776
  function applySharpen(src, w, h, radius, amount) {
15777
15777
  const blurred = gdipBlur(src, w, h, radius);
@@ -28500,7 +28500,7 @@ function boxFrame(box) {
28500
28500
  }
28501
28501
  function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = false) {
28502
28502
  const f = boxFrame(box);
28503
- const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible);
28503
+ const q = roundRectCorners(f.l, f.t, f.r, f.b, cw, ch, compatible, clockwise);
28504
28504
  const map = frameMapper(box, f.l, f.t, f.r - f.l, f.b - f.t);
28505
28505
  const pts = [];
28506
28506
  for (let i = 0; i < q.length; i += 2) {
@@ -37560,12 +37560,16 @@ function wmfRectangle(p, l, t, r, b) {
37560
37560
  axisRect: { interior: rectInterior(p, box) }
37561
37561
  });
37562
37562
  }
37563
- function compatCorner(p, w, h) {
37563
+ function compatCorner(p, w, h, box) {
37564
37564
  const m = gdiDeviceMatrix(p.rCtx);
37565
37565
  const cw = Math.round(Math.abs(w * m[0]) * 16);
37566
37566
  const ch = Math.round(Math.abs(h * m[3]) * 16);
37567
37567
  const ux = 16 * p.kx;
37568
37568
  const uy = 16 * p.ky;
37569
+ if (!penIsNull(p) && penIsCosmetic(p.rCtx)) {
37570
+ const width = box.x1 - box.x0, height = box.y1 - box.y0;
37571
+ return [Math.min(cw, width + ux) * width / (width + ux), Math.min(ch, height + uy) * height / (height + uy)];
37572
+ }
37569
37573
  if (!penIsNull(p) && !penIsCosmetic(p.rCtx)) {
37570
37574
  return [Math.round(Math.floor(cw / (2 * ux)) * 2 * ux), Math.round(Math.floor(ch / (2 * uy)) * 2 * uy)];
37571
37575
  }
@@ -37576,7 +37580,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
37576
37580
  if (box.x1 < box.x0 || box.y1 < box.y0) {
37577
37581
  return;
37578
37582
  }
37579
- const [cw, ch] = compatCorner(p, w, h);
37583
+ const [cw, ch] = compatCorner(p, w, h, box);
37580
37584
  const cr = canvasRect(box);
37581
37585
  paintGdiShape(p.rCtx, {
37582
37586
  build: (c) => {
@@ -37601,7 +37605,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
37601
37605
  c.ellipse(cr.x + ex, cr.y + ey, ex, ey, 0, 2 * q, 3 * q);
37602
37606
  c.closePath();
37603
37607
  },
37604
- raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, true),
37608
+ raster: () => roundRectRasterPath(fixBoxOf(box), cw, ch, clockwiseOf(p), w === 0 || h === 0, !penIsNull(p) && penIsCosmetic(p.rCtx)),
37605
37609
  roundPen: true,
37606
37610
  fill: true,
37607
37611
  stroke: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emf-converter",
3
- "version": "4.4.3",
3
+ "version": "4.4.5",
4
4
  "description": "Convert EMF/WMF metafile binaries to PNG data URLs or SVG (markup, data URL, React/JSX)",
5
5
  "keywords": [
6
6
  "canvas",