emf-converter 4.8.13 → 4.8.15

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
@@ -11732,10 +11732,10 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = fa
11732
11732
  ew = 0;
11733
11733
  eh = 0;
11734
11734
  }
11735
- const hy = compatible ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
11735
+ const hy = compatible || clockwise ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
11736
11736
  const topX = compatible ? Math.round(r - ew / 2) : Math.floor(r - ew / 2);
11737
11737
  const hx = r - topX;
11738
- const verticalControl = compatible && clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11738
+ const verticalControl = clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11739
11739
  const horizontalControl = Math.ceil(KAPPA * hx);
11740
11740
  const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
11741
11741
  const mx = (x) => l + r - x;
@@ -16707,7 +16707,8 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
16707
16707
  const meanDark = sectorDark[s] / sectorCount[s];
16708
16708
  const ratio = meanDark > 0 ? dark[k] / meanDark : 1;
16709
16709
  const u = distance[k] / radius;
16710
- const falloff = Math.max(strength * (1 - u) * (1 - u), 0.5 * Math.max(0, 1 - ratio) ** 2);
16710
+ const darknessFalloff = ratio < 2 ? 0.5 * (1 - ratio) ** 2 : 0;
16711
+ const falloff = Math.max(strength * (1 - u) * (1 - u), darknessFalloff);
16711
16712
  const rest = (1 - falloff) * mean;
16712
16713
  if (rest >= v) {
16713
16714
  continue;
@@ -20433,7 +20434,7 @@ function axisFilter(kernel, scale, copy) {
20433
20434
  return { radius: 0.5, weight: (i, c) => Math.floor(c + 0.5) === i ? 1 : 0 };
20434
20435
  }
20435
20436
  }
20436
- function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge = { wrap: void 0, clamp: null }) {
20437
+ function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge = { wrap: void 0, clamp: null }, integerBicubic = false) {
20437
20438
  const [outer0, outerW, inner0, innerW] = verticalFirst ? [iu0, wu, iv0, wv] : [iv0, wv, iu0, wu];
20438
20439
  const [oMin, oMax, iMin, iMax] = verticalFirst ? [box.x0, box.x1, box.y0, box.y1] : [box.y0, box.y1, box.x0, box.x1];
20439
20440
  let r = 0;
@@ -20474,11 +20475,17 @@ function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge
20474
20475
  }
20475
20476
  const alpha = px[s + 3];
20476
20477
  const wa = wi * alpha / 255;
20477
- lr += wa * px[s];
20478
- lg += wa * px[s + 1];
20479
- lb += wa * px[s + 2];
20478
+ lr += integerBicubic ? wi * Math.round(alpha * px[s] / 255) : wa * px[s];
20479
+ lg += integerBicubic ? wi * Math.round(alpha * px[s + 1] / 255) : wa * px[s + 1];
20480
+ lb += integerBicubic ? wi * Math.round(alpha * px[s + 2] / 255) : wa * px[s + 2];
20480
20481
  la += wi * alpha;
20481
20482
  }
20483
+ if (integerBicubic) {
20484
+ lr = Math.trunc(lr);
20485
+ lg = Math.trunc(lg);
20486
+ lb = Math.trunc(lb);
20487
+ la = Math.trunc(la);
20488
+ }
20482
20489
  la = Math.min(255, Math.max(0, la));
20483
20490
  r += wo * Math.min(la, Math.max(0, lr));
20484
20491
  g += wo * Math.min(la, Math.max(0, lg));
