emf-converter 4.8.3 → 4.8.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.mjs CHANGED
@@ -11704,6 +11704,11 @@ function ellipsePoints(box, cwControls) {
11704
11704
  P(hCtl, full);
11705
11705
  P(full, rightLower);
11706
11706
  P(full, vMidHi);
11707
+ if (box.halfX) {
11708
+ for (const k of [0, 1, 2, 3, 4, 5, 12]) {
11709
+ out[2 * k]++;
11710
+ }
11711
+ }
11707
11712
  return out;
11708
11713
  }
11709
11714
  function ellipseBeziers(l, t, r, b) {
@@ -11773,76 +11778,15 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = fa
11773
11778
  ];
11774
11779
  }
11775
11780
  var TRIG_STEP = 2 * Math.PI / 128;
11776
- var TRIG_NODES = [
11777
- 1,
11778
- 0.99879566,
11779
- 0.99518639,
11780
- 0.98917961,
11781
- 0.98079146,
11782
- 0.97003981,
11783
- 0.95695228,
11784
- 0.94155978,
11785
- 0.92389844,
11786
- 0.90401145,
11787
- 0.88194619,
11788
- 0.85775575,
11789
- 0.83149879,
11790
- 0.80323775,
11791
- 0.77303903,
11792
- 0.74098864,
11793
- 0.70710648,
11794
- 0.67151859,
11795
- 0.63435836,
11796
- 0.59565849,
11797
- 0.55552672,
11798
- 0.51405765,
11799
- 0.47135039,
11800
- 0.42750875,
11801
- 0.38263811,
11802
- 0.33684632,
11803
- 0.29024443,
11804
- 0.24294646,
11805
- 0.19505974,
11806
- 0.14670808,
11807
- 0.0980012,
11808
- 0.04906089,
11809
- 0
11810
- ];
11811
- var TRIG_TABLE = (() => {
11812
- const cos = [];
11813
- const sin = [];
11814
- for (let k = 0; k <= 128; k++) {
11815
- const q = k >> 5;
11816
- const i = k & 31;
11817
- const c = TRIG_NODES[i];
11818
- const s = TRIG_NODES[32 - i];
11819
- if (k === 128) {
11820
- cos.push(1);
11821
- sin.push(0);
11822
- continue;
11823
- }
11824
- cos.push([c, -s, -c, s][q]);
11825
- sin.push([s, c, -s, -c][q]);
11826
- }
11827
- return { cos, sin };
11828
- })();
11829
- function tableTrig(table) {
11830
- return (a) => {
11831
- let b = a % (2 * Math.PI);
11832
- if (b < 0) {
11833
- b += 2 * Math.PI;
11834
- }
11835
- const x = b / TRIG_STEP;
11836
- const i = Math.min(127, Math.floor(x));
11837
- const f = x - i;
11838
- return table[i] * (1 - f) + table[i + 1] * f;
11839
- };
11840
- }
11841
- var tableCos = tableTrig(TRIG_TABLE.cos);
11842
- var tableSin = tableTrig(TRIG_TABLE.sin);
11781
+ var tableCos = (angle) => polygonTrig(angle)[0];
11782
+ var tableSin = (angle) => polygonTrig(angle)[1];
11843
11783
  function angleArcPieces(startDeg, sweepDeg) {
11844
11784
  const out = [];
11845
11785
  const arc = (from, to) => {
11786
+ if (Math.abs(to - from) < 90) {
11787
+ out.push({ from, to, first: true });
11788
+ return;
11789
+ }
11846
11790
  const lo = Math.min(from, to);
11847
11791
  const hi = Math.max(from, to);
11848
11792
  const pieces = Math.floor(hi / 90) - Math.floor(lo / 90) + 1;
@@ -11891,7 +11835,8 @@ function angleArcFix(box, startDeg, sweepDeg) {
11891
11835
  const E = ellipseBeziers(l, t, l + w, t + h);
11892
11836
  const Ecw = clockwiseEllipseBeziersBox(axisBox(l, t, l + w, t + h));
11893
11837
  const start = startDeg * Math.PI / 180;
11894
- const out = [Math.round(cx + w / 2 * tableCos(start)), Math.round(cy - h / 2 * tableSin(start))];
11838
+ const startUnit = Math.abs(sweepDeg) <= 3 ? [Math.cos(start), Math.sin(start)] : polygonTrig(start);
11839
+ const out = [Math.round(cx + w / 2 * startUnit[0]), Math.round(cy - h / 2 * startUnit[1])];
11895
11840
  for (const p of angleArcPieces(startDeg, sweepDeg)) {
11896
11841
  const span = p.to - p.from;
11897
11842
  if (!p.first && Math.abs(span) === 90 && p.from % 90 === 0) {
@@ -11904,43 +11849,80 @@ function angleArcFix(box, startDeg, sweepDeg) {
11904
11849
  }
11905
11850
  continue;
11906
11851
  }
11907
- for (const v of circularArcBezier(cx, cy, w / 2, h / 2, p.from, p.to)) {
11908
- out.push(Math.round(v));
11852
+ const piece = unitPiece(p.from * Math.PI / 180, p.to * Math.PI / 180, Math.abs(sweepDeg) <= 3);
11853
+ for (let i = 0; i < 6; i += 2) {
11854
+ out.push(Math.round(cx + w / 2 * piece.ctrl[i]), Math.round(cy - h / 2 * piece.ctrl[i + 1]));
11909
11855
  }
11910
11856
  }
11911
11857
  return out;
11912
11858
  }
11913
11859
  var SMALL_SWEEP = 3 * Math.PI / 180;
11914
- function anchoredPiece(boundary, free, rx, ry, cx, cy, smallArc) {
11915
- const sweep = Math.abs(free - boundary);
11916
- const small = smallArc;
11917
- const cos = small ? Math.cos : tableCos;
11918
- const sin = small ? Math.sin : tableSin;
11919
- const anchor = [Math.round(cx + rx * Math.cos(boundary)), Math.round(cy - ry * Math.sin(boundary))];
11920
- const point = [cx + rx * cos(free), cy - ry * sin(free)];
11921
- let t;
11922
- let kappa;
11923
- if (small) {
11924
- t = Math.tan(sweep / 2);
11925
- kappa = 2 / 3 * (1 - Math.tan(sweep / 4) ** 2);
11860
+ var POLYGON_NODES = (() => {
11861
+ const cos = [];
11862
+ const sin = [];
11863
+ for (let k = 0; k <= 129; k++) {
11864
+ cos.push(Math.cos(k * TRIG_STEP));
11865
+ sin.push(Math.sin(k * TRIG_STEP));
11866
+ }
11867
+ for (let k = 0; k <= 128; k += 32) {
11868
+ cos[k] = [1, 0, -1, 0, 1][k / 32];
11869
+ sin[k] = [0, 1, 0, -1, 0][k / 32];
11870
+ }
11871
+ return { cos, sin };
11872
+ })();
11873
+ function polygonTrig(angle) {
11874
+ let b = angle % (2 * Math.PI);
11875
+ if (b < 0) {
11876
+ b += 2 * Math.PI;
11877
+ }
11878
+ const x = b / TRIG_STEP;
11879
+ const i = Math.min(127, Math.floor(x));
11880
+ const f = x - i;
11881
+ return [
11882
+ POLYGON_NODES.cos[i] * (1 - f) + POLYGON_NODES.cos[i + 1] * f,
11883
+ POLYGON_NODES.sin[i] * (1 - f) + POLYGON_NODES.sin[i + 1] * f
11884
+ ];
11885
+ }
11886
+ var ATAN_KNOTS = Array.from({ length: 33 }, (_, j) => Math.atan(j / 32));
11887
+ function interpolatedAtan(t) {
11888
+ const x = t * 32;
11889
+ const j = Math.min(31, Math.floor(x));
11890
+ return ATAN_KNOTS[j] + (ATAN_KNOTS[j + 1] - ATAN_KNOTS[j]) * (x - j);
11891
+ }
11892
+ function approximateArcAngle(x, y) {
11893
+ const ax = Math.abs(x);
11894
+ const ay = Math.abs(y);
11895
+ if (ax === 0 && ay === 0) {
11896
+ return 0;
11897
+ }
11898
+ const a = ay <= ax ? interpolatedAtan(ay / ax) : Math.PI / 2 - interpolatedAtan(ax / ay);
11899
+ if (x >= 0) {
11900
+ return y >= 0 ? a : 2 * Math.PI - a;
11901
+ }
11902
+ return y >= 0 ? Math.PI - a : Math.PI + a;
11903
+ }
11904
+ function unitPiece(from, to, small) {
11905
+ const trig = small ? (a) => [Math.cos(a), Math.sin(a)] : polygonTrig;
11906
+ const p0 = trig(from);
11907
+ const p3 = trig(to);
11908
+ const det = p0[0] * p3[1] - p0[1] * p3[0];
11909
+ let ctrl;
11910
+ if (Math.abs(det) < 1e-12) {
11911
+ ctrl = [p0[0], p0[1], p3[0], p3[1], p3[0], p3[1]];
11926
11912
  } else {
11927
- const c = tableCos(sweep);
11928
- const sn = tableSin(sweep);
11929
- t = (1 - c) / sn;
11930
- const q = t / (1 + Math.sqrt(1 + t * t));
11931
- kappa = 2 / 3 * (1 - q * q);
11932
- }
11933
- const dir = free > boundary ? 1 : -1;
11934
- const tx = -Math.round(Math.sin(boundary));
11935
- const ty = -Math.round(Math.cos(boundary));
11936
- const length = tx !== 0 ? rx : ry;
11937
- const X = [anchor[0] + dir * tx * length * t, anchor[1] + dir * ty * length * t];
11938
- return {
11939
- anchor,
11940
- free: point,
11941
- cAnchor: [anchor[0] + kappa * (X[0] - anchor[0]), anchor[1] + kappa * (X[1] - anchor[1])],
11942
- cFree: [point[0] + kappa * (X[0] - point[0]), point[1] + kappa * (X[1] - point[1])]
11943
- };
11913
+ const X = [(p3[1] - p0[1]) / det, (p0[0] - p3[0]) / det];
11914
+ const c = polygonTrig(Math.abs(to - from) / 2)[0];
11915
+ const kappa = 4 / 3 * c / (1 + c);
11916
+ ctrl = [
11917
+ p0[0] + kappa * (X[0] - p0[0]),
11918
+ p0[1] + kappa * (X[1] - p0[1]),
11919
+ p3[0] + kappa * (X[0] - p3[0]),
11920
+ p3[1] + kappa * (X[1] - p3[1]),
11921
+ p3[0],
11922
+ p3[1]
11923
+ ];
11924
+ }
11925
+ return { start: p0, ctrl };
11944
11926
  }
11945
11927
  function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
11946
11928
  const w = r - l;
@@ -11952,24 +11934,30 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
11952
11934
  const cy = t + Math.ceil(h / 2);
11953
11935
  const tcx = (l + r) / 2;
11954
11936
  const tcy = (t + b) / 2;
11955
- const angle = (x, y) => Math.atan2(-(y - tcy) / (h / 2 || 1), (x - tcx) / (w / 2 || 1));
11937
+ const angle = (x, y) => approximateArcAngle((x - tcx) / (w / 2 || 1), -(y - tcy) / (h / 2 || 1));
11956
11938
  const a0 = angle(xs, ys);
11957
11939
  let a1 = angle(xe, ye);
11940
+ const small = a1 !== a0 && Math.abs(a1 - a0) <= SMALL_SWEEP;
11958
11941
  const s = clockwise ? -1 : 1;
11959
11942
  if (s > 0) {
11960
11943
  while (a1 <= a0) a1 += 2 * Math.PI;
11961
11944
  } else {
11962
11945
  while (a1 >= a0) a1 -= 2 * Math.PI;
11963
11946
  }
11964
- const px = (a2) => cx + rx * tableCos(a2);
11965
- const py = (a2) => cy - ry * tableSin(a2);
11947
+ const px = (u) => Math.round(cx + rx * u);
11948
+ const py = (v) => Math.round(cy - ry * v);
11966
11949
  const E = clockwise ? clockwiseEllipseBeziersBox(axisBox(l, t, r, b)) : ellipseBeziers(l, t, r, b);
11967
- const out = [Math.round(px(a0)), Math.round(py(a0))];
11950
+ const startUnit = small ? [Math.cos(a0), Math.sin(a0)] : polygonTrig(a0);
11951
+ const out = [px(startUnit[0]), py(startUnit[1])];
11968
11952
  let a = a0;
11969
11953
  for (let guard = 0; guard < 8 && (s > 0 ? a < a1 - 1e-12 : a > a1 + 1e-12); guard++) {
11970
11954
  const next = s > 0 ? Math.floor(a / Q + 1e-9) * Q + Q : Math.ceil(a / Q - 1e-9) * Q - Q;
11971
11955
  const onBoundary = Math.abs(a / Q - Math.round(a / Q)) < 1e-9;
11972
- if (onBoundary && (s > 0 ? next <= a1 + 1e-12 : next >= a1 - 1e-12)) {
11956
+ const reachesEnd = s > 0 ? next >= a1 - 1e-12 : next <= a1 + 1e-12;
11957
+ const quadrantFrom = (Math.round(a / Q) % 4 + 4) % 4;
11958
+ const quadrantTo = (Math.round(next / Q) % 4 + 4) % 4;
11959
+ const generic = guard === 0 && (s > 0 ? quadrantFrom === 0 || quadrantFrom === 3 : quadrantFrom === 0 || quadrantFrom === 1) || reachesEnd && (s > 0 ? quadrantTo === 1 || quadrantTo === 2 : quadrantTo === 2 || quadrantTo === 3);
11960
+ if (!generic && onBoundary && (s > 0 ? next <= a1 + 1e-12 : next >= a1 - 1e-12)) {
11973
11961
  const qi = (Math.round(Math.min(a, next) / Q) % 4 + 4) % 4 * 6;
11974
11962
  if (s > 0) {
11975
11963
  out.push(E[qi + 2], E[qi + 3], E[qi + 4], E[qi + 5], E[qi + 6], E[qi + 7]);
@@ -11980,30 +11968,10 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
11980
11968
  continue;
11981
11969
  }
11982
11970
  const e = s > 0 ? Math.min(next, a1) : Math.max(next, a1);
11983
- const endOnBoundary = Math.abs(e / Q - Math.round(e / Q)) < 1e-9;
11984
- if (onBoundary !== endOnBoundary) {
11985
- const piece = anchoredPiece(onBoundary ? a : e, onBoundary ? e : a, rx, ry, cx, cy, Math.abs(a1 - a0) <= SMALL_SWEEP);
11986
- if (onBoundary) {
11987
- out.push(...[piece.cAnchor, piece.cFree, piece.free].flatMap((q) => [Math.round(q[0]), Math.round(q[1])]));
11988
- } else {
11989
- if (out.length === 2) {
11990
- out[0] = Math.round(piece.free[0]);
11991
- out[1] = Math.round(piece.free[1]);
11992
- }
11993
- out.push(...[piece.cFree, piece.cAnchor, piece.anchor].flatMap((q) => [Math.round(q[0]), Math.round(q[1])]));
11994
- }
11995
- a = e;
11996
- continue;
11971
+ const piece = unitPiece(a, e, small);
11972
+ for (let i = 0; i < 6; i += 2) {
11973
+ out.push(px(piece.ctrl[i]), py(piece.ctrl[i + 1]));
11997
11974
  }
11998
- const k = 4 / 3 * Math.tan((e - a) / 4);
11999
- out.push(
12000
- Math.round(px(a) - k * rx * tableSin(a)),
12001
- Math.round(py(a) - k * ry * tableCos(a)),
12002
- Math.round(px(e) + k * rx * tableSin(e)),
12003
- Math.round(py(e) + k * ry * tableCos(e)),
12004
- Math.round(px(e)),
12005
- Math.round(py(e))
12006
- );
12007
11975
  a = e;
12008
11976
  }
12009
11977
  return out;
@@ -16808,14 +16776,21 @@ function blurKernel(radius) {
16808
16776
  k[0] = 1;
16809
16777
  return k;
16810
16778
  }
16811
- let sum = 0;
16812
- for (let i = -taps; i <= taps; i++) {
16813
- const w = Math.exp(-1.96 * i * i / (radius * radius));
16814
- k[i + taps] = w;
16815
- sum += w;
16816
- }
16817
- for (let i = 0; i < k.length; i++) {
16818
- k[i] /= sum;
16779
+ const step = truncF32(truncF32(1.4) / Math.fround(radius));
16780
+ const w = new Float64Array(taps + 1);
16781
+ w[0] = 1;
16782
+ let offset = 0;
16783
+ let sum = 1;
16784
+ for (let i = 1; i <= taps; i++) {
16785
+ offset = truncF32(offset + step);
16786
+ w[i] = truncF32(Math.exp(-truncF32(offset * offset)));
16787
+ sum = truncF32(sum + truncF32(2 * w[i]));
16788
+ }
16789
+ const scale = truncF32(256 / sum);
16790
+ for (let i = 0; i <= taps; i++) {
16791
+ const weight = truncF32(w[i] * scale) / 256;
16792
+ k[taps + i] = weight;
16793
+ k[taps - i] = weight;
16819
16794
  }
16820
16795
  return k;
16821
16796
  }
@@ -29841,6 +29816,11 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = fal
29841
29816
  for (let i = 0; i < q.length; i += 2) {
29842
29817
  pts.push(...map(q[i], clockwise ? f.t + f.b - q[i + 1] : q[i + 1]));
29843
29818
  }
29819
+ if (box.halfX && !clockwise) {
29820
+ for (const k of [1, 2, 3, 4, 5, 6, 8, 15]) {
29821
+ pts[2 * k]++;
29822
+ }
29823
+ }
29844
29824
  return pts;
29845
29825
  }
29846
29826
  function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false, compatible = false) {
@@ -30922,6 +30902,51 @@ function fixExtent(rCtx, v, axis) {
30922
30902
  const k = axis === 0 ? Math.hypot(m[0], m[1]) : Math.hypot(m[2], m[3]);
30923
30903
  return Math.round(Math.abs(v) * k * 16);
30924
30904
  }
30905
+ var PS_INSIDEFRAME = 6;
30906
+ function insideFrameInset(rCtx, box, rectangle = false) {
30907
+ if ((rCtx.state.penStyle & 15) !== PS_INSIDEFRAME || !isAxisBox(box) || hasWorldRotation(rCtx)) {
30908
+ return null;
30909
+ }
30910
+ const m = gdiDeviceMatrix(rCtx);
30911
+ const px = gdiDevicePixelX(rCtx);
30912
+ const py = gdiDevicePixelY(rCtx);
30913
+ const widthX = Math.abs(rCtx.state.penWidth * m[0]) / px * 16;
30914
+ const widthY = Math.abs(rCtx.state.penWidth * m[3]) / py * 16;
30915
+ if (Math.max(widthX, widthY) < 24) {
30916
+ return null;
30917
+ }
30918
+ const wx = Math.round(widthX);
30919
+ const wy = Math.round(widthY);
30920
+ if (Math.abs(box.exx) / px < wx || Math.abs(box.eyy) / py < wy) {
30921
+ return null;
30922
+ }
30923
+ const lo = Math.floor(wx / 2);
30924
+ const hi = Math.ceil(wx / 2);
30925
+ const y = Math.round(Math.ceil(wy / 2) * py);
30926
+ return {
30927
+ left: Math.round((rectangle ? hi : lo) * px),
30928
+ right: Math.round((rectangle ? lo : hi) * px),
30929
+ top: y,
30930
+ bottom: y,
30931
+ half: wx % 2 === 1 && !rectangle
30932
+ };
30933
+ }
30934
+ function insetFixBox(box, inset) {
30935
+ const sx = box.exx < 0 ? -1 : 1;
30936
+ const sy = box.eyy < 0 ? -1 : 1;
30937
+ const framed = {
30938
+ ax: box.ax + sx * inset.left,
30939
+ ay: box.ay + sy * inset.top,
30940
+ exx: box.exx - sx * (inset.left + inset.right),
30941
+ exy: 0,
30942
+ eyx: 0,
30943
+ eyy: box.eyy - sy * (inset.top + inset.bottom)
30944
+ };
30945
+ if (inset.half && sx > 0) {
30946
+ framed.halfX = true;
30947
+ }
30948
+ return framed;
30949
+ }
30925
30950
  function handleSetPixelV(rCtx, dataOff, recSize) {
30926
30951
  const { ctx, view } = rCtx;
30927
30952
  if (recSize >= 20) {
@@ -30994,7 +31019,9 @@ function handleRectangle(rCtx, dataOff, recSize) {
30994
31019
  const t = view.getInt32(dataOff + 4, true);
30995
31020
  const r = view.getInt32(dataOff + 8, true);
30996
31021
  const b = view.getInt32(dataOff + 12, true);
30997
- const box = uprightFixBox(rCtx, l, t, r, b);
31022
+ const unframed = uprightFixBox(rCtx, l, t, r, b);
31023
+ const inset = insideFrameInset(rCtx, unframed, true);
31024
+ const box = inset ? insetFixBox(unframed, inset) : unframed;
30998
31025
  const clockwise = rCtx.state.arcDirection === 2;
30999
31026
  if (!inPath) {
31000
31027
  resetLineStyle(rCtx);
@@ -31029,10 +31056,16 @@ function handleRectangle(rCtx, dataOff, recSize) {
31029
31056
  }
31030
31057
  return true;
31031
31058
  }
31032
- const x = gmx(rCtx, l);
31033
- const y = gmy(rCtx, t);
31034
- const w = gmw(rCtx, r - l);
31035
- const h = gmh(rCtx, b - t);
31059
+ let x = gmx(rCtx, l);
31060
+ let y = gmy(rCtx, t);
31061
+ let w = gmw(rCtx, r - l);
31062
+ let h = gmh(rCtx, b - t);
31063
+ if (inset) {
31064
+ x = Math.min(box.ax, box.ax + box.exx) / 16;
31065
+ y = Math.min(box.ay, box.ay + box.eyy) / 16;
31066
+ w = Math.abs(box.exx) / 16;
31067
+ h = Math.abs(box.eyy) / 16;
31068
+ }
31036
31069
  if (inPath) {
31037
31070
  recordRectangle(rCtx, box, clockwise);
31038
31071
  } else if (needsPathBasedRectangle(rCtx)) {
@@ -31144,7 +31177,26 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31144
31177
  const b = view.getInt32(dataOff + 12, true);
31145
31178
  const cornerW = view.getInt32(dataOff + 16, true);
31146
31179
  const cornerH = view.getInt32(dataOff + 20, true);
31147
- const drawRoundRect = hasWorldRotation(rCtx) ? (c) => appendRoundRectPath(c, l, t, r, b, cornerW / 2, cornerH / 2, (x, y) => gmapPoint(rCtx, x, y)) : (c) => appendRoundRectPath(
31180
+ const clockwise = rCtx.state.arcDirection === 2;
31181
+ const unframed = uprightFixBox(rCtx, l, t, r, b);
31182
+ const inset = insideFrameInset(rCtx, unframed);
31183
+ const framed = inset ? insetFixBox(unframed, inset) : unframed;
31184
+ const devM = gdiDeviceMatrix(rCtx);
31185
+ const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
31186
+ const cornerFixH = inset ? Math.abs(cornerH * devM[3]) * 16 : fixExtent(rCtx, cornerH, 1);
31187
+ const cornerOnFrame = (fix, size, framedSize) => inset && size !== 0 ? Math.floor(Math.min(fix, size) * framedSize / size) : fix;
31188
+ const cw = cornerOnFrame(cornerFixW, Math.abs((r - l) * devM[0]) * 16, Math.abs(framed.exx));
31189
+ const ch = cornerOnFrame(cornerFixH, Math.abs((b - t) * devM[3]) * 16, Math.abs(framed.eyy));
31190
+ const drawRoundRect = inset ? (c) => appendRoundRectPath(
31191
+ c,
31192
+ Math.min(framed.ax, framed.ax + framed.exx) / 16,
31193
+ Math.min(framed.ay, framed.ay + framed.eyy) / 16,
31194
+ Math.max(framed.ax, framed.ax + framed.exx) / 16,
31195
+ Math.max(framed.ay, framed.ay + framed.eyy) / 16,
31196
+ cw / 32,
31197
+ ch / 32,
31198
+ null
31199
+ ) : hasWorldRotation(rCtx) ? (c) => appendRoundRectPath(c, l, t, r, b, cornerW / 2, cornerH / 2, (x, y) => gmapPoint(rCtx, x, y)) : (c) => appendRoundRectPath(
31148
31200
  c,
31149
31201
  gmx(rCtx, l),
31150
31202
  gmy(rCtx, t),
@@ -31154,13 +31206,12 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31154
31206
  gmh(rCtx, cornerH) / 2,
31155
31207
  null
31156
31208
  );
31157
- const clockwise = rCtx.state.arcDirection === 2;
31158
- const raster = (box = uprightFixBox(rCtx, l, t, r, b)) => roundRectRasterPath(box, fixExtent(rCtx, cornerW, 0), fixExtent(rCtx, cornerH, 1), clockwise, cornerW === 0 || cornerH === 0);
31209
+ const raster = (box = framed) => roundRectRasterPath(box, cw, ch, clockwise, cornerW === 0 || cornerH === 0);
31159
31210
  if (inPath) {
31160
- const box = uprightFixBox(rCtx, l, t, r, b);
31211
+ const box = framed;
31161
31212
  if (cornerW === 0 || cornerH === 0) recordRectangle(rCtx, box, clockwise);
31162
31213
  else {
31163
- recordBezierShape(rCtx, roundRectDeviceBeziers(box, fixExtent(rCtx, cornerW, 0), fixExtent(rCtx, cornerH, 1), clockwise), 8);
31214
+ recordBezierShape(rCtx, roundRectDeviceBeziers(box, cw, ch, clockwise), 8);
31164
31215
  rasterPathOf(rCtx).append(raster(box));
31165
31216
  }
31166
31217
  } else {
@@ -31170,7 +31221,7 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31170
31221
  c.beginPath();
31171
31222
  drawRoundRect(c);
31172
31223
  },
31173
- raster: () => raster(curvedFixBox(rCtx, l, t, r, b, true)),
31224
+ raster: () => raster(inset ? framed : curvedFixBox(rCtx, l, t, r, b, true)),
31174
31225
  roundPen: true,
31175
31226
  fill: true,
31176
31227
  stroke: true
@@ -31207,7 +31258,10 @@ function handleEllipse(rCtx, dataOff, recSize) {
31207
31258
  const r = view.getInt32(dataOff + 8, true);
31208
31259
  const b = view.getInt32(dataOff + 12, true);
31209
31260
  const clockwise = rCtx.state.arcDirection === 2;
31210
- const params = hasWorldRotation(rCtx) ? gdiEllipseParams(rCtx, (l + r) / 2, (t + b) / 2, Math.abs(r - l) / 2, Math.abs(b - t) / 2) : {
31261
+ const unframed = uprightFixBox(rCtx, l, t, r, b);
31262
+ const inset = insideFrameInset(rCtx, unframed);
31263
+ const framed = inset ? insetFixBox(unframed, inset) : unframed;
31264
+ const params = inset ? { cx: (framed.ax + framed.exx / 2) / 16, cy: (framed.ay + framed.eyy / 2) / 16, rx: Math.abs(framed.exx) / 32, ry: Math.abs(framed.eyy) / 32, rotation: 0 } : hasWorldRotation(rCtx) ? gdiEllipseParams(rCtx, (l + r) / 2, (t + b) / 2, Math.abs(r - l) / 2, Math.abs(b - t) / 2) : {
31211
31265
  cx: gmx(rCtx, (l + r) / 2),
31212
31266
  cy: gmy(rCtx, (t + b) / 2),
31213
31267
  rx: Math.abs(gmw(rCtx, r - l)) / 2,
@@ -31215,7 +31269,7 @@ function handleEllipse(rCtx, dataOff, recSize) {
31215
31269
  rotation: 0
31216
31270
  };
31217
31271
  if (inPath) {
31218
- const box = uprightFixBox(rCtx, l, t, r, b);
31272
+ const box = framed;
31219
31273
  recordBezierShape(rCtx, ellipseBeziersBox(box, clockwise), 6);
31220
31274
  rasterPathOf(rCtx).append(ellipseRasterPath(box, clockwise));
31221
31275
  } else {
@@ -31225,7 +31279,7 @@ function handleEllipse(rCtx, dataOff, recSize) {
31225
31279
  c.beginPath();
31226
31280
  c.ellipse(params.cx, params.cy, params.rx, params.ry, params.rotation, 0, Math.PI * 2);
31227
31281
  },
31228
- raster: () => ellipseRasterPath(curvedFixBox(rCtx, l, t, r, b, true), clockwise),
31282
+ raster: () => ellipseRasterPath(inset ? framed : curvedFixBox(rCtx, l, t, r, b, true), clockwise),
31229
31283
  roundPen: true,
31230
31284
  fill: true,
31231
31285
  stroke: true
@@ -31252,7 +31306,10 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
31252
31306
  const startAngle = Math.atan2((startY - cyA) / (ry || 1), (startX - cxA) / (rx || 1));
31253
31307
  const endAngle = Math.atan2((endY - cyA) / (ry || 1), (endX - cxA) / (rx || 1));
31254
31308
  const rotated = hasWorldRotation(rCtx);
31255
- const params = rotated ? gdiEllipseParams(rCtx, cxA, cyA, rx, ry) : {
31309
+ const unframed = fixBox(rCtx, l, t, r, b);
31310
+ const inset = insideFrameInset(rCtx, unframed);
31311
+ const framed = inset ? insetFixBox(unframed, inset) : unframed;
31312
+ const params = inset ? { cx: (framed.ax + framed.exx / 2) / 16, cy: (framed.ay + framed.eyy / 2) / 16, rx: Math.abs(framed.exx) / 32, ry: Math.abs(framed.eyy) / 32, rotation: 0 } : rotated ? gdiEllipseParams(rCtx, cxA, cyA, rx, ry) : {
31256
31313
  cx: gmx(rCtx, cxA),
31257
31314
  cy: gmy(rCtx, cyA),
31258
31315
  rx: Math.abs(gmw(rCtx, rx)),
@@ -31276,10 +31333,18 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
31276
31333
  }
31277
31334
  };
31278
31335
  const kind = isArcTo ? "arcto" : recType === EMR_PIE ? "pie" : recType === EMR_CHORD ? "chord" : "arc";
31336
+ const radialOnBox = (p) => {
31337
+ if (!inset) {
31338
+ return p;
31339
+ }
31340
+ const kx = unframed.exx !== 0 ? framed.exx / unframed.exx : 1;
31341
+ const ky = unframed.eyy !== 0 ? framed.eyy / unframed.eyy : 1;
31342
+ return [framed.ax + framed.exx / 2 + (p[0] - (unframed.ax + unframed.exx / 2)) * kx, framed.ay + framed.eyy / 2 + (p[1] - (unframed.ay + unframed.eyy / 2)) * ky];
31343
+ };
31279
31344
  const rasterArgs = (immediate = false) => ({
31280
- box: immediate && needsFill ? curvedFixBox(rCtx, l, t, r, b) : fixBox(rCtx, l, t, r, b),
31281
- s: fixPoint(rCtx, startX, startY),
31282
- e: fixPoint(rCtx, endX, endY),
31345
+ box: inset ? framed : immediate && needsFill ? curvedFixBox(rCtx, l, t, r, b) : unframed,
31346
+ s: radialOnBox(fixPoint(rCtx, startX, startY)),
31347
+ e: radialOnBox(fixPoint(rCtx, endX, endY)),
31283
31348
  from: currentFix(rCtx)
31284
31349
  });
31285
31350
  if (inPath) {
@@ -39314,7 +39379,7 @@ function wmfExtFloodFill(p, x, y, colorRef, type) {
39314
39379
 
39315
39380
  // src/wmf-shapes.ts
39316
39381
  var PS_NULL3 = 5;
39317
- var PS_INSIDEFRAME = 6;
39382
+ var PS_INSIDEFRAME2 = 6;
39318
39383
  function compatBox(p, l, t, r, b, opts = {}) {
39319
39384
  const exclusive = opts.exclusive !== false;
39320
39385
  const a = fixPoint(p.rCtx, l, t);
@@ -39336,23 +39401,32 @@ function compatBox(p, l, t, r, b, opts = {}) {
39336
39401
  box.x1 -= Math.round(ux * 3 / 4);
39337
39402
  box.y1 -= Math.round(uy * 3 / 4);
39338
39403
  }
39339
- if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME) {
39404
+ if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME2) {
39340
39405
  const w = Math.round(penDeviceWidth(p.rCtx) / p.kx);
39341
39406
  if (w > 1) {
39342
39407
  const matrix = gdiDeviceMatrix(p.rCtx);
39343
- const rawWidth = p.rCtx.state.penWidth * Math.sqrt(Math.abs(matrix[0] * matrix[3] - matrix[1] * matrix[2])) / p.kx;
39408
+ const wx = Math.round(Math.abs(p.rCtx.state.penWidth * matrix[0]) / p.kx * 16);
39409
+ const wy = Math.round(Math.abs(p.rCtx.state.penWidth * matrix[3]) / p.ky * 16);
39344
39410
  box.x1 += Math.round(ux);
39345
39411
  box.y1 += Math.round(uy);
39346
- box.x0 += Math.round(rawWidth * ux / 2);
39347
- box.y0 += Math.round(rawWidth * uy / 2);
39348
- box.x1 -= Math.round(rawWidth * ux / 2);
39349
- box.y1 -= Math.round(rawWidth * uy / 2);
39412
+ box.x0 += Math.round((opts.curved || opts.roundFrame ? Math.floor(wx / 2) : Math.ceil(wx / 2)) * ux / 16);
39413
+ box.y0 += Math.round(Math.ceil(wy / 2) * uy / 16);
39414
+ const half = !!opts.half && wx % 2 === 1;
39415
+ box.x1 -= Math.round((half ? Math.ceil(wx / 2) : Math.floor(wx / 2)) * ux / 16);
39416
+ box.y1 -= Math.round(Math.ceil(wy / 2) * uy / 16);
39417
+ if (half) {
39418
+ box.halfX = true;
39419
+ }
39350
39420
  }
39351
39421
  }
39352
39422
  return box;
39353
39423
  }
39354
39424
  function fixBoxOf(box) {
39355
- return axisBox(box.x0, box.y0, Math.max(box.x0, box.x1), Math.max(box.y0, box.y1));
39425
+ const fix = axisBox(box.x0, box.y0, Math.max(box.x0, box.x1), Math.max(box.y0, box.y1));
39426
+ if (box.halfX) {
39427
+ fix.halfX = true;
39428
+ }
39429
+ return fix;
39356
39430
  }
39357
39431
  function canvasRect(box) {
39358
39432
  return { x: box.x0 / 16, y: box.y0 / 16, w: Math.max(0, box.x1 - box.x0) / 16, h: Math.max(0, box.y1 - box.y0) / 16 };
@@ -39406,14 +39480,15 @@ function wmfRectangle(p, l, t, r, b) {
39406
39480
  }
39407
39481
  function compatCorner(p, w, h, box, logical) {
39408
39482
  const m = gdiDeviceMatrix(p.rCtx);
39409
- const cw = Math.round(Math.abs(w * m[0]) * 16);
39410
- const ch = Math.round(Math.abs(h * m[3]) * 16);
39483
+ Math.round(Math.abs(w * m[0]) * 16);
39484
+ Math.round(Math.abs(h * m[3]) * 16);
39411
39485
  const ux = 16 * p.kx;
39412
39486
  const uy = 16 * p.ky;
39413
- if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME && !penIsCosmetic(p.rCtx)) {
39414
- const penWidth = p.rCtx.state.penWidth * Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2])) * 16;
39487
+ if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME2 && !penIsCosmetic(p.rCtx)) {
39415
39488
  const width2 = box.x1 - box.x0, height2 = box.y1 - box.y0;
39416
- return [Math.floor(Math.min(cw, width2 + penWidth) * width2 / (width2 + penWidth)), Math.floor(Math.min(ch, height2 + penWidth) * height2 / (height2 + penWidth))];
39489
+ const fullW2 = Math.abs((logical[2] - logical[0]) * m[0]) * 16 || width2;
39490
+ const fullH2 = Math.abs((logical[3] - logical[1]) * m[3]) * 16 || height2;
39491
+ return [Math.floor(Math.min(Math.abs(w * m[0]) * 16, fullW2) * width2 / fullW2), Math.floor(Math.min(Math.abs(h * m[3]) * 16, fullH2) * height2 / fullH2)];
39417
39492
  }
39418
39493
  const width = box.x1 - box.x0, height = box.y1 - box.y0;
39419
39494
  const fullW = Math.abs((logical[2] - logical[0]) * m[0]) * 16 || width + ux;
@@ -39422,7 +39497,7 @@ function compatCorner(p, w, h, box, logical) {
39422
39497
  return penIsCosmetic(p.rCtx) && !penIsNull(p) ? scaled2 : [Math.floor(scaled2[0]), Math.floor(scaled2[1])];
39423
39498
  }
39424
39499
  function wmfRoundRect(p, l, t, r, b, w, h) {
39425
- const box = compatBox(p, l, t, r, b, { curved: true });
39500
+ const box = compatBox(p, l, t, r, b, { curved: true, half: true });
39426
39501
  if (box.x1 < box.x0 || box.y1 < box.y0) {
39427
39502
  return;
39428
39503
  }
@@ -39458,7 +39533,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
39458
39533
  });
39459
39534
  }
39460
39535
  function wmfEllipse(p, l, t, r, b) {
39461
- const box = compatBox(p, l, t, r, b, { curved: true });
39536
+ const box = compatBox(p, l, t, r, b, { curved: true, half: true });
39462
39537
  if (box.x1 < box.x0 || box.y1 < box.y0) {
39463
39538
  return;
39464
39539
  }
@@ -39475,7 +39550,7 @@ function wmfEllipse(p, l, t, r, b) {
39475
39550
  });
39476
39551
  }
39477
39552
  function compatArc(p, kind, l, t, r, b, xs, ys, xe, ye) {
39478
- const box = compatBox(p, l, t, r, b, { curved: kind === "chord" || kind === "pie" });
39553
+ const box = compatBox(p, l, t, r, b, { curved: kind === "chord" || kind === "pie", roundFrame: true });
39479
39554
  if (box.x1 < box.x0 || box.y1 < box.y0) {
39480
39555
  return null;
39481
39556
  }