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.js CHANGED
@@ -11706,6 +11706,11 @@ function ellipsePoints(box, cwControls) {
11706
11706
  P(hCtl, full);
11707
11707
  P(full, rightLower);
11708
11708
  P(full, vMidHi);
11709
+ if (box.halfX) {
11710
+ for (const k of [0, 1, 2, 3, 4, 5, 12]) {
11711
+ out[2 * k]++;
11712
+ }
11713
+ }
11709
11714
  return out;
11710
11715
  }
11711
11716
  function ellipseBeziers(l, t, r, b) {
@@ -11775,76 +11780,15 @@ function roundRectCorners(l, t, r, b, cw, ch, compatible = false, clockwise = fa
11775
11780
  ];
11776
11781
  }
11777
11782
  var TRIG_STEP = 2 * Math.PI / 128;
11778
- var TRIG_NODES = [
11779
- 1,
11780
- 0.99879566,
11781
- 0.99518639,
11782
- 0.98917961,
11783
- 0.98079146,
11784
- 0.97003981,
11785
- 0.95695228,
11786
- 0.94155978,
11787
- 0.92389844,
11788
- 0.90401145,
11789
- 0.88194619,
11790
- 0.85775575,
11791
- 0.83149879,
11792
- 0.80323775,
11793
- 0.77303903,
11794
- 0.74098864,
11795
- 0.70710648,
11796
- 0.67151859,
11797
- 0.63435836,
11798
- 0.59565849,
11799
- 0.55552672,
11800
- 0.51405765,
11801
- 0.47135039,
11802
- 0.42750875,
11803
- 0.38263811,
11804
- 0.33684632,
11805
- 0.29024443,
11806
- 0.24294646,
11807
- 0.19505974,
11808
- 0.14670808,
11809
- 0.0980012,
11810
- 0.04906089,
11811
- 0
11812
- ];
11813
- var TRIG_TABLE = (() => {
11814
- const cos = [];
11815
- const sin = [];
11816
- for (let k = 0; k <= 128; k++) {
11817
- const q = k >> 5;
11818
- const i = k & 31;
11819
- const c = TRIG_NODES[i];
11820
- const s = TRIG_NODES[32 - i];
11821
- if (k === 128) {
11822
- cos.push(1);
11823
- sin.push(0);
11824
- continue;
11825
- }
11826
- cos.push([c, -s, -c, s][q]);
11827
- sin.push([s, c, -s, -c][q]);
11828
- }
11829
- return { cos, sin };
11830
- })();
11831
- function tableTrig(table) {
11832
- return (a) => {
11833
- let b = a % (2 * Math.PI);
11834
- if (b < 0) {
11835
- b += 2 * Math.PI;
11836
- }
11837
- const x = b / TRIG_STEP;
11838
- const i = Math.min(127, Math.floor(x));
11839
- const f = x - i;
11840
- return table[i] * (1 - f) + table[i + 1] * f;
11841
- };
11842
- }
11843
- var tableCos = tableTrig(TRIG_TABLE.cos);
11844
- var tableSin = tableTrig(TRIG_TABLE.sin);
11783
+ var tableCos = (angle) => polygonTrig(angle)[0];
11784
+ var tableSin = (angle) => polygonTrig(angle)[1];
11845
11785
  function angleArcPieces(startDeg, sweepDeg) {
11846
11786
  const out = [];
11847
11787
  const arc = (from, to) => {
11788
+ if (Math.abs(to - from) < 90) {
11789
+ out.push({ from, to, first: true });
11790
+ return;
11791
+ }
11848
11792
  const lo = Math.min(from, to);
11849
11793
  const hi = Math.max(from, to);
11850
11794
  const pieces = Math.floor(hi / 90) - Math.floor(lo / 90) + 1;
@@ -11893,7 +11837,8 @@ function angleArcFix(box, startDeg, sweepDeg) {
11893
11837
  const E = ellipseBeziers(l, t, l + w, t + h);
11894
11838
  const Ecw = clockwiseEllipseBeziersBox(axisBox(l, t, l + w, t + h));
11895
11839
  const start = startDeg * Math.PI / 180;
11896
- const out = [Math.round(cx + w / 2 * tableCos(start)), Math.round(cy - h / 2 * tableSin(start))];
11840
+ const startUnit = Math.abs(sweepDeg) <= 3 ? [Math.cos(start), Math.sin(start)] : polygonTrig(start);
11841
+ const out = [Math.round(cx + w / 2 * startUnit[0]), Math.round(cy - h / 2 * startUnit[1])];
11897
11842
  for (const p of angleArcPieces(startDeg, sweepDeg)) {
11898
11843
  const span = p.to - p.from;
11899
11844
  if (!p.first && Math.abs(span) === 90 && p.from % 90 === 0) {
@@ -11906,43 +11851,80 @@ function angleArcFix(box, startDeg, sweepDeg) {
11906
11851
  }
11907
11852
  continue;
11908
11853
  }
11909
- for (const v of circularArcBezier(cx, cy, w / 2, h / 2, p.from, p.to)) {
11910
- out.push(Math.round(v));
11854
+ const piece = unitPiece(p.from * Math.PI / 180, p.to * Math.PI / 180, Math.abs(sweepDeg) <= 3);
11855
+ for (let i = 0; i < 6; i += 2) {
11856
+ out.push(Math.round(cx + w / 2 * piece.ctrl[i]), Math.round(cy - h / 2 * piece.ctrl[i + 1]));
11911
11857
  }
11912
11858
  }
11913
11859
  return out;
11914
11860
  }
11915
11861
  var SMALL_SWEEP = 3 * Math.PI / 180;
11916
- function anchoredPiece(boundary, free, rx, ry, cx, cy, smallArc) {
11917
- const sweep = Math.abs(free - boundary);
11918
- const small = smallArc;
11919
- const cos = small ? Math.cos : tableCos;
11920
- const sin = small ? Math.sin : tableSin;
11921
- const anchor = [Math.round(cx + rx * Math.cos(boundary)), Math.round(cy - ry * Math.sin(boundary))];
11922
- const point = [cx + rx * cos(free), cy - ry * sin(free)];
11923
- let t;
11924
- let kappa;
11925
- if (small) {
11926
- t = Math.tan(sweep / 2);
11927
- kappa = 2 / 3 * (1 - Math.tan(sweep / 4) ** 2);
11862
+ var POLYGON_NODES = (() => {
11863
+ const cos = [];
11864
+ const sin = [];
11865
+ for (let k = 0; k <= 129; k++) {
11866
+ cos.push(Math.cos(k * TRIG_STEP));
11867
+ sin.push(Math.sin(k * TRIG_STEP));
11868
+ }
11869
+ for (let k = 0; k <= 128; k += 32) {
11870
+ cos[k] = [1, 0, -1, 0, 1][k / 32];
11871
+ sin[k] = [0, 1, 0, -1, 0][k / 32];
11872
+ }
11873
+ return { cos, sin };
11874
+ })();
11875
+ function polygonTrig(angle) {
11876
+ let b = angle % (2 * Math.PI);
11877
+ if (b < 0) {
11878
+ b += 2 * Math.PI;
11879
+ }
11880
+ const x = b / TRIG_STEP;
11881
+ const i = Math.min(127, Math.floor(x));
11882
+ const f = x - i;
11883
+ return [
11884
+ POLYGON_NODES.cos[i] * (1 - f) + POLYGON_NODES.cos[i + 1] * f,
11885
+ POLYGON_NODES.sin[i] * (1 - f) + POLYGON_NODES.sin[i + 1] * f
11886
+ ];
11887
+ }
11888
+ var ATAN_KNOTS = Array.from({ length: 33 }, (_, j) => Math.atan(j / 32));
11889
+ function interpolatedAtan(t) {
11890
+ const x = t * 32;
11891
+ const j = Math.min(31, Math.floor(x));
11892
+ return ATAN_KNOTS[j] + (ATAN_KNOTS[j + 1] - ATAN_KNOTS[j]) * (x - j);
11893
+ }
11894
+ function approximateArcAngle(x, y) {
11895
+ const ax = Math.abs(x);
11896
+ const ay = Math.abs(y);
11897
+ if (ax === 0 && ay === 0) {
11898
+ return 0;
11899
+ }
11900
+ const a = ay <= ax ? interpolatedAtan(ay / ax) : Math.PI / 2 - interpolatedAtan(ax / ay);
11901
+ if (x >= 0) {
11902
+ return y >= 0 ? a : 2 * Math.PI - a;
11903
+ }
11904
+ return y >= 0 ? Math.PI - a : Math.PI + a;
11905
+ }
11906
+ function unitPiece(from, to, small) {
11907
+ const trig = small ? (a) => [Math.cos(a), Math.sin(a)] : polygonTrig;
11908
+ const p0 = trig(from);
11909
+ const p3 = trig(to);
11910
+ const det = p0[0] * p3[1] - p0[1] * p3[0];
11911
+ let ctrl;
11912
+ if (Math.abs(det) < 1e-12) {
11913
+ ctrl = [p0[0], p0[1], p3[0], p3[1], p3[0], p3[1]];
11928
11914
  } else {
11929
- const c = tableCos(sweep);
11930
- const sn = tableSin(sweep);
11931
- t = (1 - c) / sn;
11932
- const q = t / (1 + Math.sqrt(1 + t * t));
11933
- kappa = 2 / 3 * (1 - q * q);
11934
- }
11935
- const dir = free > boundary ? 1 : -1;
11936
- const tx = -Math.round(Math.sin(boundary));
11937
- const ty = -Math.round(Math.cos(boundary));
11938
- const length = tx !== 0 ? rx : ry;
11939
- const X = [anchor[0] + dir * tx * length * t, anchor[1] + dir * ty * length * t];
11940
- return {
11941
- anchor,
11942
- free: point,
11943
- cAnchor: [anchor[0] + kappa * (X[0] - anchor[0]), anchor[1] + kappa * (X[1] - anchor[1])],
11944
- cFree: [point[0] + kappa * (X[0] - point[0]), point[1] + kappa * (X[1] - point[1])]
11945
- };
11915
+ const X = [(p3[1] - p0[1]) / det, (p0[0] - p3[0]) / det];
11916
+ const c = polygonTrig(Math.abs(to - from) / 2)[0];
11917
+ const kappa = 4 / 3 * c / (1 + c);
11918
+ ctrl = [
11919
+ p0[0] + kappa * (X[0] - p0[0]),
11920
+ p0[1] + kappa * (X[1] - p0[1]),
11921
+ p3[0] + kappa * (X[0] - p3[0]),
11922
+ p3[1] + kappa * (X[1] - p3[1]),
11923
+ p3[0],
11924
+ p3[1]
11925
+ ];
11926
+ }
11927
+ return { start: p0, ctrl };
11946
11928
  }
11947
11929
  function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
11948
11930
  const w = r - l;
@@ -11954,24 +11936,30 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
11954
11936
  const cy = t + Math.ceil(h / 2);
11955
11937
  const tcx = (l + r) / 2;
11956
11938
  const tcy = (t + b) / 2;
11957
- const angle = (x, y) => Math.atan2(-(y - tcy) / (h / 2 || 1), (x - tcx) / (w / 2 || 1));
11939
+ const angle = (x, y) => approximateArcAngle((x - tcx) / (w / 2 || 1), -(y - tcy) / (h / 2 || 1));
11958
11940
  const a0 = angle(xs, ys);
11959
11941
  let a1 = angle(xe, ye);
11942
+ const small = a1 !== a0 && Math.abs(a1 - a0) <= SMALL_SWEEP;
11960
11943
  const s = clockwise ? -1 : 1;
11961
11944
  if (s > 0) {
11962
11945
  while (a1 <= a0) a1 += 2 * Math.PI;
11963
11946
  } else {
11964
11947
  while (a1 >= a0) a1 -= 2 * Math.PI;
11965
11948
  }
11966
- const px = (a2) => cx + rx * tableCos(a2);
11967
- const py = (a2) => cy - ry * tableSin(a2);
11949
+ const px = (u) => Math.round(cx + rx * u);
11950
+ const py = (v) => Math.round(cy - ry * v);
11968
11951
  const E = clockwise ? clockwiseEllipseBeziersBox(axisBox(l, t, r, b)) : ellipseBeziers(l, t, r, b);
11969
- const out = [Math.round(px(a0)), Math.round(py(a0))];
11952
+ const startUnit = small ? [Math.cos(a0), Math.sin(a0)] : polygonTrig(a0);
11953
+ const out = [px(startUnit[0]), py(startUnit[1])];
11970
11954
  let a = a0;
11971
11955
  for (let guard = 0; guard < 8 && (s > 0 ? a < a1 - 1e-12 : a > a1 + 1e-12); guard++) {
11972
11956
  const next = s > 0 ? Math.floor(a / Q + 1e-9) * Q + Q : Math.ceil(a / Q - 1e-9) * Q - Q;
11973
11957
  const onBoundary = Math.abs(a / Q - Math.round(a / Q)) < 1e-9;
11974
- if (onBoundary && (s > 0 ? next <= a1 + 1e-12 : next >= a1 - 1e-12)) {
11958
+ const reachesEnd = s > 0 ? next >= a1 - 1e-12 : next <= a1 + 1e-12;
11959
+ const quadrantFrom = (Math.round(a / Q) % 4 + 4) % 4;
11960
+ const quadrantTo = (Math.round(next / Q) % 4 + 4) % 4;
11961
+ 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);
11962
+ if (!generic && onBoundary && (s > 0 ? next <= a1 + 1e-12 : next >= a1 - 1e-12)) {
11975
11963
  const qi = (Math.round(Math.min(a, next) / Q) % 4 + 4) % 4 * 6;
11976
11964
  if (s > 0) {
11977
11965
  out.push(E[qi + 2], E[qi + 3], E[qi + 4], E[qi + 5], E[qi + 6], E[qi + 7]);
@@ -11982,30 +11970,10 @@ function arcBeziers(l, t, r, b, xs, ys, xe, ye, clockwise) {
11982
11970
  continue;
11983
11971
  }
11984
11972
  const e = s > 0 ? Math.min(next, a1) : Math.max(next, a1);
11985
- const endOnBoundary = Math.abs(e / Q - Math.round(e / Q)) < 1e-9;
11986
- if (onBoundary !== endOnBoundary) {
11987
- const piece = anchoredPiece(onBoundary ? a : e, onBoundary ? e : a, rx, ry, cx, cy, Math.abs(a1 - a0) <= SMALL_SWEEP);
11988
- if (onBoundary) {
11989
- out.push(...[piece.cAnchor, piece.cFree, piece.free].flatMap((q) => [Math.round(q[0]), Math.round(q[1])]));
11990
- } else {
11991
- if (out.length === 2) {
11992
- out[0] = Math.round(piece.free[0]);
11993
- out[1] = Math.round(piece.free[1]);
11994
- }
11995
- out.push(...[piece.cFree, piece.cAnchor, piece.anchor].flatMap((q) => [Math.round(q[0]), Math.round(q[1])]));
11996
- }
11997
- a = e;
11998
- continue;
11973
+ const piece = unitPiece(a, e, small);
11974
+ for (let i = 0; i < 6; i += 2) {
11975
+ out.push(px(piece.ctrl[i]), py(piece.ctrl[i + 1]));
11999
11976
  }
12000
- const k = 4 / 3 * Math.tan((e - a) / 4);
12001
- out.push(
12002
- Math.round(px(a) - k * rx * tableSin(a)),
12003
- Math.round(py(a) - k * ry * tableCos(a)),
12004
- Math.round(px(e) + k * rx * tableSin(e)),
12005
- Math.round(py(e) + k * ry * tableCos(e)),
12006
- Math.round(px(e)),
12007
- Math.round(py(e))
12008
- );
12009
11977
  a = e;
12010
11978
  }
12011
11979
  return out;
@@ -29850,6 +29818,11 @@ function roundRectDeviceBeziers(box, cw, ch, clockwise = false, compatible = fal
29850
29818
  for (let i = 0; i < q.length; i += 2) {
29851
29819
  pts.push(...map(q[i], clockwise ? f.t + f.b - q[i + 1] : q[i + 1]));
29852
29820
  }
29821
+ if (box.halfX && !clockwise) {
29822
+ for (const k of [1, 2, 3, 4, 5, 6, 8, 15]) {
29823
+ pts[2 * k]++;
29824
+ }
29825
+ }
29853
29826
  return pts;
29854
29827
  }
29855
29828
  function roundRectRasterPath(box, cw, ch, clockwise = false, rectangle = false, compatible = false) {
@@ -30931,6 +30904,51 @@ function fixExtent(rCtx, v, axis) {
30931
30904
  const k = axis === 0 ? Math.hypot(m[0], m[1]) : Math.hypot(m[2], m[3]);
30932
30905
  return Math.round(Math.abs(v) * k * 16);
30933
30906
  }
30907
+ var PS_INSIDEFRAME = 6;
30908
+ function insideFrameInset(rCtx, box, rectangle = false) {
30909
+ if ((rCtx.state.penStyle & 15) !== PS_INSIDEFRAME || !isAxisBox(box) || hasWorldRotation(rCtx)) {
30910
+ return null;
30911
+ }
30912
+ const m = gdiDeviceMatrix(rCtx);
30913
+ const px = gdiDevicePixelX(rCtx);
30914
+ const py = gdiDevicePixelY(rCtx);
30915
+ const widthX = Math.abs(rCtx.state.penWidth * m[0]) / px * 16;
30916
+ const widthY = Math.abs(rCtx.state.penWidth * m[3]) / py * 16;
30917
+ if (Math.max(widthX, widthY) < 24) {
30918
+ return null;
30919
+ }
30920
+ const wx = Math.round(widthX);
30921
+ const wy = Math.round(widthY);
30922
+ if (Math.abs(box.exx) / px < wx || Math.abs(box.eyy) / py < wy) {
30923
+ return null;
30924
+ }
30925
+ const lo = Math.floor(wx / 2);
30926
+ const hi = Math.ceil(wx / 2);
30927
+ const y = Math.round(Math.ceil(wy / 2) * py);
30928
+ return {
30929
+ left: Math.round((rectangle ? hi : lo) * px),
30930
+ right: Math.round((rectangle ? lo : hi) * px),
30931
+ top: y,
30932
+ bottom: y,
30933
+ half: wx % 2 === 1 && !rectangle
30934
+ };
30935
+ }
30936
+ function insetFixBox(box, inset) {
30937
+ const sx = box.exx < 0 ? -1 : 1;
30938
+ const sy = box.eyy < 0 ? -1 : 1;
30939
+ const framed = {
30940
+ ax: box.ax + sx * inset.left,
30941
+ ay: box.ay + sy * inset.top,
30942
+ exx: box.exx - sx * (inset.left + inset.right),
30943
+ exy: 0,
30944
+ eyx: 0,
30945
+ eyy: box.eyy - sy * (inset.top + inset.bottom)
30946
+ };
30947
+ if (inset.half && sx > 0) {
30948
+ framed.halfX = true;
30949
+ }
30950
+ return framed;
30951
+ }
30934
30952
  function handleSetPixelV(rCtx, dataOff, recSize) {
30935
30953
  const { ctx, view } = rCtx;
30936
30954
  if (recSize >= 20) {
@@ -31003,7 +31021,9 @@ function handleRectangle(rCtx, dataOff, recSize) {
31003
31021
  const t = view.getInt32(dataOff + 4, true);
31004
31022
  const r = view.getInt32(dataOff + 8, true);
31005
31023
  const b = view.getInt32(dataOff + 12, true);
31006
- const box = uprightFixBox(rCtx, l, t, r, b);
31024
+ const unframed = uprightFixBox(rCtx, l, t, r, b);
31025
+ const inset = insideFrameInset(rCtx, unframed, true);
31026
+ const box = inset ? insetFixBox(unframed, inset) : unframed;
31007
31027
  const clockwise = rCtx.state.arcDirection === 2;
31008
31028
  if (!inPath) {
31009
31029
  resetLineStyle(rCtx);
@@ -31038,10 +31058,16 @@ function handleRectangle(rCtx, dataOff, recSize) {
31038
31058
  }
31039
31059
  return true;
31040
31060
  }
31041
- const x = gmx(rCtx, l);
31042
- const y = gmy(rCtx, t);
31043
- const w = gmw(rCtx, r - l);
31044
- const h = gmh(rCtx, b - t);
31061
+ let x = gmx(rCtx, l);
31062
+ let y = gmy(rCtx, t);
31063
+ let w = gmw(rCtx, r - l);
31064
+ let h = gmh(rCtx, b - t);
31065
+ if (inset) {
31066
+ x = Math.min(box.ax, box.ax + box.exx) / 16;
31067
+ y = Math.min(box.ay, box.ay + box.eyy) / 16;
31068
+ w = Math.abs(box.exx) / 16;
31069
+ h = Math.abs(box.eyy) / 16;
31070
+ }
31045
31071
  if (inPath) {
31046
31072
  recordRectangle(rCtx, box, clockwise);
31047
31073
  } else if (needsPathBasedRectangle(rCtx)) {
@@ -31153,7 +31179,26 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31153
31179
  const b = view.getInt32(dataOff + 12, true);
31154
31180
  const cornerW = view.getInt32(dataOff + 16, true);
31155
31181
  const cornerH = view.getInt32(dataOff + 20, true);
31156
- const drawRoundRect = hasWorldRotation(rCtx) ? (c) => appendRoundRectPath(c, l, t, r, b, cornerW / 2, cornerH / 2, (x, y) => gmapPoint(rCtx, x, y)) : (c) => appendRoundRectPath(
31182
+ const clockwise = rCtx.state.arcDirection === 2;
31183
+ const unframed = uprightFixBox(rCtx, l, t, r, b);
31184
+ const inset = insideFrameInset(rCtx, unframed);
31185
+ const framed = inset ? insetFixBox(unframed, inset) : unframed;
31186
+ const devM = gdiDeviceMatrix(rCtx);
31187
+ const cornerFixW = inset ? Math.abs(cornerW * devM[0]) * 16 : fixExtent(rCtx, cornerW, 0);
31188
+ const cornerFixH = inset ? Math.abs(cornerH * devM[3]) * 16 : fixExtent(rCtx, cornerH, 1);
31189
+ const cornerOnFrame = (fix, size, framedSize) => inset && size !== 0 ? Math.floor(Math.min(fix, size) * framedSize / size) : fix;
31190
+ const cw = cornerOnFrame(cornerFixW, Math.abs((r - l) * devM[0]) * 16, Math.abs(framed.exx));
31191
+ const ch = cornerOnFrame(cornerFixH, Math.abs((b - t) * devM[3]) * 16, Math.abs(framed.eyy));
31192
+ const drawRoundRect = inset ? (c) => appendRoundRectPath(
31193
+ c,
31194
+ Math.min(framed.ax, framed.ax + framed.exx) / 16,
31195
+ Math.min(framed.ay, framed.ay + framed.eyy) / 16,
31196
+ Math.max(framed.ax, framed.ax + framed.exx) / 16,
31197
+ Math.max(framed.ay, framed.ay + framed.eyy) / 16,
31198
+ cw / 32,
31199
+ ch / 32,
31200
+ null
31201
+ ) : hasWorldRotation(rCtx) ? (c) => appendRoundRectPath(c, l, t, r, b, cornerW / 2, cornerH / 2, (x, y) => gmapPoint(rCtx, x, y)) : (c) => appendRoundRectPath(
31157
31202
  c,
31158
31203
  gmx(rCtx, l),
31159
31204
  gmy(rCtx, t),
@@ -31163,13 +31208,12 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31163
31208
  gmh(rCtx, cornerH) / 2,
31164
31209
  null
31165
31210
  );
31166
- const clockwise = rCtx.state.arcDirection === 2;
31167
- const raster = (box = uprightFixBox(rCtx, l, t, r, b)) => roundRectRasterPath(box, fixExtent(rCtx, cornerW, 0), fixExtent(rCtx, cornerH, 1), clockwise, cornerW === 0 || cornerH === 0);
31211
+ const raster = (box = framed) => roundRectRasterPath(box, cw, ch, clockwise, cornerW === 0 || cornerH === 0);
31168
31212
  if (inPath) {
31169
- const box = uprightFixBox(rCtx, l, t, r, b);
31213
+ const box = framed;
31170
31214
  if (cornerW === 0 || cornerH === 0) recordRectangle(rCtx, box, clockwise);
31171
31215
  else {
31172
- recordBezierShape(rCtx, roundRectDeviceBeziers(box, fixExtent(rCtx, cornerW, 0), fixExtent(rCtx, cornerH, 1), clockwise), 8);
31216
+ recordBezierShape(rCtx, roundRectDeviceBeziers(box, cw, ch, clockwise), 8);
31173
31217
  rasterPathOf(rCtx).append(raster(box));
31174
31218
  }
31175
31219
  } else {
@@ -31179,7 +31223,7 @@ function handleRoundRect(rCtx, dataOff, recSize) {
31179
31223
  c.beginPath();
31180
31224
  drawRoundRect(c);
31181
31225
  },
31182
- raster: () => raster(curvedFixBox(rCtx, l, t, r, b, true)),
31226
+ raster: () => raster(inset ? framed : curvedFixBox(rCtx, l, t, r, b, true)),
31183
31227
  roundPen: true,
31184
31228
  fill: true,
31185
31229
  stroke: true
@@ -31216,7 +31260,10 @@ function handleEllipse(rCtx, dataOff, recSize) {
31216
31260
  const r = view.getInt32(dataOff + 8, true);
31217
31261
  const b = view.getInt32(dataOff + 12, true);
31218
31262
  const clockwise = rCtx.state.arcDirection === 2;
31219
- const params = hasWorldRotation(rCtx) ? gdiEllipseParams(rCtx, (l + r) / 2, (t + b) / 2, Math.abs(r - l) / 2, Math.abs(b - t) / 2) : {
31263
+ const unframed = uprightFixBox(rCtx, l, t, r, b);
31264
+ const inset = insideFrameInset(rCtx, unframed);
31265
+ const framed = inset ? insetFixBox(unframed, inset) : unframed;
31266
+ 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) : {
31220
31267
  cx: gmx(rCtx, (l + r) / 2),
31221
31268
  cy: gmy(rCtx, (t + b) / 2),
31222
31269
  rx: Math.abs(gmw(rCtx, r - l)) / 2,
@@ -31224,7 +31271,7 @@ function handleEllipse(rCtx, dataOff, recSize) {
31224
31271
  rotation: 0
31225
31272
  };
31226
31273
  if (inPath) {
31227
- const box = uprightFixBox(rCtx, l, t, r, b);
31274
+ const box = framed;
31228
31275
  recordBezierShape(rCtx, ellipseBeziersBox(box, clockwise), 6);
31229
31276
  rasterPathOf(rCtx).append(ellipseRasterPath(box, clockwise));
31230
31277
  } else {
@@ -31234,7 +31281,7 @@ function handleEllipse(rCtx, dataOff, recSize) {
31234
31281
  c.beginPath();
31235
31282
  c.ellipse(params.cx, params.cy, params.rx, params.ry, params.rotation, 0, Math.PI * 2);
31236
31283
  },
31237
- raster: () => ellipseRasterPath(curvedFixBox(rCtx, l, t, r, b, true), clockwise),
31284
+ raster: () => ellipseRasterPath(inset ? framed : curvedFixBox(rCtx, l, t, r, b, true), clockwise),
31238
31285
  roundPen: true,
31239
31286
  fill: true,
31240
31287
  stroke: true
@@ -31261,7 +31308,10 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
31261
31308
  const startAngle = Math.atan2((startY - cyA) / (ry || 1), (startX - cxA) / (rx || 1));
31262
31309
  const endAngle = Math.atan2((endY - cyA) / (ry || 1), (endX - cxA) / (rx || 1));
31263
31310
  const rotated = hasWorldRotation(rCtx);
31264
- const params = rotated ? gdiEllipseParams(rCtx, cxA, cyA, rx, ry) : {
31311
+ const unframed = fixBox(rCtx, l, t, r, b);
31312
+ const inset = insideFrameInset(rCtx, unframed);
31313
+ const framed = inset ? insetFixBox(unframed, inset) : unframed;
31314
+ 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) : {
31265
31315
  cx: gmx(rCtx, cxA),
31266
31316
  cy: gmy(rCtx, cyA),
31267
31317
  rx: Math.abs(gmw(rCtx, rx)),
@@ -31285,10 +31335,18 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
31285
31335
  }
31286
31336
  };
31287
31337
  const kind = isArcTo ? "arcto" : recType === EMR_PIE ? "pie" : recType === EMR_CHORD ? "chord" : "arc";
31338
+ const radialOnBox = (p) => {
31339
+ if (!inset) {
31340
+ return p;
31341
+ }
31342
+ const kx = unframed.exx !== 0 ? framed.exx / unframed.exx : 1;
31343
+ const ky = unframed.eyy !== 0 ? framed.eyy / unframed.eyy : 1;
31344
+ 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];
31345
+ };
31288
31346
  const rasterArgs = (immediate = false) => ({
31289
- box: immediate && needsFill ? curvedFixBox(rCtx, l, t, r, b) : fixBox(rCtx, l, t, r, b),
31290
- s: fixPoint(rCtx, startX, startY),
31291
- e: fixPoint(rCtx, endX, endY),
31347
+ box: inset ? framed : immediate && needsFill ? curvedFixBox(rCtx, l, t, r, b) : unframed,
31348
+ s: radialOnBox(fixPoint(rCtx, startX, startY)),
31349
+ e: radialOnBox(fixPoint(rCtx, endX, endY)),
31292
31350
  from: currentFix(rCtx)
31293
31351
  });
31294
31352
  if (inPath) {
@@ -39323,7 +39381,7 @@ function wmfExtFloodFill(p, x, y, colorRef, type) {
39323
39381
 
39324
39382
  // src/wmf-shapes.ts
39325
39383
  var PS_NULL3 = 5;
39326
- var PS_INSIDEFRAME = 6;
39384
+ var PS_INSIDEFRAME2 = 6;
39327
39385
  function compatBox(p, l, t, r, b, opts = {}) {
39328
39386
  const exclusive = opts.exclusive !== false;
39329
39387
  const a = fixPoint(p.rCtx, l, t);
@@ -39345,23 +39403,32 @@ function compatBox(p, l, t, r, b, opts = {}) {
39345
39403
  box.x1 -= Math.round(ux * 3 / 4);
39346
39404
  box.y1 -= Math.round(uy * 3 / 4);
39347
39405
  }
39348
- if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME) {
39406
+ if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME2) {
39349
39407
  const w = Math.round(penDeviceWidth(p.rCtx) / p.kx);
39350
39408
  if (w > 1) {
39351
39409
  const matrix = gdiDeviceMatrix(p.rCtx);
39352
- const rawWidth = p.rCtx.state.penWidth * Math.sqrt(Math.abs(matrix[0] * matrix[3] - matrix[1] * matrix[2])) / p.kx;
39410
+ const wx = Math.round(Math.abs(p.rCtx.state.penWidth * matrix[0]) / p.kx * 16);
39411
+ const wy = Math.round(Math.abs(p.rCtx.state.penWidth * matrix[3]) / p.ky * 16);
39353
39412
  box.x1 += Math.round(ux);
39354
39413
  box.y1 += Math.round(uy);
39355
- box.x0 += Math.round(rawWidth * ux / 2);
39356
- box.y0 += Math.round(rawWidth * uy / 2);
39357
- box.x1 -= Math.round(rawWidth * ux / 2);
39358
- box.y1 -= Math.round(rawWidth * uy / 2);
39414
+ box.x0 += Math.round((opts.curved || opts.roundFrame ? Math.floor(wx / 2) : Math.ceil(wx / 2)) * ux / 16);
39415
+ box.y0 += Math.round(Math.ceil(wy / 2) * uy / 16);
39416
+ const half = !!opts.half && wx % 2 === 1;
39417
+ box.x1 -= Math.round((half ? Math.ceil(wx / 2) : Math.floor(wx / 2)) * ux / 16);
39418
+ box.y1 -= Math.round(Math.ceil(wy / 2) * uy / 16);
39419
+ if (half) {
39420
+ box.halfX = true;
39421
+ }
39359
39422
  }
39360
39423
  }
39361
39424
  return box;
39362
39425
  }
39363
39426
  function fixBoxOf(box) {
39364
- return axisBox(box.x0, box.y0, Math.max(box.x0, box.x1), Math.max(box.y0, box.y1));
39427
+ const fix = axisBox(box.x0, box.y0, Math.max(box.x0, box.x1), Math.max(box.y0, box.y1));
39428
+ if (box.halfX) {
39429
+ fix.halfX = true;
39430
+ }
39431
+ return fix;
39365
39432
  }
39366
39433
  function canvasRect(box) {
39367
39434
  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 };
@@ -39415,14 +39482,15 @@ function wmfRectangle(p, l, t, r, b) {
39415
39482
  }
39416
39483
  function compatCorner(p, w, h, box, logical) {
39417
39484
  const m = gdiDeviceMatrix(p.rCtx);
39418
- const cw = Math.round(Math.abs(w * m[0]) * 16);
39419
- const ch = Math.round(Math.abs(h * m[3]) * 16);
39485
+ Math.round(Math.abs(w * m[0]) * 16);
39486
+ Math.round(Math.abs(h * m[3]) * 16);
39420
39487
  const ux = 16 * p.kx;
39421
39488
  const uy = 16 * p.ky;
39422
- if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME && !penIsCosmetic(p.rCtx)) {
39423
- const penWidth = p.rCtx.state.penWidth * Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2])) * 16;
39489
+ if ((p.rCtx.state.penStyle & 15) === PS_INSIDEFRAME2 && !penIsCosmetic(p.rCtx)) {
39424
39490
  const width2 = box.x1 - box.x0, height2 = box.y1 - box.y0;
39425
- return [Math.floor(Math.min(cw, width2 + penWidth) * width2 / (width2 + penWidth)), Math.floor(Math.min(ch, height2 + penWidth) * height2 / (height2 + penWidth))];
39491
+ const fullW2 = Math.abs((logical[2] - logical[0]) * m[0]) * 16 || width2;
39492
+ const fullH2 = Math.abs((logical[3] - logical[1]) * m[3]) * 16 || height2;
39493
+ 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)];
39426
39494
  }
39427
39495
  const width = box.x1 - box.x0, height = box.y1 - box.y0;
39428
39496
  const fullW = Math.abs((logical[2] - logical[0]) * m[0]) * 16 || width + ux;
@@ -39431,7 +39499,7 @@ function compatCorner(p, w, h, box, logical) {
39431
39499
  return penIsCosmetic(p.rCtx) && !penIsNull(p) ? scaled2 : [Math.floor(scaled2[0]), Math.floor(scaled2[1])];
39432
39500
  }
39433
39501
  function wmfRoundRect(p, l, t, r, b, w, h) {
39434
- const box = compatBox(p, l, t, r, b, { curved: true });
39502
+ const box = compatBox(p, l, t, r, b, { curved: true, half: true });
39435
39503
  if (box.x1 < box.x0 || box.y1 < box.y0) {
39436
39504
  return;
39437
39505
  }
@@ -39467,7 +39535,7 @@ function wmfRoundRect(p, l, t, r, b, w, h) {
39467
39535
  });
39468
39536
  }
39469
39537
  function wmfEllipse(p, l, t, r, b) {
39470
- const box = compatBox(p, l, t, r, b, { curved: true });
39538
+ const box = compatBox(p, l, t, r, b, { curved: true, half: true });
39471
39539
  if (box.x1 < box.x0 || box.y1 < box.y0) {
39472
39540
  return;
39473
39541
  }
@@ -39484,7 +39552,7 @@ function wmfEllipse(p, l, t, r, b) {
39484
39552
  });
39485
39553
  }
39486
39554
  function compatArc(p, kind, l, t, r, b, xs, ys, xe, ye) {
39487
- const box = compatBox(p, l, t, r, b, { curved: kind === "chord" || kind === "pie" });
39555
+ const box = compatBox(p, l, t, r, b, { curved: kind === "chord" || kind === "pie", roundFrame: true });
39488
39556
  if (box.x1 < box.x0 || box.y1 < box.y0) {
39489
39557
  return null;
39490
39558
  }