emf-converter 4.8.4 → 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;
@@ -29848,6 +29816,11 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = fal
29848
29816
  for (let i = 0; i < q.length; i += 2) {
29849
29817
  pts.push(...map(q[i], clockwise ? f.t + f.b - q[i + 1] : q[i + 1]));
29850
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
+ }
29851
29824
  return pts;
29852
29825
  }
29853
29826
  function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false, compatible = false) {
@@ -30929,6 +30902,51 @@ function fixExtent(rCtx, v, axis) {
30929
30902
  const k = axis === 0 ? Math.hypot(m[0], m[1]) : Math.hypot(m[2], m[3]);
30930
30903
  return Math.round(Math.abs(v) * k * 16);
30931
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
+ }
30932
30950
  function handleSetPixelV(rCtx, dataOff, recSize) {
30933
30951
  const { ctx, view } = rCtx;
30934
30952
  if (recSize >= 20) {
@@ -31001,7 +31019,9 @@ function handleRectangle(rCtx, dataOff, recSize) {
31001
31019
  const t = view.getInt32(dataOff + 4, true);
31002
31020
  const r = view.getInt32(dataOff + 8, true);
31003
31021
  const b = view.getInt32(dataOff + 12, true);
31004
- 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;
31005
31025
  const clockwise = rCtx.state.arcDirection === 2;
31006
31026
  if (!inPath) {
31007
31027
  resetLineStyle(rCtx);
@@ -31036,10 +31056,16 @@ function handleRectangle(rCtx, dataOff, recSize) {
31036
31056
  }
31037
31057
  return true;
31038
31058
  }
31039
- const x = gmx(rCtx, l);
31040
- const y = gmy(rCtx, t);
31041
- const w = gmw(rCtx, r - l);
31042
- 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
+ }
31043
31069
  if (inPath) {
31044
31070
  recordRectangle(rCtx, box, clockwise);
31045
31071
  } else if (needsPathBasedRectangle(rCtx)) {
@@ -31151,7 +31177,26 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31151
31177
  const b = view.getInt32(dataOff + 12, true);
31152
31178
  const cornerW = view.getInt32(dataOff + 16, true);
31153
31179
  const cornerH = view.getInt32(dataOff + 20, true);
31154
- 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(
31155
31200
  c,
31156
31201
  gmx(rCtx, l),
31157
31202
  gmy(rCtx, t),
@@ -31161,13 +31206,12 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31161
31206
  gmh(rCtx, cornerH) / 2,
31162
31207
  null
31163
31208
  );
31164
- const clockwise = rCtx.state.arcDirection === 2;
31165
- 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);
31166
31210
  if (inPath) {
31167
- const box = uprightFixBox(rCtx, l, t, r, b);
31211
+ const box = framed;
31168
31212
  if (cornerW === 0 || cornerH === 0) recordRectangle(rCtx, box, clockwise);
31169
31213
  else {
31170
- recordBezierShape(rCtx, roundRectDeviceBeziers(box, fixExtent(rCtx, cornerW, 0), fixExtent(rCtx, cornerH, 1), clockwise), 8);
31214
+ recordBezierShape(rCtx, roundRectDeviceBeziers(box, cw, ch, clockwise), 8);
31171
31215
  rasterPathOf(rCtx).append(raster(box));
31172
31216
  }
31173
31217
  } else {
@@ -31177,7 +31221,7 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31177
31221
  c.beginPath();
31178
31222
  drawRoundRect(c);
31179
31223
  },
31180
- raster: () => raster(curvedFixBox(rCtx, l, t, r, b, true)),
31224
+ raster: () => raster(inset ? framed : curvedFixBox(rCtx, l, t, r, b, true)),
31181
31225
  roundPen: true,
31182
31226
  fill: true,
31183
31227
  stroke: true
@@ -31214,7 +31258,10 @@ function handleEllipse(rCtx, dataOff, recSize) {
31214
31258
  const r = view.getInt32(dataOff + 8, true);
31215
31259
  const b = view.getInt32(dataOff + 12, true);
31216
31260
  const clockwise = rCtx.state.arcDirection === 2;
31217
- 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) : {
31218
31265
  cx: gmx(rCtx, (l + r) / 2),
31219
31266
  cy: gmy(rCtx, (t + b) / 2),
31220
31267
  rx: Math.abs(gmw(rCtx, r - l)) / 2,
@@ -31222,7 +31269,7 @@ function handleEllipse(rCtx, dataOff, recSize) {
31222
31269
  rotation: 0
31223
31270
  };
31224
31271
  if (inPath) {
31225
- const box = uprightFixBox(rCtx, l, t, r, b);
31272
+ const box = framed;
31226
31273
  recordBezierShape(rCtx, ellipseBeziersBox(box, clockwise), 6);
31227
31274
  rasterPathOf(rCtx).append(ellipseRasterPath(box, clockwise));
31228
31275
  } else {
@@ -31232,7 +31279,7 @@ function handleEllipse(rCtx, dataOff, recSize) {
31232
31279
  c.beginPath();
31233
31280
  c.ellipse(params.cx, params.cy, params.rx, params.ry, params.rotation, 0, Math.PI * 2);
31234
31281
  },
31235
- raster: () => ellipseRasterPath(curvedFixBox(rCtx, l, t, r, b, true), clockwise),
31282
+ raster: () => ellipseRasterPath(inset ? framed : curvedFixBox(rCtx, l, t, r, b, true), clockwise),
31236
31283
  roundPen: true,
31237
31284
  fill: true,
31238
31285
  stroke: true
@@ -31259,7 +31306,10 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
31259
31306
  const startAngle = Math.atan2((startY - cyA) / (ry || 1), (startX - cxA) / (rx || 1));
31260
31307
  const endAngle = Math.atan2((endY - cyA) / (ry || 1), (endX - cxA) / (rx || 1));
31261
31308
  const rotated = hasWorldRotation(rCtx);
31262
- 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) : {
31263
31313
  cx: gmx(rCtx, cxA),
31264
31314
  cy: gmy(rCtx, cyA),
31265
31315
  rx: Math.abs(gmw(rCtx, rx)),
@@ -31283,10 +31333,18 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
31283
31333
  }
31284
31334
  };
31285
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
+ };
31286
31344
  const rasterArgs = (immediate = false) => ({
31287
- box: immediate && needsFill ? curvedFixBox(rCtx, l, t, r, b) : fixBox(rCtx, l, t, r, b),
31288
- s: fixPoint(rCtx, startX, startY),
31289
- 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)),
31290
31348
  from: currentFix(rCtx)
31291
31349
  });
