emf-converter 4.4.12 → 4.4.14

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
@@ -15863,7 +15863,7 @@ function mirror(p, n) {
15863
15863
  }
15864
15864
  return p;
15865
15865
  }
15866
- function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h) {
15866
+ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h, verticalRows = Math.ceil(h / w)) {
15867
15867
  const k = blurKernel(radius);
15868
15868
  const taps = (k.length - 1) / 2;
15869
15869
  const horizontalIndex = taps >= edgeWidth ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
@@ -15893,7 +15893,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
15893
15893
  }
15894
15894
  if (taps > 0 && vRow >= 0 && vRow < h) {
15895
15895
  const horizontal = out.slice();
15896
- const endRow = fullVertical ? h : Math.min(h, vRow + Math.ceil(h / w));
15896
+ const endRow = fullVertical ? h : Math.min(h, vRow + verticalRows);
15897
15897
  for (let row = vRow; row < endRow; row++) {
15898
15898
  const col = new Float64Array(w * 4);
15899
15899
  for (let j = -taps; j <= taps; j++) {
@@ -16012,13 +16012,12 @@ function copyBlock(src, width, sx, sy, w, h, dst, bw, dx, dy) {
16012
16012
  dst.set(src.subarray(from, from + w * 4), ((dy + y) * bw + dx) * 4);
16013
16013
  }
16014
16014
  }
16015
- function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1) {
16015
+ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
16016
16016
  const r = Math.ceil(radius);
16017
16017
  const bw = x1 - x0 + 2 * r;
16018
16018
  const bh = y1 - y0 + 2 * r;
16019
16019
  const buf = new Uint8ClampedArray(bw * bh * 4);
16020
- const inside = x0 - r >= 0 && y0 - r >= 0 && x1 + r <= width && y1 + r <= height;
16021
- if (inside) {
16020
+ if (cropped) {
16022
16021
  copyBlock(rgba, width, x0, y0, x1 - x0, y1 - y0, buf, bw, r, r);
16023
16022
  } else {
16024
16023
  const gx0 = Math.max(0, x0 - r);
@@ -16027,7 +16026,7 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1) {
16027
16026
  const gy1 = Math.min(height, y1 + r);
16028
16027
  copyBlock(rgba, width, gx0, gy0, gx1 - gx0, gy1 - gy0, buf, bw, gx0 - (x0 - r), gy0 - (y0 - r));
16029
16028
  }
16030
- const blurred = gdipBlur(buf, bw, bh, radius, inside ? r : 0, inside);
16029
+ const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, false, bw, bh, Math.ceil((y1 - y0) / (x1 - x0)));
16031
16030
  const w = x1 - x0;
16032
16031
  const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
16033
16032
  for (let y = 0; y < y1 - y0; y++) {
@@ -16068,7 +16067,8 @@ function applyImageEffectToRect(rgba, width, height, effect, src) {
16068
16067
  return { rgba: shown, x: x0, y: y0, width: shownWidth, height: shownHeight };
16069
16068
  };
16070
16069
  if (src && effect.kind === "blur" && effect.expandEdge) {
16071
- return result(expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1));
16070
+ const cropped = Math.ceil(src.x + src.w) < width && Math.ceil(src.y + src.h) < height;
16071
+ return result(expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1, cropped));
16072
16072
  }
16073
16073
  let region = rgba;
16074
16074
  if (w !== width || h !== height) {
@@ -28141,7 +28141,7 @@ function drawVertices(pen, dx, dy) {
28141
28141
  function halfPixel(v) {
28142
28142
  return Math.sign(v) * 8 * Math.floor((Math.abs(v) + 4) / 8);
28143
28143
  }
28144
- function flatVector(width, dx0, dy0) {
28144
+ function perpendicularVectors(width, dx0, dy0) {
28145
28145
  let dx = dx0;
28146
28146
  let dy = dy0;
28147
28147
  const flip = dx < 0 || dx === 0 && dy < 0;
@@ -28175,9 +28175,9 @@ function flatVector(width, dx0, dy0) {
28175
28175
  const ox = off ? sgn * off[0] : 0;
28176
28176
  const oy = off ? sgn * off[1] : 0;
28177
28177
  const r = (v) => 8 * Math.floor((v + 4) / 8);
28178
- const vx = r(D[0] + (B[0] - D[0]) * w + 0.5 * Math.sign(dy) + ox);
28179
- const vy = r(D[1] + (B[1] - D[1]) * w + 0.5 * Math.sign(dx) + oy);
28180
- return flip ? [-vx, -vy] : [vx, vy];
28178
+ const x = D[0] + (B[0] - D[0]) * w, y = D[1] + (B[1] - D[1]) * w;
28179
+ const vx = r(x + 0.5 * Math.sign(dy) + ox), vy = r(y + 0.5 * Math.sign(dx) + oy);
28180
+ return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
28181
28181
  }
28182
28182
  function squareExtension(width, dx, dy) {
28183
28183
  const len = Math.hypot(dx, dy);
@@ -28220,7 +28220,8 @@ var Outliner = class {
28220
28220
  const d = drawDir ?? [dx, dy];
28221
28221
  const [L, R] = drawVertices(this.pen, d[0], d[1]);
28222
28222
  const perpendicular = this.opts.roundCurveJoins && drawDir ? drawDir : [dx, dy];
28223
- return { dx, dy, L, R, v: flatVector(this.opts.width, perpendicular[0], perpendicular[1]), e: squareExtension(this.opts.width, dx, dy), curveEnd: !!drawDir };
28223
+ const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
28224
+ return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, dx, dy), curveEnd: !!drawDir };
28224
28225
  }
28225
28226
  push(p, v) {
28226
28227
  this.pts.push([p[0] + v[0], p[1] + v[1]]);
@@ -28316,7 +28317,7 @@ var Outliner = class {
28316
28317
  if (this.rr) {
28317
28318
  this.walk(p, s[from], s[to], false, false);
28318
28319
  } else {
28319
- const A = this.capSide(s, from);
28320
+ const A = from === "R" ? s.vRaw : [-s.vRaw[0], -s.vRaw[1]];
28320
28321
  this.wedge(p, A, [-A[0], -A[1]], true, false);
28321
28322
  }
28322
28323
  this.push(p, this.capSide(s, to));
@@ -28343,6 +28344,8 @@ var Outliner = class {
28343
28344
  const join = this.opts.roundCurveJoins ? "round" : this.opts.join;
28344
28345
  let sa = this.joinSide(a, side);
28345
28346
  let sb = this.joinSide(b, side);
28347
+ const rayA = side === "R" ? a.vRaw : [-a.vRaw[0], -a.vRaw[1]];
28348
+ const rayB = side === "R" ? b.vRaw : [-b.vRaw[0], -b.vRaw[1]];
28346
28349
  if (this.opts.roundCurveJoins && !this.originalRoundJoinSides && a.curveEnd && b.curveEnd) {
28347
28350
  sa = side === "R" ? a.v : [-a.v[0], -a.v[1]];
28348
28351
  sb = side === "R" ? b.v : [-b.v[0], -b.v[1]];
@@ -28363,10 +28366,10 @@ var Outliner = class {
28363
28366
  this.walk(p, Da, Db, false, incl);
28364
28367
  } else {
28365
28368
  const anti = sa[0] === -sb[0] && sa[1] === -sb[1];
28366
- this.wedge(p, sa, sb, !anti, !anti);
28369
+ this.wedge(p, rayA, rayB, !anti, !anti);
28367
28370
  }
28368
28371
  } else if (join === "miter") {
28369
- const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit);
28372
+ const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit, side);
28370
28373
  if (m) {
28371
28374
  this.push(p, m);
28372
28375
  }
@@ -28380,7 +28383,7 @@ var Outliner = class {
28380
28383
  }
28381
28384
  if (join === "round" && cap === "flat" && !this.opts.roundCurveJoins) {
28382
28385
  this.push(p, sb);
28383
- this.wedge(p, sb, sa, false, false);
28386
+ this.wedge(p, rayB, rayA, false, false);
28384
28387
  this.push(p, sa);
28385
28388
  this.pts.push([p[0], p[1]]);
28386
28389
  }
@@ -28599,7 +28602,7 @@ function widenPath(path, opts) {
28599
28602
  }
28600
28603
  return out;
28601
28604
  }
28602
- function miterPoint(sa, da, sb, db, width, limit) {
28605
+ function miterPoint(sa, da, sb, db, width, limit, side) {
28603
28606
  const den = da[0] * db[1] - da[1] * db[0];
28604
28607
  if (den === 0) {
28605
28608
  return null;
@@ -28609,10 +28612,13 @@ function miterPoint(sa, da, sb, db, width, limit) {
28609
28612
  const t = (wx * db[1] - wy * db[0]) / den;
28610
28613
  const mx = sa[0] + da[0] * t;
28611
28614
  const my = sa[1] + da[1] * t;
28612
- if (Math.hypot(mx, my) > limit * width / 2) {
28615
+ const x = Math.sign(mx) * Math.floor(Math.abs(mx) + 0.5);
28616
+ const y = Math.sign(my) * Math.floor(Math.abs(my) + 0.5);
28617
+ const pixel = side === "L" ? Math.ceil : Math.floor;
28618
+ if (Math.hypot(pixel(x / 16), pixel(y / 16)) > limit * width / 32) {
28613
28619
  return null;
28614
28620
  }
28615
- return [Math.floor(mx + 0.5), Math.floor(my + 0.5)];
28621
+ return [x, y];
28616
28622
  }
28617
28623
 
28618
28624
  // src/emf-gdi-raster-shapes.ts
package/dist/browser.mjs CHANGED
@@ -15861,7 +15861,7 @@ function mirror(p, n) {
15861
15861
  }
15862
15862
  return p;
15863
15863
  }
15864
- function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h) {
15864
+ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h, verticalRows = Math.ceil(h / w)) {
15865
15865
  const k = blurKernel(radius);
15866
15866
  const taps = (k.length - 1) / 2;
15867
15867
  const horizontalIndex = taps >= edgeWidth ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
@@ -15891,7 +15891,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
15891
15891
  }
15892
15892
  if (taps > 0 && vRow >= 0 && vRow < h) {
15893
15893
  const horizontal = out.slice();
15894
- const endRow = fullVertical ? h : Math.min(h, vRow + Math.ceil(h / w));
15894
+ const endRow = fullVertical ? h : Math.min(h, vRow + verticalRows);
15895
15895
  for (let row = vRow; row < endRow; row++) {
15896
15896
  const col = new Float64Array(w * 4);
15897
15897
  for (let j = -taps; j <= taps; j++) {
@@ -16010,13 +16010,12 @@ function copyBlock(src, width, sx, sy, w, h, dst, bw, dx, dy) {
16010
16010
  dst.set(src.subarray(from, from + w * 4), ((dy + y) * bw + dx) * 4);
16011
16011
  }
16012
16012
  }
16013
- function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1) {
16013
+ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
16014
16014
  const r = Math.ceil(radius);
16015
16015
  const bw = x1 - x0 + 2 * r;
16016
16016
  const bh = y1 - y0 + 2 * r;
16017
16017
  const buf = new Uint8ClampedArray(bw * bh * 4);
16018
- const inside = x0 - r >= 0 && y0 - r >= 0 && x1 + r <= width && y1 + r <= height;
16019
- if (inside) {
16018
+ if (cropped) {
16020
16019
  copyBlock(rgba, width, x0, y0, x1 - x0, y1 - y0, buf, bw, r, r);
16021
16020
  } else {
16022
16021
  const gx0 = Math.max(0, x0 - r);
@@ -16025,7 +16024,7 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1) {
16025
16024
  const gy1 = Math.min(height, y1 + r);
16026
16025
  copyBlock(rgba, width, gx0, gy0, gx1 - gx0, gy1 - gy0, buf, bw, gx0 - (x0 - r), gy0 - (y0 - r));
16027
16026
  }
16028
- const blurred = gdipBlur(buf, bw, bh, radius, inside ? r : 0, inside);
16027
+ const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, false, bw, bh, Math.ceil((y1 - y0) / (x1 - x0)));
16029
16028
  const w = x1 - x0;
16030
16029
  const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
16031
16030
  for (let y = 0; y < y1 - y0; y++) {
@@ -16066,7 +16065,8 @@ function applyImageEffectToRect(rgba, width, height, effect, src) {
16066
16065
  return { rgba: shown, x: x0, y: y0, width: shownWidth, height: shownHeight };
16067
16066
  };
16068
16067
  if (src && effect.kind === "blur" && effect.expandEdge) {
16069
- return result(expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1));
16068
+ const cropped = Math.ceil(src.x + src.w) < width && Math.ceil(src.y + src.h) < height;
16069
+ return result(expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1, cropped));
16070
16070
  }
16071
16071
  let region = rgba;
16072
16072
  if (w !== width || h !== height) {
@@ -28139,7 +28139,7 @@ function drawVertices(pen, dx, dy) {
28139
28139
  function halfPixel(v) {
28140
28140
  return Math.sign(v) * 8 * Math.floor((Math.abs(v) + 4) / 8);
28141
28141
  }
28142
- function flatVector(width, dx0, dy0) {
28142
+ function perpendicularVectors(width, dx0, dy0) {
28143
28143
  let dx = dx0;
28144
28144
  let dy = dy0;
28145
28145
  const flip = dx < 0 || dx === 0 && dy < 0;
@@ -28173,9 +28173,9 @@ function flatVector(width, dx0, dy0) {
28173
28173
  const ox = off ? sgn * off[0] : 0;
28174
28174
  const oy = off ? sgn * off[1] : 0;
28175
28175
  const r = (v) => 8 * Math.floor((v + 4) / 8);
28176
- const vx = r(D[0] + (B[0] - D[0]) * w + 0.5 * Math.sign(dy) + ox);
28177
- const vy = r(D[1] + (B[1] - D[1]) * w + 0.5 * Math.sign(dx) + oy);
28178
- return flip ? [-vx, -vy] : [vx, vy];
28176
+ const x = D[0] + (B[0] - D[0]) * w, y = D[1] + (B[1] - D[1]) * w;
28177
+ const vx = r(x + 0.5 * Math.sign(dy) + ox), vy = r(y + 0.5 * Math.sign(dx) + oy);
28178
+ return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
28179
28179
  }
28180
28180
  function squareExtension(width, dx, dy) {
28181
28181
  const len = Math.hypot(dx, dy);
@@ -28218,7 +28218,8 @@ var Outliner = class {
28218
28218
  const d = drawDir ?? [dx, dy];
28219
28219
  const [L, R] = drawVertices(this.pen, d[0], d[1]);
28220
28220
  const perpendicular = this.opts.roundCurveJoins && drawDir ? drawDir : [dx, dy];
28221
- return { dx, dy, L, R, v: flatVector(this.opts.width, perpendicular[0], perpendicular[1]), e: squareExtension(this.opts.width, dx, dy), curveEnd: !!drawDir };
28221
+ const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
28222
+ return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, dx, dy), curveEnd: !!drawDir };
28222
28223
  }
28223
28224
  push(p, v) {
28224
28225
  this.pts.push([p[0] + v[0], p[1] + v[1]]);
@@ -28314,7 +28315,7 @@ var Outliner = class {
28314
28315
  if (this.rr) {
28315
28316
  this.walk(p, s[from], s[to], false, false);
28316
28317
  } else {
28317
- const A = this.capSide(s, from);
28318
+ const A = from === "R" ? s.vRaw : [-s.vRaw[0], -s.vRaw[1]];
28318
28319
  this.wedge(p, A, [-A[0], -A[1]], true, false);
28319
28320
  }
28320
28321
  this.push(p, this.capSide(s, to));
@@ -28341,6 +28342,8 @@ var Outliner = class {
28341
28342
  const join = this.opts.roundCurveJoins ? "round" : this.opts.join;
28342
28343
  let sa = this.joinSide(a, side);
28343
28344
  let sb = this.joinSide(b, side);
28345
+ const rayA = side === "R" ? a.vRaw : [-a.vRaw[0], -a.vRaw[1]];
28346
+ const rayB = side === "R" ? b.vRaw : [-b.vRaw[0], -b.vRaw[1]];
28344
28347
  if (this.opts.roundCurveJoins && !this.originalRoundJoinSides && a.curveEnd && b.curveEnd) {
28345
28348
  sa = side === "R" ? a.v : [-a.v[0], -a.v[1]];
28346
28349
  sb = side === "R" ? b.v : [-b.v[0], -b.v[1]];
@@ -28361,10 +28364,10 @@ var Outliner = class {
28361
28364
  this.walk(p, Da, Db, false, incl);
28362
28365
  } else {
28363
28366
  const anti = sa[0] === -sb[0] && sa[1] === -sb[1];
28364
- this.wedge(p, sa, sb, !anti, !anti);
28367
+ this.wedge(p, rayA, rayB, !anti, !anti);
28365
28368
  }
28366
28369
  } else if (join === "miter") {
28367
- const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit);
28370
+ const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit, side);
28368
28371
  if (m) {
28369
28372
  this.push(p, m);
28370
28373
  }
@@ -28378,7 +28381,7 @@ var Outliner = class {
28378
28381
  }
28379
28382
  if (join === "round" && cap === "flat" && !this.opts.roundCurveJoins) {
28380
28383
  this.push(p, sb);
28381
- this.wedge(p, sb, sa, false, false);
28384
+ this.wedge(p, rayB, rayA, false, false);
28382
28385
  this.push(p, sa);
28383
28386
  this.pts.push([p[0], p[1]]);
28384
28387
  }
@@ -28597,7 +28600,7 @@ function widenPath(path, opts) {
28597
28600
  }
28598
28601
  return out;
28599
28602
  }
28600
- function miterPoint(sa, da, sb, db, width, limit) {
28603
+ function miterPoint(sa, da, sb, db, width, limit, side) {
28601
28604
  const den = da[0] * db[1] - da[1] * db[0];
28602
28605
  if (den === 0) {
28603
28606
  return null;
@@ -28607,10 +28610,13 @@ function miterPoint(sa, da, sb, db, width, limit) {
28607
28610
  const t = (wx * db[1] - wy * db[0]) / den;
28608
28611
  const mx = sa[0] + da[0] * t;
28609
28612
  const my = sa[1] + da[1] * t;
28610
- if (Math.hypot(mx, my) > limit * width / 2) {
28613
+ const x = Math.sign(mx) * Math.floor(Math.abs(mx) + 0.5);
28614
+ const y = Math.sign(my) * Math.floor(Math.abs(my) + 0.5);
28615
+ const pixel = side === "L" ? Math.ceil : Math.floor;
28616
+ if (Math.hypot(pixel(x / 16), pixel(y / 16)) > limit * width / 32) {
28611
28617
  return null;
28612
28618
  }
28613
- return [Math.floor(mx + 0.5), Math.floor(my + 0.5)];
28619
+ return [x, y];
28614
28620
  }
28615
28621
 
28616
28622
  // src/emf-gdi-raster-shapes.ts
package/dist/index.js CHANGED
@@ -15864,7 +15864,7 @@ function mirror(p, n) {
15864
15864
  }
15865
15865
  return p;
15866
15866
  }
15867
- function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h) {
15867
+ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h, verticalRows = Math.ceil(h / w)) {
15868
15868
  const k = blurKernel(radius);
15869
15869
  const taps = (k.length - 1) / 2;
15870
15870
  const horizontalIndex = taps >= edgeWidth ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
@@ -15894,7 +15894,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
15894
15894
  }
15895
15895
  if (taps > 0 && vRow >= 0 && vRow < h) {
15896
15896
  const horizontal = out.slice();
15897
- const endRow = fullVertical ? h : Math.min(h, vRow + Math.ceil(h / w));
15897
+ const endRow = fullVertical ? h : Math.min(h, vRow + verticalRows);
15898
15898
  for (let row = vRow; row < endRow; row++) {
15899
15899
  const col = new Float64Array(w * 4);
15900
15900
  for (let j = -taps; j <= taps; j++) {
@@ -16013,13 +16013,12 @@ function copyBlock(src, width, sx, sy, w, h, dst, bw, dx, dy) {
16013
16013
  dst.set(src.subarray(from, from + w * 4), ((dy + y) * bw + dx) * 4);
16014
16014
  }
16015
16015
  }
16016
- function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1) {
16016
+ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
16017
16017
  const r = Math.ceil(radius);
16018
16018
  const bw = x1 - x0 + 2 * r;
16019
16019
  const bh = y1 - y0 + 2 * r;
16020
16020
  const buf = new Uint8ClampedArray(bw * bh * 4);
16021
- const inside = x0 - r >= 0 && y0 - r >= 0 && x1 + r <= width && y1 + r <= height;
16022
- if (inside) {
16021
+ if (cropped) {
16023
16022
  copyBlock(rgba, width, x0, y0, x1 - x0, y1 - y0, buf, bw, r, r);
16024
16023
  } else {
16025
16024
  const gx0 = Math.max(0, x0 - r);
@@ -16028,7 +16027,7 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1) {
16028
16027
  const gy1 = Math.min(height, y1 + r);
16029
16028
  copyBlock(rgba, width, gx0, gy0, gx1 - gx0, gy1 - gy0, buf, bw, gx0 - (x0 - r), gy0 - (y0 - r));
16030
16029
  }
16031
- const blurred = gdipBlur(buf, bw, bh, radius, inside ? r : 0, inside);
16030
+ const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, false, bw, bh, Math.ceil((y1 - y0) / (x1 - x0)));
16032
16031
  const w = x1 - x0;
16033
16032
  const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
16034
16033
  for (let y = 0; y < y1 - y0; y++) {
@@ -16069,7 +16068,8 @@ function applyImageEffectToRect(rgba, width, height, effect, src) {
16069
16068
  return { rgba: shown, x: x0, y: y0, width: shownWidth, height: shownHeight };
16070
16069
  };
16071
16070
  if (src && effect.kind === "blur" && effect.expandEdge) {
16072
- return result(expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1));
16071
+ const cropped = Math.ceil(src.x + src.w) < width && Math.ceil(src.y + src.h) < height;
16072
+ return result(expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1, cropped));
16073
16073
  }
16074
16074
  let region = rgba;
16075
16075
  if (w !== width || h !== height) {
@@ -28142,7 +28142,7 @@ function drawVertices(pen, dx, dy) {
28142
28142
  function halfPixel(v) {
28143
28143
  return Math.sign(v) * 8 * Math.floor((Math.abs(v) + 4) / 8);
28144
28144
  }
28145
- function flatVector(width, dx0, dy0) {
28145
+ function perpendicularVectors(width, dx0, dy0) {
28146
28146
  let dx = dx0;
28147
28147
  let dy = dy0;
28148
28148
  const flip = dx < 0 || dx === 0 && dy < 0;
@@ -28176,9 +28176,9 @@ function flatVector(width, dx0, dy0) {
28176
28176
  const ox = off ? sgn * off[0] : 0;
28177
28177
  const oy = off ? sgn * off[1] : 0;
28178
28178
  const r = (v) => 8 * Math.floor((v + 4) / 8);
28179
- const vx = r(D[0] + (B[0] - D[0]) * w + 0.5 * Math.sign(dy) + ox);
28180
- const vy = r(D[1] + (B[1] - D[1]) * w + 0.5 * Math.sign(dx) + oy);
28181
- return flip ? [-vx, -vy] : [vx, vy];
28179
+ const x = D[0] + (B[0] - D[0]) * w, y = D[1] + (B[1] - D[1]) * w;
28180
+ const vx = r(x + 0.5 * Math.sign(dy) + ox), vy = r(y + 0.5 * Math.sign(dx) + oy);
28181
+ return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
28182
28182
  }
28183
28183
  function squareExtension(width, dx, dy) {
28184
28184
  const len = Math.hypot(dx, dy);
@@ -28221,7 +28221,8 @@ var Outliner = class {
28221
28221
  const d = drawDir ?? [dx, dy];
28222
28222
  const [L, R] = drawVertices(this.pen, d[0], d[1]);
28223
28223
  const perpendicular = this.opts.roundCurveJoins && drawDir ? drawDir : [dx, dy];
28224
- return { dx, dy, L, R, v: flatVector(this.opts.width, perpendicular[0], perpendicular[1]), e: squareExtension(this.opts.width, dx, dy), curveEnd: !!drawDir };
28224
+ const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
28225
+ return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, dx, dy), curveEnd: !!drawDir };
28225
28226
  }
28226
28227
  push(p, v) {
28227
28228
  this.pts.push([p[0] + v[0], p[1] + v[1]]);
@@ -28317,7 +28318,7 @@ var Outliner = class {
28317
28318
  if (this.rr) {
28318
28319
  this.walk(p, s[from], s[to], false, false);
28319
28320
  } else {
28320
- const A = this.capSide(s, from);
28321
+ const A = from === "R" ? s.vRaw : [-s.vRaw[0], -s.vRaw[1]];
28321
28322
  this.wedge(p, A, [-A[0], -A[1]], true, false);
28322
28323
  }
28323
28324
  this.push(p, this.capSide(s, to));
@@ -28344,6 +28345,8 @@ var Outliner = class {
28344
28345
  const join = this.opts.roundCurveJoins ? "round" : this.opts.join;
28345
28346
  let sa = this.joinSide(a, side);
28346
28347
  let sb = this.joinSide(b, side);
28348
+ const rayA = side === "R" ? a.vRaw : [-a.vRaw[0], -a.vRaw[1]];
28349
+ const rayB = side === "R" ? b.vRaw : [-b.vRaw[0], -b.vRaw[1]];
28347
28350
  if (this.opts.roundCurveJoins && !this.originalRoundJoinSides && a.curveEnd && b.curveEnd) {
28348
28351
  sa = side === "R" ? a.v : [-a.v[0], -a.v[1]];
28349
28352
  sb = side === "R" ? b.v : [-b.v[0], -b.v[1]];
@@ -28364,10 +28367,10 @@ var Outliner = class {
28364
28367
  this.walk(p, Da, Db, false, incl);
28365
28368
  } else {
28366
28369
  const anti = sa[0] === -sb[0] && sa[1] === -sb[1];
28367
- this.wedge(p, sa, sb, !anti, !anti);
28370
+ this.wedge(p, rayA, rayB, !anti, !anti);
28368
28371
  }
28369
28372
  } else if (join === "miter") {
28370
- const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit);
28373
+ const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit, side);
28371
28374
  if (m) {
28372
28375
  this.push(p, m);
28373
28376
  }
@@ -28381,7 +28384,7 @@ var Outliner = class {
28381
28384
  }
28382
28385
  if (join === "round" && cap === "flat" && !this.opts.roundCurveJoins) {
28383
28386
  this.push(p, sb);
28384
- this.wedge(p, sb, sa, false, false);
28387
+ this.wedge(p, rayB, rayA, false, false);
28385
28388
  this.push(p, sa);
28386
28389
  this.pts.push([p[0], p[1]]);
28387
28390
  }
@@ -28600,7 +28603,7 @@ function widenPath(path, opts) {
28600
28603
  }
28601
28604
  return out;
28602
28605
  }
28603
- function miterPoint(sa, da, sb, db, width, limit) {
28606
+ function miterPoint(sa, da, sb, db, width, limit, side) {
28604
28607
  const den = da[0] * db[1] - da[1] * db[0];
28605
28608
  if (den === 0) {
28606
28609
  return null;
@@ -28610,10 +28613,13 @@ function miterPoint(sa, da, sb, db, width, limit) {
28610
28613
  const t = (wx * db[1] - wy * db[0]) / den;
28611
28614
  const mx = sa[0] + da[0] * t;
28612
28615
  const my = sa[1] + da[1] * t;
28613
- if (Math.hypot(mx, my) > limit * width / 2) {
28616
+ const x = Math.sign(mx) * Math.floor(Math.abs(mx) + 0.5);
28617
+ const y = Math.sign(my) * Math.floor(Math.abs(my) + 0.5);
28618
+ const pixel = side === "L" ? Math.ceil : Math.floor;
28619
+ if (Math.hypot(pixel(x / 16), pixel(y / 16)) > limit * width / 32) {
28614
28620
  return null;
28615
28621
  }
28616
- return [Math.floor(mx + 0.5), Math.floor(my + 0.5)];
28622
+ return [x, y];
28617
28623
  }
28618
28624
 
28619
28625
  // src/emf-gdi-raster-shapes.ts
package/dist/index.mjs CHANGED
@@ -15862,7 +15862,7 @@ function mirror(p, n) {
15862
15862
  }
15863
15863
  return p;
15864
15864
  }
15865
- function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h) {
15865
+ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical = false, edgeWidth = w, edgeHeight = h, verticalRows = Math.ceil(h / w)) {
15866
15866
  const k = blurKernel(radius);
15867
15867
  const taps = (k.length - 1) / 2;
15868
15868
  const horizontalIndex = taps >= edgeWidth ? (x) => Math.max(0, Math.min(w - 1, x)) : (x) => mirror(x, w);
@@ -15892,7 +15892,7 @@ function gdipBlur(src, w, h, radius, vRow = 0, vZeroAbove = false, fullVertical
15892
15892
  }
15893
15893
  if (taps > 0 && vRow >= 0 && vRow < h) {
15894
15894
  const horizontal = out.slice();
15895
- const endRow = fullVertical ? h : Math.min(h, vRow + Math.ceil(h / w));
15895
+ const endRow = fullVertical ? h : Math.min(h, vRow + verticalRows);
15896
15896
  for (let row = vRow; row < endRow; row++) {
15897
15897
  const col = new Float64Array(w * 4);
15898
15898
  for (let j = -taps; j <= taps; j++) {
@@ -16011,13 +16011,12 @@ function copyBlock(src, width, sx, sy, w, h, dst, bw, dx, dy) {
16011
16011
  dst.set(src.subarray(from, from + w * 4), ((dy + y) * bw + dx) * 4);
16012
16012
  }
16013
16013
  }
16014
- function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1) {
16014
+ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1, cropped) {
16015
16015
  const r = Math.ceil(radius);
16016
16016
  const bw = x1 - x0 + 2 * r;
16017
16017
  const bh = y1 - y0 + 2 * r;
16018
16018
  const buf = new Uint8ClampedArray(bw * bh * 4);
16019
- const inside = x0 - r >= 0 && y0 - r >= 0 && x1 + r <= width && y1 + r <= height;
16020
- if (inside) {
16019
+ if (cropped) {
16021
16020
  copyBlock(rgba, width, x0, y0, x1 - x0, y1 - y0, buf, bw, r, r);
16022
16021
  } else {
16023
16022
  const gx0 = Math.max(0, x0 - r);
@@ -16026,7 +16025,7 @@ function expandedBlur(rgba, width, height, radius, x0, y0, x1, y1) {
16026
16025
  const gy1 = Math.min(height, y1 + r);
16027
16026
  copyBlock(rgba, width, gx0, gy0, gx1 - gx0, gy1 - gy0, buf, bw, gx0 - (x0 - r), gy0 - (y0 - r));
16028
16027
  }
16029
- const blurred = gdipBlur(buf, bw, bh, radius, inside ? r : 0, inside);
16028
+ const blurred = blurReduction(radius) > 1 ? effectBlur(buf, bw, bh, radius) : gdipBlur(buf, bw, bh, radius, cropped ? r : 0, cropped, false, bw, bh, Math.ceil((y1 - y0) / (x1 - x0)));
16030
16029
  const w = x1 - x0;
16031
16030
  const out = new Uint8ClampedArray(w * (y1 - y0) * 4);
16032
16031
  for (let y = 0; y < y1 - y0; y++) {
@@ -16067,7 +16066,8 @@ function applyImageEffectToRect(rgba, width, height, effect, src) {
16067
16066
  return { rgba: shown, x: x0, y: y0, width: shownWidth, height: shownHeight };
16068
16067
  };
16069
16068
  if (src && effect.kind === "blur" && effect.expandEdge) {
16070
- return result(expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1));
16069
+ const cropped = Math.ceil(src.x + src.w) < width && Math.ceil(src.y + src.h) < height;
16070
+ return result(expandedBlur(rgba, width, height, effect.radius, x0, y0, x1, y1, cropped));
16071
16071
  }
16072
16072
  let region = rgba;
16073
16073
  if (w !== width || h !== height) {
@@ -28140,7 +28140,7 @@ function drawVertices(pen, dx, dy) {
28140
28140
  function halfPixel(v) {
28141
28141
  return Math.sign(v) * 8 * Math.floor((Math.abs(v) + 4) / 8);
28142
28142
  }
28143
- function flatVector(width, dx0, dy0) {
28143
+ function perpendicularVectors(width, dx0, dy0) {
28144
28144
  let dx = dx0;
28145
28145
  let dy = dy0;
28146
28146
  const flip = dx < 0 || dx === 0 && dy < 0;
@@ -28174,9 +28174,9 @@ function flatVector(width, dx0, dy0) {
28174
28174
  const ox = off ? sgn * off[0] : 0;
28175
28175
  const oy = off ? sgn * off[1] : 0;
28176
28176
  const r = (v) => 8 * Math.floor((v + 4) / 8);
28177
- const vx = r(D[0] + (B[0] - D[0]) * w + 0.5 * Math.sign(dy) + ox);
28178
- const vy = r(D[1] + (B[1] - D[1]) * w + 0.5 * Math.sign(dx) + oy);
28179
- return flip ? [-vx, -vy] : [vx, vy];
28177
+ const x = D[0] + (B[0] - D[0]) * w, y = D[1] + (B[1] - D[1]) * w;
28178
+ const vx = r(x + 0.5 * Math.sign(dy) + ox), vy = r(y + 0.5 * Math.sign(dx) + oy);
28179
+ return { v: flip ? [-vx, -vy] : [vx, vy], ray: flip ? [-x, -y] : [x, y] };
28180
28180
  }
28181
28181
  function squareExtension(width, dx, dy) {
28182
28182
  const len = Math.hypot(dx, dy);
@@ -28219,7 +28219,8 @@ var Outliner = class {
28219
28219
  const d = drawDir ?? [dx, dy];
28220
28220
  const [L, R] = drawVertices(this.pen, d[0], d[1]);
28221
28221
  const perpendicular = this.opts.roundCurveJoins && drawDir ? drawDir : [dx, dy];
28222
- return { dx, dy, L, R, v: flatVector(this.opts.width, perpendicular[0], perpendicular[1]), e: squareExtension(this.opts.width, dx, dy), curveEnd: !!drawDir };
28222
+ const vectors = perpendicularVectors(this.opts.width, perpendicular[0], perpendicular[1]);
28223
+ return { dx, dy, L, R, v: vectors.v, vRaw: vectors.ray, e: squareExtension(this.opts.width, dx, dy), curveEnd: !!drawDir };
28223
28224
  }
28224
28225
  push(p, v) {
28225
28226
  this.pts.push([p[0] + v[0], p[1] + v[1]]);
@@ -28315,7 +28316,7 @@ var Outliner = class {
28315
28316
  if (this.rr) {
28316
28317
  this.walk(p, s[from], s[to], false, false);
28317
28318
  } else {
28318
- const A = this.capSide(s, from);
28319
+ const A = from === "R" ? s.vRaw : [-s.vRaw[0], -s.vRaw[1]];
28319
28320
  this.wedge(p, A, [-A[0], -A[1]], true, false);
28320
28321
  }
28321
28322
  this.push(p, this.capSide(s, to));
@@ -28342,6 +28343,8 @@ var Outliner = class {
28342
28343
  const join = this.opts.roundCurveJoins ? "round" : this.opts.join;
28343
28344
  let sa = this.joinSide(a, side);
28344
28345
  let sb = this.joinSide(b, side);
28346
+ const rayA = side === "R" ? a.vRaw : [-a.vRaw[0], -a.vRaw[1]];
28347
+ const rayB = side === "R" ? b.vRaw : [-b.vRaw[0], -b.vRaw[1]];
28345
28348
  if (this.opts.roundCurveJoins && !this.originalRoundJoinSides && a.curveEnd && b.curveEnd) {
28346
28349
  sa = side === "R" ? a.v : [-a.v[0], -a.v[1]];
28347
28350
  sb = side === "R" ? b.v : [-b.v[0], -b.v[1]];
@@ -28362,10 +28365,10 @@ var Outliner = class {
28362
28365
  this.walk(p, Da, Db, false, incl);
28363
28366
  } else {
28364
28367
  const anti = sa[0] === -sb[0] && sa[1] === -sb[1];
28365
- this.wedge(p, sa, sb, !anti, !anti);
28368
+ this.wedge(p, rayA, rayB, !anti, !anti);
28366
28369
  }
28367
28370
  } else if (join === "miter") {
28368
- const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit);
28371
+ const m = miterPoint(sa, [a.dx, a.dy], sb, [b.dx, b.dy], width, miterLimit, side);
28369
28372
  if (m) {
28370
28373
  this.push(p, m);
28371
28374
  }
@@ -28379,7 +28382,7 @@ var Outliner = class {
28379
28382
  }
28380
28383
  if (join === "round" && cap === "flat" && !this.opts.roundCurveJoins) {
28381
28384
  this.push(p, sb);
28382
- this.wedge(p, sb, sa, false, false);
28385
+ this.wedge(p, rayB, rayA, false, false);
28383
28386
  this.push(p, sa);
28384
28387
  this.pts.push([p[0], p[1]]);
28385
28388
  }
@@ -28598,7 +28601,7 @@ function widenPath(path, opts) {
28598
28601
  }
28599
28602
  return out;
28600
28603
  }
28601
- function miterPoint(sa, da, sb, db, width, limit) {
28604
+ function miterPoint(sa, da, sb, db, width, limit, side) {
28602
28605
  const den = da[0] * db[1] - da[1] * db[0];
28603
28606
  if (den === 0) {
28604
28607
  return null;
@@ -28608,10 +28611,13 @@ function miterPoint(sa, da, sb, db, width, limit) {
28608
28611
  const t = (wx * db[1] - wy * db[0]) / den;
28609
28612
  const mx = sa[0] + da[0] * t;
28610
28613
  const my = sa[1] + da[1] * t;
28611
- if (Math.hypot(mx, my) > limit * width / 2) {
28614
+ const x = Math.sign(mx) * Math.floor(Math.abs(mx) + 0.5);
28615
+ const y = Math.sign(my) * Math.floor(Math.abs(my) + 0.5);
28616
+ const pixel = side === "L" ? Math.ceil : Math.floor;
28617
+ if (Math.hypot(pixel(x / 16), pixel(y / 16)) > limit * width / 32) {
28612
28618
  return null;
28613
28619
  }
28614
- return [Math.floor(mx + 0.5), Math.floor(my + 0.5)];
28620
+ return [x, y];
28615
28621
  }
28616
28622
 
28617
28623
  // src/emf-gdi-raster-shapes.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emf-converter",
3
- "version": "4.4.12",
3
+ "version": "4.4.14",
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",