@@ -20526,6 +20533,7 @@ function resampleImage(rgba, width, height, spec, surface) {
20526
20533
  let kernel = spec.kernel;
20527
20534
  const hq = kernel === "hq-bilinear" || kernel === "hq-bicubic";
20528
20535
  const axisAligned = m[1] === 0 && m[2] === 0;
20536
+ const integerBicubic = kernel === "bicubic" && axisAligned;
20529
20537
  let farFade = false;
20530
20538
  let shiftX = 0;
20531
20539
  let shiftY = 0;
@@ -20607,12 +20615,17 @@ function resampleImage(rgba, width, height, spec, surface) {
20607
20615
  mirrorX: spec.wrap === "tile-flip-x" || spec.wrap === "tile-flip-xy",
20608
20616
  mirrorY: spec.wrap === "tile-flip-y" || spec.wrap === "tile-flip-xy"
20609
20617
  };
20618
+ const bicubicDu = Math.round(inv2[0] * FIX16);
20619
+ const bicubicDv = Math.round(inv2[1] * FIX16);
20610
20620
  for (let j = 0; j < h; j++) {
20611
20621
  const py = by0 + j + o;
20622
+ let start = -1;
20623
+ let su = 0;
20624
+ let sv = 0;
20612
20625
  for (let i = 0; i < w; i++) {
20613
20626
  const px = bx0 + i + o;
20614
- const u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
20615
- const v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
20627
+ let u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
20628
+ let v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
20616
20629
  const cx = px + COVERAGE_NUDGE_X;
20617
20630
  const cy = py + COVERAGE_NUDGE_Y;
20618
20631
  const eu = inv2[0] * cx + inv2[2] * cy + inv2[4];
@@ -20620,6 +20633,15 @@ function resampleImage(rgba, width, height, spec, surface) {
20620
20633
  if (eu < spec.srcX || ev < spec.srcY || eu >= uMax || ev >= vMax) {
20621
20634
  continue;
20622
20635
  }
20636
+ if (integerBicubic) {
20637
+ if (start < 0) {
20638
+ start = i;
20639
+ su = Math.round(u * FIX16);
20640
+ sv = Math.round(v * FIX16);
20641
+ }
20642
+ u = Math.floor((su + (i - start) * bicubicDu) / (FIX16 / 64)) / 64;
20643
+ v = Math.floor((sv + (i - start) * bicubicDv) / (FIX16 / 64)) / 64;
20644
+ }
20623
20645
  const box = { x0: 0, y0: 0, x1: width, y1: height };
20624
20646
  const sampleAt = (cu, cv) => {
20625
20647
  const iu0 = Math.ceil(cu - fu.radius);
@@ -20634,7 +20656,7 @@ function resampleImage(rgba, width, height, spec, surface) {
20634
20656
  for (let t = iv0; t <= iv1; t++) {
20635
20657
  wv.push(fv.weight(t, cv));
20636
20658
  }
20637
- return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge);
20659
+ return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge, integerBicubic);
20638
20660
  };
20639
20661
  let [r, g, b, a] = sampleAt(u, v);
20640
20662
  if (farFade && !spec.wrap && a > 0) {
@@ -20652,6 +20674,13 @@ function resampleImage(rgba, width, height, spec, surface) {
20652
20674
  if (a <= 0) {
20653
20675
  continue;
20654
20676
  }
20677
+ if (integerBicubic) {
20678
+ r = Math.trunc(r);
20679
+ g = Math.trunc(g);
20680
+ b = Math.trunc(b);
20681
+ a = Math.trunc(a);
20682
+ if (a <= 0) continue;
20683
+ }
20655
20684
  const alpha = Math.min(255, a);
20656
20685
  const dst = (j * w + i) * 4;
20657
20686
  out[dst] = Math.min(Math.max(0, r), alpha) * 255 / alpha;
@@ -29789,7 +29818,7 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = fal
29789
29818
  for (let i = 0; i < q.length; i += 2) {
29790
29819
  pts.push(...map(q[i], clockwise ? f.t + f.b - q[i + 1] : q[i + 1]));
29791
29820
  }
29792
- if (box.halfX && !clockwise) {
29821
+ if (box.halfX) {
29793
29822
  for (const k of [1, 2, 3, 4, 5, 6, 8, 15]) {
29794
29823
  pts[2 * k]++;
29795
29824
  }
@@ -30880,7 +30909,7 @@ function fixExtent(rCtx, v, axis) {
30880
30909
  return Math.round(Math.abs(v) * k * 16);
30881
30910
  }
30882
30911
  var PS_INSIDEFRAME = 6;
30883
- function insideFrameInset(rCtx, box, rectangle = false) {
30912
+ function insideFrameInset(rCtx, box, rectangle = false, clockwiseRoundRect = false) {
30884
30913
  if ((rCtx.state.penStyle & 15) !== PS_INSIDEFRAME || !isAxisBox(box) || hasWorldRotation(rCtx)) {
30885
30914
  return null;
30886
30915
  }
@@ -30899,7 +30928,7 @@ function insideFrameInset(rCtx, box, rectangle = false) {
30899
30928
  }
30900
30929
  const lo = Math.floor(wx / 2);
30901
30930
  const hi = Math.ceil(wx / 2);
30902
- const y = Math.round(Math.ceil(wy / 2) * py);
30931
+ const y = Math.round((clockwiseRoundRect ? Math.floor(wy / 2) : Math.ceil(wy / 2)) * py);
30903
30932
  return {
30904
30933
  left: Math.round((rectangle ? hi : lo) * px),
30905
30934
  right: Math.round((rectangle ? lo : hi) * px),
@@ -31163,7 +31192,7 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31163
31192
  const cornerH = view.getInt32(dataOff + 20, true);
31164
31193
  const clockwise = rCtx.state.arcDirection === 2;
31165
31194
  const unframed = uprightFixBox(rCtx, l, t, r, b);
31166
- const inset = insideFrameInset(rCtx, unframed);
31195
+ const inset = insideFrameInset(rCtx, unframed, false, clockwise);
31167
31196
  const framed = inset ? insetFixBox(unframed, inset) : unframed;
31168
31197
  const devM = gdiDeviceMatrix(rCtx);
31169
31198
  const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
package/dist/browser.mjs CHANGED
@@ -11730,10 +11730,10 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = fa
11730
11730
  ew = 0;
11731
11731
  eh = 0;
11732
11732
  }
11733
- const hy = compatible ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
11733
+ const hy = compatible || clockwise ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
11734
11734
  const topX = compatible ? Math.round(r - ew / 2) : Math.floor(r - ew / 2);
11735
11735
  const hx = r - topX;
11736
- const verticalControl = compatible && clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11736
+ const verticalControl = clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11737
11737
  const horizontalControl = Math.ceil(KAPPA * hx);
11738
11738
  const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
11739
11739
  const mx = (x) => l + r - x;
@@ -16705,7 +16705,8 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
16705
16705
  const meanDark = sectorDark[s] / sectorCount[s];
16706
16706
  const ratio = meanDark > 0 ? dark[k] / meanDark : 1;
16707
16707
  const u = distance[k] / radius;
16708
- const falloff = Math.max(strength * (1 - u) * (1 - u), 0.5 * Math.max(0, 1 - ratio) ** 2);
16708
+ const darknessFalloff = ratio < 2 ? 0.5 * (1 - ratio) ** 2 : 0;
16709
+ const falloff = Math.max(strength * (1 - u) * (1 - u), darknessFalloff);
16709
16710
  const rest = (1 - falloff) * mean;
16710
16711
  if (rest >= v) {
16711
16712
  continue;
@@ -20431,7 +20432,7 @@ function axisFilter(kernel, scale, copy) {
20431
20432
  return { radius: 0.5, weight: (i, c) => Math.floor(c + 0.5) === i ? 1 : 0 };
20432
20433
  }
20433
20434
  }
20434
- function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge = { wrap: void 0, clamp: null }) {
20435
+ function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge = { wrap: void 0, clamp: null }, integerBicubic = false) {
20435
20436
  const [outer0, outerW, inner0, innerW] = verticalFirst ? [iu0, wu, iv0, wv] : [iv0, wv, iu0, wu];
20436
20437
  const [oMin, oMax, iMin, iMax] = verticalFirst ? [box.x0, box.x1, box.y0, box.y1] : [box.y0, box.y1, box.x0, box.x1];
20437
20438
  let r = 0;
@@ -20472,11 +20473,17 @@ function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge
20472
20473
  }
20473
20474
  const alpha = px[s + 3];
20474
20475
  const wa = wi * alpha / 255;
20475
- lr += wa * px[s];
20476
- lg += wa * px[s + 1];
20477
- lb += wa * px[s + 2];
20476
+ lr += integerBicubic ? wi * Math.round(alpha * px[s] / 255) : wa * px[s];
20477
+ lg += integerBicubic ? wi * Math.round(alpha * px[s + 1] / 255) : wa * px[s + 1];
20478
+ lb += integerBicubic ? wi * Math.round(alpha * px[s + 2] / 255) : wa * px[s + 2];
20478
20479
  la += wi * alpha;
20479
20480
  }
20481
+ if (integerBicubic) {
20482
+ lr = Math.trunc(lr);
20483
+ lg = Math.trunc(lg);
20484
+ lb = Math.trunc(lb);
20485
+ la = Math.trunc(la);
20486
+ }
20480
20487
  la = Math.min(255, Math.max(0, la));
20481
20488
  r += wo * Math.min(la, Math.max(0, lr));
20482
20489
  g += wo * Math.min(la, Math.max(0, lg));
@@ -20524,6 +20531,7 @@ function resampleImage(rgba, width, height, spec, surface) {
20524
20531
  let kernel = spec.kernel;
20525
20532
  const hq = kernel === "hq-bilinear" || kernel === "hq-bicubic";
20526
20533
  const axisAligned = m[1] === 0 && m[2] === 0;
20534
+ const integerBicubic = kernel === "bicubic" && axisAligned;
20527
20535
  let farFade = false;
20528
20536
  let shiftX = 0;
20529
20537
  let shiftY = 0;
@@ -20605,12 +20613,17 @@ function resampleImage(rgba, width, height, spec, surface) {
20605
20613
  mirrorX: spec.wrap === "tile-flip-x" || spec.wrap === "tile-flip-xy",
20606
20614
  mirrorY: spec.wrap === "tile-flip-y" || spec.wrap === "tile-flip-xy"
20607
20615
  };
20616
+ const bicubicDu = Math.round(inv2[0] * FIX16);
20617
+ const bicubicDv = Math.round(inv2[1] * FIX16);
20608
20618
  for (let j = 0; j < h; j++) {
20609
20619
  const py = by0 + j + o;
20620
+ let start = -1;
20621
+ let su = 0;
20622
+ let sv = 0;
20610
20623
  for (let i = 0; i < w; i++) {
20611
20624
  const px = bx0 + i + o;
20612
- const u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
20613
- const v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
20625
+ let u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
20626
+ let v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
20614
20627
  const cx = px + COVERAGE_NUDGE_X;
20615
20628
  const cy = py + COVERAGE_NUDGE_Y;
20616
20629
  const eu = inv2[0] * cx + inv2[2] * cy + inv2[4];
@@ -20618,6 +20631,15 @@ function resampleImage(rgba, width, height, spec, surface) {
20618
20631
  if (eu < spec.srcX || ev < spec.srcY || eu >= uMax || ev >= vMax) {
20619
20632
  continue;
20620
20633
  }
20634
+ if (integerBicubic) {
20635
+ if (start < 0) {
20636
+ start = i;
20637
+ su = Math.round(u * FIX16);
20638
+ sv = Math.round(v * FIX16);
20639
+ }
20640
+ u = Math.floor((su + (i - start) * bicubicDu) / (FIX16 / 64)) / 64;
20641
+ v = Math.floor((sv + (i - start) * bicubicDv) / (FIX16 / 64)) / 64;
20642
+ }
20621
20643
  const box = { x0: 0, y0: 0, x1: width, y1: height };
20622
20644
  const sampleAt = (cu, cv) => {
20623
20645
  const iu0 = Math.ceil(cu - fu.radius);
@@ -20632,7 +20654,7 @@ function resampleImage(rgba, width, height, spec, surface) {
20632
20654
  for (let t = iv0; t <= iv1; t++) {
20633
20655
  wv.push(fv.weight(t, cv));
20634
20656
  }
20635
- return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge);
20657
+ return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge, integerBicubic);
20636
20658
  };
20637
20659
  let [r, g, b, a] = sampleAt(u, v);
20638
20660
  if (farFade && !spec.wrap && a > 0) {
@@ -20650,6 +20672,13 @@ function resampleImage(rgba, width, height, spec, surface) {
20650
20672
  if (a <= 0) {
20651
20673
  continue;
20652
20674
  }
20675
+ if (integerBicubic) {
20676
+ r = Math.trunc(r);
20677
+ g = Math.trunc(g);
20678
+ b = Math.trunc(b);
20679
+ a = Math.trunc(a);
20680
+ if (a <= 0) continue;
20681
+ }
20653
20682
  const alpha = Math.min(255, a);
20654
20683
  const dst = (j * w + i) * 4;
20655
20684
  out[dst] = Math.min(Math.max(0, r), alpha) * 255 / alpha;
@@ -29787,7 +29816,7 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = fal
29787
29816
  for (let i = 0; i < q.length; i += 2) {
29788
29817
  pts.push(...map(q[i], clockwise ? f.t + f.b - q[i + 1] : q[i + 1]));
29789
29818
  }
29790
- if (box.halfX && !clockwise) {
29819
+ if (box.halfX) {
29791
29820
  for (const k of [1, 2, 3, 4, 5, 6, 8, 15]) {
29792
29821
  pts[2 * k]++;
29793
29822
  }
@@ -30878,7 +30907,7 @@ function fixExtent(rCtx, v, axis) {
30878
30907
  return Math.round(Math.abs(v) * k * 16);
30879
30908
  }
30880
30909
  var PS_INSIDEFRAME = 6;
30881
- function insideFrameInset(rCtx, box, rectangle = false) {
30910
+ function insideFrameInset(rCtx, box, rectangle = false, clockwiseRoundRect = false) {
30882
30911
  if ((rCtx.state.penStyle & 15) !== PS_INSIDEFRAME || !isAxisBox(box) || hasWorldRotation(rCtx)) {
30883
30912
  return null;
30884
30913
  }
@@ -30897,7 +30926,7 @@ function insideFrameInset(rCtx, box, rectangle = false) {
30897
30926
  }
30898
30927
  const lo = Math.floor(wx / 2);
30899
30928
  const hi = Math.ceil(wx / 2);
30900
- const y = Math.round(Math.ceil(wy / 2) * py);
30929
+ const y = Math.round((clockwiseRoundRect ? Math.floor(wy / 2) : Math.ceil(wy / 2)) * py);
30901
30930
  return {
30902
30931
  left: Math.round((rectangle ? hi : lo) * px),
30903
30932
  right: Math.round((rectangle ? lo : hi) * px),
@@ -31161,7 +31190,7 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31161
31190
  const cornerH = view.getInt32(dataOff + 20, true);
31162
31191
  const clockwise = rCtx.state.arcDirection === 2;
31163
31192
  const unframed = uprightFixBox(rCtx, l, t, r, b);
31164
- const inset = insideFrameInset(rCtx, unframed);
31193
+ const inset = insideFrameInset(rCtx, unframed, false, clockwise);
31165
31194
  const framed = inset ? insetFixBox(unframed, inset) : unframed;
31166
31195
  const devM = gdiDeviceMatrix(rCtx);
31167
31196
  const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
package/dist/index.js CHANGED
@@ -11733,10 +11733,10 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = fa
11733
11733
  ew = 0;
11734
11734
  eh = 0;
11735
11735
  }
11736
- const hy = compatible ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
11736
+ const hy = compatible || clockwise ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
11737
11737
  const topX = compatible ? Math.round(r - ew / 2) : Math.floor(r - ew / 2);
11738
11738
  const hx = r - topX;
11739
- const verticalControl = compatible && clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11739
+ const verticalControl = clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11740
11740
  const horizontalControl = Math.ceil(KAPPA * hx);
11741
11741
  const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
11742
11742
  const mx = (x) => l + r - x;
@@ -16708,7 +16708,8 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
16708
16708
  const meanDark = sectorDark[s] / sectorCount[s];
16709
16709
  const ratio = meanDark > 0 ? dark[k] / meanDark : 1;
16710
16710
  const u = distance[k] / radius;
16711
- const falloff = Math.max(strength * (1 - u) * (1 - u), 0.5 * Math.max(0, 1 - ratio) ** 2);
16711
+ const darknessFalloff = ratio < 2 ? 0.5 * (1 - ratio) ** 2 : 0;
16712
+ const falloff = Math.max(strength * (1 - u) * (1 - u), darknessFalloff);
16712
16713
  const rest = (1 - falloff) * mean;
16713
16714
  if (rest >= v) {
16714
16715
  continue;
@@ -20434,7 +20435,7 @@ function axisFilter(kernel, scale, copy) {
20434
20435
  return { radius: 0.5, weight: (i, c) => Math.floor(c + 0.5) === i ? 1 : 0 };
20435
20436
  }
20436
20437
  }
20437
- function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge = { wrap: void 0, clamp: null }) {
20438
+ function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge = { wrap: void 0, clamp: null }, integerBicubic = false) {
20438
20439
  const [outer0, outerW, inner0, innerW] = verticalFirst ? [iu0, wu, iv0, wv] : [iv0, wv, iu0, wu];
20439
20440
  const [oMin, oMax, iMin, iMax] = verticalFirst ? [box.x0, box.x1, box.y0, box.y1] : [box.y0, box.y1, box.x0, box.x1];
20440
20441
  let r = 0;
@@ -20475,11 +20476,17 @@ function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge
20475
20476
  }
20476
20477
  const alpha = px[s + 3];
20477
20478
  const wa = wi * alpha / 255;
20478
- lr += wa * px[s];
20479
- lg += wa * px[s + 1];
20480
- lb += wa * px[s + 2];
20479
+ lr += integerBicubic ? wi * Math.round(alpha * px[s] / 255) : wa * px[s];
20480
+ lg += integerBicubic ? wi * Math.round(alpha * px[s + 1] / 255) : wa * px[s + 1];
20481
+ lb += integerBicubic ? wi * Math.round(alpha * px[s + 2] / 255) : wa * px[s + 2];
20481
20482
  la += wi * alpha;
20482
20483
  }
20484
+ if (integerBicubic) {
20485
+ lr = Math.trunc(lr);
20486
+ lg = Math.trunc(lg);
20487
+ lb = Math.trunc(lb);
20488
+ la = Math.trunc(la);
20489
+ }
20483
20490
  la = Math.min(255, Math.max(0, la));
20484
20491
  r += wo * Math.min(la, Math.max(0, lr));
20485
20492
  g += wo * Math.min(la, Math.max(0, lg));
@@ -20527,6 +20534,7 @@ function resampleImage(rgba, width, height, spec, surface) {
20527
20534
  let kernel = spec.kernel;
20528
20535
  const hq = kernel === "hq-bilinear" || kernel === "hq-bicubic";
20529
20536
  const axisAligned = m[1] === 0 && m[2] === 0;
20537
+ const integerBicubic = kernel === "bicubic" && axisAligned;
20530
20538
  let farFade = false;
20531
20539
  let shiftX = 0;
20532
20540
  let shiftY = 0;
@@ -20608,12 +20616,17 @@ function resampleImage(rgba, width, height, spec, surface) {
20608
20616
  mirrorX: spec.wrap === "tile-flip-x" || spec.wrap === "tile-flip-xy",
20609
20617
  mirrorY: spec.wrap === "tile-flip-y" || spec.wrap === "tile-flip-xy"
20610
20618
  };
20619
+ const bicubicDu = Math.round(inv2[0] * FIX16);
20620
+ const bicubicDv = Math.round(inv2[1] * FIX16);
20611
20621
  for (let j = 0; j < h; j++) {
20612
20622
  const py = by0 + j + o;
20623
+ let start = -1;
20624
+ let su = 0;
20625
+ let sv = 0;
20613
20626
  for (let i = 0; i < w; i++) {
20614
20627
  const px = bx0 + i + o;
20615
- const u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
20616
- const v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
20628
+ let u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
20629
+ let v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
20617
20630
  const cx = px + COVERAGE_NUDGE_X;
20618
20631
  const cy = py + COVERAGE_NUDGE_Y;
20619
20632
  const eu = inv2[0] * cx + inv2[2] * cy + inv2[4];
@@ -20621,6 +20634,15 @@ function resampleImage(rgba, width, height, spec, surface) {
20621
20634
  if (eu < spec.srcX || ev < spec.srcY || eu >= uMax || ev >= vMax) {
20622
20635
  continue;
20623
20636
  }
20637
+ if (integerBicubic) {
20638
+ if (start < 0) {
20639
+ start = i;
20640
+ su = Math.round(u * FIX16);
20641
+ sv = Math.round(v * FIX16);
20642
+ }
20643
+ u = Math.floor((su + (i - start) * bicubicDu) / (FIX16 / 64)) / 64;
20644
+ v = Math.floor((sv + (i - start) * bicubicDv) / (FIX16 / 64)) / 64;
20645
+ }
20624
20646
  const box = { x0: 0, y0: 0, x1: width, y1: height };
20625
20647
  const sampleAt = (cu, cv) => {
20626
20648
  const iu0 = Math.ceil(cu - fu.radius);
@@ -20635,7 +20657,7 @@ function resampleImage(rgba, width, height, spec, surface) {
20635
20657
  for (let t = iv0; t <= iv1; t++) {
20636
20658
  wv.push(fv.weight(t, cv));
20637
20659
  }
20638
- return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge);
20660
+ return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge, integerBicubic);
20639
20661
  };
20640
20662
  let [r, g, b, a] = sampleAt(u, v);
20641
20663
  if (farFade && !spec.wrap && a > 0) {
@@ -20653,6 +20675,13 @@ function resampleImage(rgba, width, height, spec, surface) {
20653
20675
  if (a <= 0) {
20654
20676
  continue;
20655
20677
  }
20678
+ if (integerBicubic) {
20679
+ r = Math.trunc(r);
20680
+ g = Math.trunc(g);
20681
+ b = Math.trunc(b);
20682
+ a = Math.trunc(a);
20683
+ if (a <= 0) continue;
20684
+ }
20656
20685
  const alpha = Math.min(255, a);
20657
20686
  const dst = (j * w + i) * 4;
20658
20687
  out[dst] = Math.min(Math.max(0, r), alpha) * 255 / alpha;
@@ -29790,7 +29819,7 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = fal
29790
29819
  for (let i = 0; i < q.length; i += 2) {
29791
29820
  pts.push(...map(q[i], clockwise ? f.t + f.b - q[i + 1] : q[i + 1]));
29792
29821
  }
29793
- if (box.halfX && !clockwise) {
29822
+ if (box.halfX) {
29794
29823
  for (const k of [1, 2, 3, 4, 5, 6, 8, 15]) {
29795
29824
  pts[2 * k]++;
29796
29825
  }
@@ -30881,7 +30910,7 @@ function fixExtent(rCtx, v, axis) {
30881
30910
  return Math.round(Math.abs(v) * k * 16);
30882
30911
  }
30883
30912
  var PS_INSIDEFRAME = 6;
30884
- function insideFrameInset(rCtx, box, rectangle = false) {
30913
+ function insideFrameInset(rCtx, box, rectangle = false, clockwiseRoundRect = false) {
30885
30914
  if ((rCtx.state.penStyle & 15) !== PS_INSIDEFRAME || !isAxisBox(box) || hasWorldRotation(rCtx)) {
30886
30915
  return null;
30887
30916
  }
@@ -30900,7 +30929,7 @@ function insideFrameInset(rCtx, box, rectangle = false) {
30900
30929
  }
30901
30930
  const lo = Math.floor(wx / 2);
30902
30931
  const hi = Math.ceil(wx / 2);
30903
- const y = Math.round(Math.ceil(wy / 2) * py);
30932
+ const y = Math.round((clockwiseRoundRect ? Math.floor(wy / 2) : Math.ceil(wy / 2)) * py);
30904
30933
  return {
30905
30934
  left: Math.round((rectangle ? hi : lo) * px),
30906
30935
  right: Math.round((rectangle ? lo : hi) * px),
@@ -31164,7 +31193,7 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31164
31193
  const cornerH = view.getInt32(dataOff + 20, true);
31165
31194
  const clockwise = rCtx.state.arcDirection === 2;
31166
31195
  const unframed = uprightFixBox(rCtx, l, t, r, b);
31167
- const inset = insideFrameInset(rCtx, unframed);
31196
+ const inset = insideFrameInset(rCtx, unframed, false, clockwise);
31168
31197
  const framed = inset ? insetFixBox(unframed, inset) : unframed;
31169
31198
  const devM = gdiDeviceMatrix(rCtx);
31170
31199
  const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
package/dist/index.mjs CHANGED
@@ -11731,10 +11731,10 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = fa
11731
11731
  ew = 0;
11732
11732
  eh = 0;
11733
11733
  }
11734
- const hy = compatible ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
11734
+ const hy = compatible || clockwise ? Math.round(eh / 2) : Math.floor(h / 2) - Math.floor((h - eh) / 2);
11735
11735
  const topX = compatible ? Math.round(r - ew / 2) : Math.floor(r - ew / 2);
11736
11736
  const hx = r - topX;
11737
- const verticalControl = compatible && clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11737
+ const verticalControl = clockwise ? Math.ceil(KAPPA * hy) : Math.floor(KAPPA * hy);
11738
11738
  const horizontalControl = Math.ceil(KAPPA * hx);
11739
11739
  const q = [r, t + hy, r, t + hy - verticalControl, r - hx + horizontalControl, t, topX, t];
11740
11740
  const mx = (x) => l + r - x;
@@ -16706,7 +16706,8 @@ function correctRedEyeArea(out, stride, x0, y0, x1, y1, carry) {
16706
16706
  const meanDark = sectorDark[s] / sectorCount[s];
16707
16707
  const ratio = meanDark > 0 ? dark[k] / meanDark : 1;
16708
16708
  const u = distance[k] / radius;
16709
- const falloff = Math.max(strength * (1 - u) * (1 - u), 0.5 * Math.max(0, 1 - ratio) ** 2);
16709
+ const darknessFalloff = ratio < 2 ? 0.5 * (1 - ratio) ** 2 : 0;
16710
+ const falloff = Math.max(strength * (1 - u) * (1 - u), darknessFalloff);
16710
16711
  const rest = (1 - falloff) * mean;
16711
16712
  if (rest >= v) {
16712
16713
  continue;
@@ -20432,7 +20433,7 @@ function axisFilter(kernel, scale, copy) {
20432
20433
  return { radius: 0.5, weight: (i, c) => Math.floor(c + 0.5) === i ? 1 : 0 };
20433
20434
  }
20434
20435
  }
20435
- function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge = { wrap: void 0, clamp: null }) {
20436
+ function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge = { wrap: void 0, clamp: null }, integerBicubic = false) {
20436
20437
  const [outer0, outerW, inner0, innerW] = verticalFirst ? [iu0, wu, iv0, wv] : [iv0, wv, iu0, wu];
20437
20438
  const [oMin, oMax, iMin, iMax] = verticalFirst ? [box.x0, box.x1, box.y0, box.y1] : [box.y0, box.y1, box.x0, box.x1];
20438
20439
  let r = 0;
@@ -20473,11 +20474,17 @@ function blendSeparable(rgba, width, box, iu0, wu, iv0, wv, verticalFirst, edge
20473
20474
  }
20474
20475
  const alpha = px[s + 3];
20475
20476
  const wa = wi * alpha / 255;
20476
- lr += wa * px[s];
20477
- lg += wa * px[s + 1];
20478
- lb += wa * px[s + 2];
20477
+ lr += integerBicubic ? wi * Math.round(alpha * px[s] / 255) : wa * px[s];
20478
+ lg += integerBicubic ? wi * Math.round(alpha * px[s + 1] / 255) : wa * px[s + 1];
20479
+ lb += integerBicubic ? wi * Math.round(alpha * px[s + 2] / 255) : wa * px[s + 2];
20479
20480
  la += wi * alpha;
20480
20481
  }
20482
+ if (integerBicubic) {
20483
+ lr = Math.trunc(lr);
20484
+ lg = Math.trunc(lg);
20485
+ lb = Math.trunc(lb);
20486
+ la = Math.trunc(la);
20487
+ }
20481
20488
  la = Math.min(255, Math.max(0, la));
20482
20489
  r += wo * Math.min(la, Math.max(0, lr));
20483
20490
  g += wo * Math.min(la, Math.max(0, lg));
@@ -20525,6 +20532,7 @@ function resampleImage(rgba, width, height, spec, surface) {
20525
20532
  let kernel = spec.kernel;
20526
20533
  const hq = kernel === "hq-bilinear" || kernel === "hq-bicubic";
20527
20534
  const axisAligned = m[1] === 0 && m[2] === 0;
20535
+ const integerBicubic = kernel === "bicubic" && axisAligned;
20528
20536
  let farFade = false;
20529
20537
  let shiftX = 0;
20530
20538
  let shiftY = 0;
@@ -20606,12 +20614,17 @@ function resampleImage(rgba, width, height, spec, surface) {
20606
20614
  mirrorX: spec.wrap === "tile-flip-x" || spec.wrap === "tile-flip-xy",
20607
20615
  mirrorY: spec.wrap === "tile-flip-y" || spec.wrap === "tile-flip-xy"
20608
20616
  };
20617
+ const bicubicDu = Math.round(inv2[0] * FIX16);
20618
+ const bicubicDv = Math.round(inv2[1] * FIX16);
20609
20619
  for (let j = 0; j < h; j++) {
20610
20620
  const py = by0 + j + o;
20621
+ let start = -1;
20622
+ let su = 0;
20623
+ let sv = 0;
20611
20624
  for (let i = 0; i < w; i++) {
20612
20625
  const px = bx0 + i + o;
20613
- const u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
20614
- const v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
20626
+ let u = inv2[0] * (px - shiftX) + inv2[2] * (py - shiftY) + inv2[4];
20627
+ let v = inv2[1] * (px - shiftX) + inv2[3] * (py - shiftY) + inv2[5];
20615
20628
  const cx = px + COVERAGE_NUDGE_X;
20616
20629
  const cy = py + COVERAGE_NUDGE_Y;
20617
20630
  const eu = inv2[0] * cx + inv2[2] * cy + inv2[4];
@@ -20619,6 +20632,15 @@ function resampleImage(rgba, width, height, spec, surface) {
20619
20632
  if (eu < spec.srcX || ev < spec.srcY || eu >= uMax || ev >= vMax) {
20620
20633
  continue;
20621
20634
  }
20635
+ if (integerBicubic) {
20636
+ if (start < 0) {
20637
+ start = i;
20638
+ su = Math.round(u * FIX16);
20639
+ sv = Math.round(v * FIX16);
20640
+ }
20641
+ u = Math.floor((su + (i - start) * bicubicDu) / (FIX16 / 64)) / 64;
20642
+ v = Math.floor((sv + (i - start) * bicubicDv) / (FIX16 / 64)) / 64;
20643
+ }
20622
20644
  const box = { x0: 0, y0: 0, x1: width, y1: height };
20623
20645
  const sampleAt = (cu, cv) => {
20624
20646
  const iu0 = Math.ceil(cu - fu.radius);
@@ -20633,7 +20655,7 @@ function resampleImage(rgba, width, height, spec, surface) {
20633
20655
  for (let t = iv0; t <= iv1; t++) {
20634
20656
  wv.push(fv.weight(t, cv));
20635
20657
  }
20636
- return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge);
20658
+ return blendSeparable(rgba, width, box, iu0, wu, iv0, wv, kernel === "bicubic", edge, integerBicubic);
20637
20659
  };
20638
20660
  let [r, g, b, a] = sampleAt(u, v);
20639
20661
  if (farFade && !spec.wrap && a > 0) {
@@ -20651,6 +20673,13 @@ function resampleImage(rgba, width, height, spec, surface) {
20651
20673
  if (a <= 0) {
20652
20674
  continue;
20653
20675
  }
20676
+ if (integerBicubic) {
20677
+ r = Math.trunc(r);
20678
+ g = Math.trunc(g);
20679
+ b = Math.trunc(b);
20680
+ a = Math.trunc(a);
20681
+ if (a <= 0) continue;
20682
+ }
20654
20683
  const alpha = Math.min(255, a);
20655
20684
  const dst = (j * w + i) * 4;
20656
20685
  out[dst] = Math.min(Math.max(0, r), alpha) * 255 / alpha;
@@ -29788,7 +29817,7 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = fal
29788
29817
  for (let i = 0; i < q.length; i += 2) {
29789
29818
  pts.push(...map(q[i], clockwise ? f.t + f.b - q[i + 1] : q[i + 1]));
29790
29819
  }
29791
- if (box.halfX && !clockwise) {
29820
+ if (box.halfX) {
29792
29821
  for (const k of [1, 2, 3, 4, 5, 6, 8, 15]) {
29793
29822
  pts[2 * k]++;
29794
29823
  }
@@ -30879,7 +30908,7 @@ function fixExtent(rCtx, v, axis) {
30879
30908
  return Math.round(Math.abs(v) * k * 16);
30880
30909
  }
30881
30910
  var PS_INSIDEFRAME = 6;
30882
- function insideFrameInset(rCtx, box, rectangle = false) {
30911
+ function insideFrameInset(rCtx, box, rectangle = false, clockwiseRoundRect = false) {
30883
30912
  if ((rCtx.state.penStyle & 15) !== PS_INSIDEFRAME || !isAxisBox(box) || hasWorldRotation(rCtx)) {
30884
30913
  return null;
30885
30914
  }
@@ -30898,7 +30927,7 @@ function insideFrameInset(rCtx, box, rectangle = false) {
30898
30927
  }
30899
30928
  const lo = Math.floor(wx / 2);
30900
30929
  const hi = Math.ceil(wx / 2);
30901
- const y = Math.round(Math.ceil(wy / 2) * py);
30930
+ const y = Math.round((clockwiseRoundRect ? Math.floor(wy / 2) : Math.ceil(wy / 2)) * py);
30902
30931
  return {
30903
30932
  left: Math.round((rectangle ? hi : lo) * px),
30904
30933
  right: Math.round((rectangle ? lo : hi) * px),
@@ -31162,7 +31191,7 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31162
31191
  const cornerH = view.getInt32(dataOff + 20, true);
31163
31192
  const clockwise = rCtx.state.arcDirection === 2;
31164
31193
  const unframed = uprightFixBox(rCtx, l, t, r, b);
31165
- const inset = insideFrameInset(rCtx, unframed);
31194
+ const inset = insideFrameInset(rCtx, unframed, false, clockwise);
31166
31195
  const framed = inset ? insetFixBox(unframed, inset) : unframed;
31167
31196
  const devM = gdiDeviceMatrix(rCtx);
31168
31197
  const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emf-converter",
3
- "version": "4.8.13",
3
+ "version": "4.8.15",
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",