31292
31350
  if (inPath) {
@@ -39321,7 +39379,7 @@ function wmfExtFloodFill(p, x, y, colorRef, type) {
39321
39379
 
39322
39380
  // src/wmf-shapes.ts
39323
39381
  var PS_NULL3 = 5;
39324
- var PS_INSIDEFRAME = 6;
39382
+ var PS_INSIDEFRAME2 = 6;
39325
39383
  function compatBox(p, l, t, r, b, opts = {}) {
39326
39384
  const exclusive = opts.exclusive !== false;
39327
39385
  const a = fixPoint(p.rCtx, l, t);
@@ -39343,23 +39401,32 @@ function compatBox(p, l, t, r, b, opts = {}) {
39343
39401
  box.x1 -= Math.round(ux * 3 / 4);
39344
39402
  box.y1 -= Math.round(uy * 3 / 4);
39345
39403
  }
39346
- if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME) {
39404
+ if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME2) {
39347
39405
  const w = Math.round(penDeviceWidth(p.rCtx) / p.kx);
39348
39406
  if (w > 1) {
39349
39407
  const matrix = gdiDeviceMatrix(p.rCtx);
39350
- 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);
39351
39410
  box.x1 += Math.round(ux);
39352
39411
  box.y1 += Math.round(uy);
39353
- box.x0 += Math.round(rawWidth * ux / 2);
39354
- box.y0 += Math.round(rawWidth * uy / 2);
39355
- box.x1 -= Math.round(rawWidth * ux / 2);
39356
- 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
+ }
39357
39420
  }
39358
39421
  }
39359
39422
  return box;
39360
39423
  }
39361
39424
  function fixBoxOf(box) {
39362
- 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;
39363
39430
  }
39364
39431
  function canvasRect(box) {
39365
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 };
@@ -39413,14 +39480,15 @@ function wmfRectangle(p, l, t, r, b) {
39413
39480
  }
39414
39481
  function compatCorner(p, w, h, box, logical) {
39415
39482
  const m = gdiDeviceMatrix(p.rCtx);
39416
- const cw = Math.round(Math.abs(w * m[0]) * 16);
39417
- 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);
39418
39485
  const ux = 16 * p.kx;
39419
39486
  const uy = 16 * p.ky;
39420
- if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME && !penIsCosmetic(p.rCtx)) {
39421
- 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)) {
39422
39488
  const width2 = box.x1 - box.x0, height2 = box.y1 - box.y0;
39423
- 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)];
39424
39492
  }
39425
39493
  const width = box.x1 - box.x0, height = box.y1 - box.y0;
39426
39494
  const fullW = Math.abs((logical[2] - logical[0]) * m[0]) * 16 || width + ux;
@@ -39429,7 +39497,7 @@ function compatCorner(p, w, h, box, logical) {
39429
39497
  return penIsCosmetic(p.rCtx) && !penIsNull(p) ? scaled2 : [Math.floor(scaled2[0]), Math.floor(scaled2[1])];
39430
39498
  }
39431
39499
  function wmfRoundRect(p, l, t, r, b, w, h) {
39432
- const box = compatBox(p, l, t, r, b, { curved: true });
39500
+ const box = compatBox(p, l, t, r, b, { curved: true, half: true });
39433
39501
  if (box.x1 < box.x0 || box.y1 < box.y0) {
39434
39502
  return;
39435
39503
  }
@@ -39465,7 +39533,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
39465
39533
  });
39466
39534
  }
39467
39535
  function wmfEllipse(p, l, t, r, b) {
39468
- const box = compatBox(p, l, t, r, b, { curved: true });
39536
+ const box = compatBox(p, l, t, r, b, { curved: true, half: true });
39469
39537
  if (box.x1 < box.x0 || box.y1 < box.y0) {
39470
39538
  return;
39471
39539
  }
@@ -39482,7 +39550,7 @@ function wmfEllipse(p, l, t, r, b) {
39482
39550
  });
39483
39551
  }
39484
39552
  function compatArc(p, kind, l, t, r, b, xs, ys, xe, ye) {
39485
- 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 });
39486
39554
  if (box.x1 < box.x0 || box.y1 < box.y0) {
39487
39555
  return null;
39488
39556
  }