diff --git a/crates/engine/src/cmd.rs b/crates/engine/src/cmd.rs
--- a/crates/engine/src/cmd.rs
+++ b/crates/engine/src/cmd.rs
@@ -31,6 +31,7 @@ mod overkill;
 mod pline_opts;
 pub mod plotters;
 mod props;
+pub use draw2::RectangModes;
 pub use draw2::breakline::BreaklineOptions;
 pub use props::MatchProps;
 pub(crate) use props::{current_color_value, set_current_color_value};
diff --git a/crates/engine/src/cmd/draw2.rs b/crates/engine/src/cmd/draw2.rs
--- a/crates/engine/src/cmd/draw2.rs
+++ b/crates/engine/src/cmd/draw2.rs
@@ -7,7 +7,7 @@ use cadcraft_geom::{Arc, Circle, Ellipse, Line, PolyVertex, Polyline, Spline, TA
 use serde_json::{Value, json};
 
 use super::curves::{self, Chain, MAX_GEN, TanObj};
-use super::helpers::{arc, circle, line, lwpoly, rect_vertices, rect_with_corners, v3};
+use super::helpers::{arc, circle, line, lwpoly, rect_vertices, v3};
 
 use super::machines::number;
 use super::{CommandSpec, bad, bool_or, f64_or, f64_req, point_param, point_req, point_value, points_param, size_param, str_param, targets};
@@ -31,6 +31,7 @@ use centermark::{CenterM, run_centerline, run_centermark};
 use curves3d::{HelixM, Poly3dM, SplineCvM, run_3dpoly, run_helix, run_spline_cv};
 use divide::{DivideM, run_divide, run_measure};
 use ellipse::{run_ellipse_arc, run_ellipse_axis};
+pub use rect::RectangModes;
 pub(crate) use rect::{RectM2, run_rectang2};
 use revcloud::{CloudKind, RevcloudM, run_revcloud};
 pub(crate) use tancircle::TanCircleM;
diff --git a/crates/engine/src/cmd/draw2/rect.rs b/crates/engine/src/cmd/draw2/rect.rs
--- a/crates/engine/src/cmd/draw2/rect.rs
+++ b/crates/engine/src/cmd/draw2/rect.rs
@@ -4,8 +4,89 @@ use super::*;
 // RECTANG with Area / Dimensions / Rotation / Width / Elevation / Thickness
 // =====================================================================================
 
+/// RECTANG's corner options, remembered between invocations as AutoCAD remembers them
+/// ("Current rectangle modes:  Fillet=2.0000", "Elevation=7.5000  Thickness=2.2500  Rotation=30.96").
+#[derive(Clone, Copy, Debug, Default, PartialEq)]
+pub struct RectangModes {
+    pub chamfer: (f64, f64),
+    pub fillet: f64,
+    pub width: f64,
+    pub elevation: f64,
+    pub thickness: f64,
+    /// Radians.
+    pub rotation: f64,
+}
+
+/// The vertices of the rectangle from the origin to the opposite corner `(w, h)` (signed), as
+/// AutoCAD lists them: from the first corner along the first axis, so counterclockwise when `w`
+/// and `h` share a sign and clockwise otherwise. A fillet or chamfer replaces each corner by the
+/// point on the edge into it (where the fillet arc starts, or the first chamfer distance) and
+/// the point on the edge out of it (the second chamfer distance). Corners too large for the
+/// shorter side leave each corner as two coincident vertices.
+fn rect_corner_vertices((w, h): (f64, f64), fillet: f64, chamfer: (f64, f64)) -> Vec<PolyVertex> {
+    let corners = [Vec2::ZERO, Vec2::new(w, 0.0), Vec2::new(w, h), Vec2::new(0.0, h)];
+    let Some((d_in, d_out)) = corner_cuts(fillet, chamfer) else { return corners.into_iter().map(PolyVertex::new).collect() };
+    // A fillet's quarter circle bulges the way the rectangle runs; a chamfer is straight.
+    let quarter = cadcraft_geom::arc_to_bulge(std::f64::consts::FRAC_PI_2);
+    let bulge = match (fillet > 0.0, w * h < 0.0) {
+        (false, _) => 0.0,
+        (true, false) => quarter,
+        (true, true) => -quarter,
+    };
+    let fits = corners_fit((w, h), fillet, chamfer);
+    let mut out = Vec::with_capacity(8);
+    for (i, c) in corners.iter().enumerate() {
+        let (Some(prev), Some(next)) = (corners.get((i + 3) % 4), corners.get((i + 1) % 4)) else { continue };
+        if fits {
+            out.push(PolyVertex::with_bulge(*c - (*c - *prev).normalized() * d_in, bulge));
+            out.push(PolyVertex::new(*c + (*next - *c).normalized() * d_out));
+        } else {
+            out.extend([PolyVertex::new(*c), PolyVertex::new(*c)]);
+        }
+    }
+    out
+}
+
+/// How far a fillet or chamfer cuts into the edges into and out of each corner, if one is set.
+fn corner_cuts(fillet: f64, chamfer: (f64, f64)) -> Option<(f64, f64)> {
+    if fillet > 0.0 {
+        Some((fillet, fillet))
+    } else if chamfer.0 > 0.0 && chamfer.1 > 0.0 {
+        Some(chamfer)
+    } else {
+        None
+    }
+}
+
+/// Whether the fillet or chamfer fits the shorter side of a `w` × `h` rectangle (else its
+/// corners stay square).
+fn corners_fit((w, h): (f64, f64), fillet: f64, chamfer: (f64, f64)) -> bool {
+    corner_cuts(fillet, chamfer).is_none_or(|(d_in, d_out)| d_in + d_out <= w.abs().min(h.abs()) * (1.0 + 1e-12))
+}
+
+/// The area the rounded or cut corners take off the full rectangle: AutoCAD's Area option sizes
+/// the rectangle so its outline, corners included, encloses the area asked for.
+fn corner_cut(fillet: f64, chamfer: (f64, f64)) -> f64 {
+    if fillet > 0.0 {
+        (4.0 - std::f64::consts::PI) * fillet * fillet
+    } else if chamfer.0 > 0.0 && chamfer.1 > 0.0 {
+        2.0 * chamfer.0 * chamfer.1
+    } else {
+        0.0
+    }
+}
+
+/// The sides of the rectangle of `area` whose length (or, with `breadth`, width) is `side`: the
+/// corners' cut is added back so the outline encloses the area, unless the corners then don't fit
+/// and stay square, when the area is the full rectangle's.
+fn area_sides(area: f64, side: f64, breadth: bool, fillet: f64, chamfer: (f64, f64)) -> (f64, f64) {
+    let sides = |a: f64| if breadth { (a / side, side) } else { (side, a / side) };
+    let cut = sides(area + corner_cut(fillet, chamfer));
+    if corners_fit(cut, fillet, chamfer) { cut } else { sides(area) }
+}
+
 fn rect_kind(first: Vec2, (w, h): (f64, f64), rot: f64, fillet: f64, chamfer: (f64, f64), width: f64, elevation: f64) -> EntityKind {
-    let local = rect_with_corners(Vec2::ZERO, Vec2::new(w, h), fillet, chamfer);
+    let local = rect_corner_vertices((w, h), fillet, chamfer);
     let vs = local.into_iter().map(|v| PolyVertex { p: first + v.p.rotate(rot), ..v }).collect();
     let mut k = lwpoly(vs, true);
     if let EntityKind::LwPolyline(pl) = &mut k {
@@ -16,8 +97,9 @@ fn rect_kind(first: Vec2, (w, h): (f64, f64), rot: f64, fillet: f64, chamfer: (f
 }
 
 /// The width and height of a rectangle from its `dimensions`, its `p2` corner, its `area` with
-/// `length` or `breadth`, or its second corner `p2`, rotated by `rot` about `a`.
-fn rect_size(p: &Value, a: Vec2, rot: f64, centered: bool) -> Result<(f64, f64)> {
+/// `length` or `breadth` (allowing for the `fillet` or `chamfer` corners), or its second corner
+/// `p2`, rotated by `rot` about `a`.
+fn rect_size(p: &Value, a: Vec2, rot: f64, centered: bool, fillet: f64, chamfer: (f64, f64)) -> Result<(f64, f64)> {
     Ok(if let Some(d) = p.get("dimensions").and_then(Value::as_array) {
         let l = d.first().and_then(Value::as_f64).filter(|v| v.is_finite()).ok_or_else(|| bad("rectang", "dimensions: [length, width]"))?;
         let wd = d.get(1).and_then(Value::as_f64).filter(|v| v.is_finite()).ok_or_else(|| bad("rectang", "dimensions: [length, width]"))?;
@@ -34,8 +116,8 @@ fn rect_size(p: &Value, a: Vec2, rot: f64, centered: bool) -> Result<(f64, f64)>
             return Err(bad("rectang", "area must be positive"));
         }
         match (p.get("length").and_then(Value::as_f64), p.get("breadth").and_then(Value::as_f64)) {
-            (Some(l), _) if l.is_finite() && l > 0.0 => (l, area / l),
-            (_, Some(b)) if b.is_finite() && b > 0.0 => (area / b, b),
+            (Some(l), _) if l.is_finite() && l > 0.0 => area_sides(area, l, false, fillet, chamfer),
+            (_, Some(b)) if b.is_finite() && b > 0.0 => area_sides(area, b, true, fillet, chamfer),
             _ => return Err(bad("rectang", "area needs `length` or `breadth`")),
         }
     } else {
@@ -64,7 +146,7 @@ pub(crate) fn run_rectang2(s: &mut Session, p: &Value) -> Result<Value> {
     }
     let fillet = size_param("rectang", p, "fillet", true)?.unwrap_or(0.0);
     let width = size_param("rectang", p, "width", true)?.unwrap_or(0.0);
-    let (w, h) = rect_size(p, a, rot, centered)?;
+    let (w, h) = rect_size(p, a, rot, centered, fillet, ch)?;
     if w.abs() < 1e-12 || h.abs() < 1e-12 || !w.is_finite() || !h.is_finite() {
         return Err(bad("rectang", "rectangle has no area"));
     }
@@ -125,8 +207,20 @@ impl RectM2 {
         // A rectangle has its own thickness option and does not take THICKNESS.
         let t = self.thickness;
         s.doc_mut()?.modify_entity(hd, |e| e.common.thickness = t)?;
+        self.remember(s);
         Ok(Step::Done)
     }
+    /// Keeps the corner options for the next RECTANG.
+    fn remember(&self, s: &mut Session) {
+        s.last_used.rectang = RectangModes {
+            chamfer: self.chamfer,
+            fillet: self.fillet,
+            width: self.width,
+            elevation: self.elevation,
+            thickness: self.thickness,
+            rotation: self.rotation,
+        };
+    }
     /// The rectangle's local origin (the corner `rect_kind` draws from) for a size: the first
     /// point itself as a corner, or the first point less half the size around the centre.
     fn origin(&self, w: f64, h: f64) -> Option<Vec2> {
@@ -152,6 +246,17 @@ impl Interactive for RectM2 {
     fn name(&self) -> &'static str {
         "RECTANG"
     }
+    /// Starts from the corner options the last RECTANG used.
+    fn begin(&mut self, s: &mut Session) -> Result<Step> {
+        let m = s.last_used.rectang;
+        self.chamfer = m.chamfer;
+        self.fillet = m.fillet;
+        self.width = m.width;
+        self.elevation = m.elevation;
+        self.thickness = m.thickness;
+        self.rotation = m.rotation;
+        Ok(Step::Continue)
+    }
     /// Asks for the pending option's value, or for the first and second points; in centre mode
     /// the first prompt asks for the centre instead of a corner.
     fn prompt(&self, _s: &Session) -> Prompt {
@@ -204,8 +309,15 @@ impl Interactive for RectM2 {
                     self.chamfer.1 = self.chamfer.0;
                     self.asking = Some(RAsk::Chamfer2);
                 }
-                RAsk::Chamfer2 => self.chamfer.1 = val(&i, self.chamfer.1)?.max(0.0),
-                RAsk::Fillet => self.fillet = val(&i, self.fillet)?.max(0.0),
+                // A rectangle's corners are chamfered or filleted: the option set last wins.
+                RAsk::Chamfer2 => {
+                    self.chamfer.1 = val(&i, self.chamfer.1)?.max(0.0);
+                    self.fillet = 0.0;
+                }
+                RAsk::Fillet => {
+                    self.fillet = val(&i, self.fillet)?.max(0.0);
+                    self.chamfer = (0.0, 0.0);
+                }
                 RAsk::Width => self.width = val(&i, self.width)?.max(0.0),
                 RAsk::Elevation => self.elevation = val(&i, self.elevation)?,
                 RAsk::Thickness => self.thickness = val(&i, self.thickness)?,
@@ -228,7 +340,7 @@ impl Interactive for RectM2 {
                         self.asking = Some(a);
                         return Err(other("Value must be positive."));
                     }
-                    let (w, h) = if a == RAsk::AreaLength { (v, self.area / v) } else { (self.area / v, v) };
+                    let (w, h) = area_sides(self.area, v, a == RAsk::AreaWidth, self.fillet, self.chamfer);
                     return self.make(s, w, h);
                 }
                 RAsk::DimL => {
@@ -257,6 +369,7 @@ impl Interactive for RectM2 {
                     }
                 }
             }
+            self.remember(s);
             return Ok(Step::Continue);
         }
         match i {
diff --git a/crates/engine/src/cmd/draw2/tests.rs b/crates/engine/src/cmd/draw2/tests.rs
--- a/crates/engine/src/cmd/draw2/tests.rs
+++ b/crates/engine/src/cmd/draw2/tests.rs
@@ -611,7 +611,8 @@ fn rectang_options_command_line() {
     s.cmdline("rectang 0,0 r p 0,0 1,1 d 2 2 5,5").unwrap();
     let pts = rect_pts(&s);
     assert!(pts.iter().any(|p| near(*p, 0.0, 8f64.sqrt())), "{pts:?}");
-    s.cmdline("rectang w 0.5 c 0.5 0.5 0,0 4,4").unwrap();
+    // The 45° rotation picked above is remembered, as AutoCAD remembers it: set it back.
+    s.cmdline("rectang w 0.5 c 0.5 0.5 0,0 r 0 4,4").unwrap();
     match last(&s) {
         EntityKind::LwPolyline(p) => assert!(p.const_width == 0.5 && p.vertices.len() == 8),
         k => panic!("{k:?}"),
@@ -623,6 +624,241 @@ fn rectang_options_command_line() {
     }
 }
 
+/// RECTANG against what AutoCAD 2024 stores for the same typed input (black-box: synthetic
+/// input in accoreconsole, read back with `entget`): vertex order, chamfer and fillet corners,
+/// corners too large for the sides, Area with the corners taken off, and options remembered
+/// between invocations.
+#[test]
+fn rectang_vertices_match_autocad() {
+    type Case = (&'static [&'static str], &'static [[f64; 3]], [f64; 3]);
+    // (typed input, vertices [x, y, bulge], [width, elevation, thickness])
+    let cases: [Case; 12] = [
+        // RECTANG-000: the first corner first, along the first axis: clockwise here.
+        (
+            &["rectang -2.2557479240466947,-9.488221049171962 _R 0 -31.36203661716106,-47.886714708394166"],
+            &[
+                [-2.255747924046694, -9.488221049171962, 0.0],
+                [-31.36203661716105, -9.488221049171962, 0.0],
+                [-31.36203661716105, -47.88671470839417, 0.0],
+                [-2.255747924046694, -47.88671470839417, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+        // RECTANG-001: chamfer: the first distance on the edge into each corner, the second on the edge out.
+        (
+            &["rectang _C 2.2518104656366162 3.766337568886034 4.8089419289768,29.66648885915597 _R 0 28.114797694689763,43.85884965263156"],
+            &[
+                [4.8089419289768, 31.91829932479258, 0.0],
+                [8.575279497862834, 29.66648885915597, 0.0],
+                [25.86298722905314, 29.66648885915597, 0.0],
+                [28.11479769468976, 33.432826428042, 0.0],
+                [28.11479769468976, 41.60703918699494, 0.0],
+                [24.34846012580373, 43.85884965263156, 0.0],
+                [7.060752394613416, 43.85884965263156, 0.0],
+                [4.8089419289768, 40.09251208374553, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+        // RECTANG-009: the same, running clockwise.
+        (
+            &["rectang _C 1.6573799714125943 2.8497357251231277 24.04847098725292,25.59232167490267 _R 0 6.633832923690861,65.99502168115245"],
+            &[
+                [24.04847098725292, 27.24970164631526, 0.0],
+                [21.19873526212979, 25.59232167490267, 0.0],
+                [8.291212895103454, 25.59232167490267, 0.0],
+                [6.63383292369086, 28.4420574000258, 0.0],
+                [6.63383292369086, 64.33764170973986, 0.0],
+                [9.48356864881399, 65.99502168115245, 0.0],
+                [22.39109101584032, 65.99502168115245, 0.0],
+                [24.04847098725292, 63.14528595602933, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+        // RECTANG-018: a fillet running clockwise bulges the other way.
+        (
+            &["rectang _F 1.5960102281545085 -8.446136404870288,-1.0540502598928434 _R 0 41.8290524978361,-18.73385540701941"],
+            &[
+                [-8.446136404870288, -2.650060488047352, -0.414213562373095],
+                [-6.850126176715778, -1.054050259892843, 0.0],
+                [40.23304226968159, -1.054050259892843, -0.414213562373095],
+                [41.8290524978361, -2.650060488047352, 0.0],
+                [41.8290524978361, -17.1378451788649, -0.414213562373095],
+                [40.23304226968159, -18.7338554070194, 0.0],
+                [-6.850126176715778, -18.7338554070194, -0.414213562373095],
+                [-8.446136404870288, -17.1378451788649, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+        // RECTANG-025: Chamfer then Fillet: the fillet wins.
+        (
+            &["rectang _C 1.0 2.0 _F 3.0 -23.770950967162776,10.634038271168158 _R 0 5.6012940597800664,50.84914942110857"],
+            &[
+                [-23.77095096716277, 13.63403827116815, 0.414213562373095],
+                [-20.77095096716277, 10.63403827116815, 0.0],
+                [2.601294059780066, 10.63403827116815, 0.414213562373095],
+                [5.601294059780066, 13.63403827116815, 0.0],
+                [5.601294059780066, 47.84914942110857, 0.414213562373095],
+                [2.601294059780066, 50.84914942110857, 0.0],
+                [-20.77095096716277, 50.84914942110857, 0.414213562373095],
+                [-23.77095096716277, 47.84914942110857, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+        // RECTANG-026: Fillet then Chamfer: the chamfer wins.
+        (
+            &["rectang _F 3.0 _C 1.0 2.0 8.075900385075748,-27.116639225773056 _R 0 20.00095065903931,8.864147463029973"],
+            &[
+                [8.075900385075748, -26.11663922577305, 0.0],
+                [10.07590038507574, -27.11663922577305, 0.0],
+                [19.00095065903931, -27.11663922577305, 0.0],
+                [20.00095065903931, -25.11663922577305, 0.0],
+                [20.00095065903931, 7.864147463029972, 0.0],
+                [18.00095065903931, 8.864147463029973, 0.0],
+                [9.075900385075748, 8.864147463029973, 0.0],
+                [8.075900385075748, 6.864147463029972, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+        // RECTANG-028: Area counts the chamfered corners off.
+        (
+            &["rectang _C 1.5 2.5 26.36462345136234,-19.7291241693893 _R 0 _A 1442.9297064464572 _W 35.53488991311575"],
+            &[
+                [26.36462345136234, -18.2291241693893, 0.0],
+                [28.86462345136234, -19.7291241693893, 0.0],
+                [65.68168268505678, -19.7291241693893, 0.0],
+                [67.18168268505678, -17.2291241693893, 0.0],
+                [67.18168268505678, 14.30576574372644, 0.0],
+                [64.68168268505678, 15.80576574372644, 0.0],
+                [27.86462345136234, 15.80576574372644, 0.0],
+                [26.36462345136234, 13.30576574372644, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+        // RECTANG-035-VN: Area counts the fillets off, at survey coordinates.
+        (
+            &["rectang _F 2.0 612322.0691653182,2398792.948957577 _R 0 _A 592.8936847254046 _L 19.287858563349488"],
+            &[
+                [612322.0691653182, 2398794.948957577, 0.414213562373095],
+                [612324.0691653182, 2398792.948957577, 0.0],
+                [612339.3570238815, 2398792.948957577, 0.414213562373095],
+                [612341.3570238815, 2398794.948957577, 0.0],
+                [612341.3570238815, 2398821.866195597, 0.414213562373095],
+                [612339.3570238815, 2398823.866195598, 0.0],
+                [612324.0691653182, 2398823.866195598, 0.414213562373095],
+                [612322.0691653182, 2398821.866195597, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+        // RECTANG-029: a fillet too large: each corner two coincident vertices.
+        (
+            &["rectang _F 11.37084114989061 -21.46774953784037,-0.023473793210982308 _R 0 -2.5163476213560187,49.88119923361903"],
+            &[
+                [-21.46774953784036, -0.0234737932109823, 0.0],
+                [-21.46774953784036, -0.0234737932109823, 0.0],
+                [-2.516347621356018, -0.0234737932109823, 0.0],
+                [-2.516347621356018, -0.0234737932109823, 0.0],
+                [-2.516347621356018, 49.88119923361903, 0.0],
+                [-2.516347621356018, 49.88119923361903, 0.0],
+                [-21.46774953784036, 49.88119923361903, 0.0],
+                [-21.46774953784036, 49.88119923361903, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+        // RECTANG-039-VN: a chamfer too large, rotated, with Dimensions.
+        (
+            &[
+                "rectang _C 18.656567079201356 18.656567079201356 612317.9599920243,2398739.0200147885 _R 30 _D 26.652238684573366 32.64533161964191 612344.6122307089,2398771.6653464083",
+            ],
+            &[
+                [612317.9599920243, 2398739.020014788, 0.0],
+                [612317.9599920243, 2398739.020014788, 0.0],
+                [612341.041507793, 2398752.34613413, 0.0],
+                [612341.041507793, 2398752.34613413, 0.0],
+                [612324.7188419831, 2398780.617820628, 0.0],
+                [612324.7188419831, 2398780.617820628, 0.0],
+                [612301.6373262145, 2398767.291701286, 0.0],
+                [612301.6373262145, 2398767.291701286, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+        // RECTANG-030: rotation by two points, elevation and thickness.
+        (
+            &["rectang _E 7.5 _T 2.25 -18.42481827666694,-20.50343704206707 _R _P 0.0,0.0 10.0,6.0 10.197290578707722,25.5222006119985"],
+            &[
+                [-18.42481827666694, -20.50343704206706, 0.0],
+                [22.92627837613747, 4.307220949615576, 0.0],
+                [10.19729057870772, 25.5222006119985, 0.0],
+                [-31.15380607409669, 0.7115426203158534, 0.0],
+            ],
+            [0.0, 7.5, 2.25],
+        ),
+        // RECTANG-024: the fillet is remembered for the next RECTANG.
+        (
+            &[
+                "rectang _F 2.0 -12.364845593042645,8.36037449067684 _R 0 31.044931977794846,17.998089850295315",
+                "rectang 41.044931977794846,27.998089850295315 84.45470954863234,37.63580520991379",
+            ],
+            &[
+                [41.04493197779484, 29.99808985029531, 0.414213562373095],
+                [43.04493197779485, 27.99808985029531, 0.0],
+                [82.45470954863234, 27.99808985029531, 0.414213562373095],
+                [84.45470954863234, 29.99808985029531, 0.0],
+                [84.45470954863234, 35.63580520991379, 0.414213562373095],
+                [82.45470954863234, 37.63580520991379, 0.0],
+                [43.04493197779485, 37.63580520991379, 0.414213562373095],
+                [41.04493197779484, 35.63580520991379, 0.0],
+            ],
+            [0.0, 0.0, 0.0],
+        ),
+    ];
+    let same = |a: f64, b: f64| (a - b).abs() <= 1e-9 * a.abs().max(b.abs()).max(1.0);
+    for (input, want, [width, elevation, thickness]) in cases {
+        let mut s = Session::new();
+        for line in input {
+            s.cmdline(line).unwrap();
+            assert!(s.running.is_none(), "{line}: {}", s.prompt_text());
+        }
+        let e = s.doc().unwrap().model.last().unwrap().clone();
+        let EntityKind::LwPolyline(p) = &e.kind else { panic!("{input:?}: {:?}", e.kind) };
+        let got: Vec<[f64; 3]> = p.vertices.iter().map(|v| [v.p.x, v.p.y, v.bulge]).collect();
+        let ok = got.len() == want.len() && got.iter().zip(want).all(|(g, w)| g.iter().zip(w).all(|(a, b)| same(*a, *b)));
+        assert!(
+            ok,
+            "{input:?}
+ got {got:?}
+want {want:?}"
+        );
+        assert!(p.closed && same(p.const_width, width) && same(p.elevation, elevation) && same(e.common.thickness, thickness), "{input:?}");
+    }
+    // Rotation, elevation and thickness are remembered too: AutoCAD opens the next RECTANG with
+    // "Current rectangle modes:  Elevation=7.5000  Thickness=2.2500  Rotation=30.96".
+    let mut s = Session::new();
+    s.cmdline("rectang _E 7.5 _T 2.25 0,0 _R _P 0,0 10,6 10,20").unwrap();
+    s.cmdline("rectang 100,100 110,105").unwrap();
+    let e = s.doc().unwrap().model.last().unwrap().clone();
+    let EntityKind::LwPolyline(p) = &e.kind else { panic!("{:?}", e.kind) };
+    let edge = p.vertices[1].p - p.vertices[0].p;
+    assert!(p.vertices[0].p == Vec2::new(100.0, 100.0) && same(edge.angle(), 6f64.atan2(10.0)), "{p:?}");
+    assert!(p.elevation == 7.5 && e.common.thickness == 2.25);
+}
+
+/// Area allows for cut corners only while they fit: a fillet too large for the resulting sides
+/// leaves square corners, so the rectangle is the full area asked for (4 × 1, not 4 × 1.858).
+#[test]
+fn rectang_area_with_corners_too_large_stays_exact() {
+    let check = |s: &Session| {
+        let pts = rect_pts(s);
+        let b = cadcraft_geom::Bounds2::from_points(pts.clone());
+        assert!(near(b.min, 0.0, 0.0) && near(b.max, 4.0, 1.0), "{pts:?}");
+        assert!(pts.len() == 8 && pts.chunks(2).all(|c| c[0] == c[1]), "{pts:?}");
+    };
+    let mut s = Session::new();
+    s.cmdline("rectang _F 2 0,0 _A 4 _L 4").unwrap();
+    check(&s);
+    s.execute("rectang", &json!({"p1": [0, 0], "area": 4, "length": 4, "fillet": 2})).unwrap();
+    check(&s);
+}
+
 /// Guards the JSON `center: true` form for every sizing route: a picked corner mirrored about
 /// the centre, full-size `dimensions`, full `area`, rotation about the centre, that the default
 /// corner mode is untouched, and that centre mode without a size is rejected.
@@ -658,7 +894,7 @@ fn rectang_center_mode_json() {
 }
 
 /// Guards that fillet, chamfer, width and thickness still apply in centre mode, and that an
-/// oversized fillet falls back to sharp corners without moving the rectangle off centre.
+/// oversized fillet leaves sharp corners without moving the rectangle off centre.
 #[test]
 fn rectang_center_mode_honours_options() {
     let mut s = Session::new();
@@ -675,9 +911,11 @@ fn rectang_center_mode_honours_options() {
     assert_eq!(rect_pts(&s).len(), 8);
     let b = cadcraft_geom::Bounds2::from_points(rect_pts(&s));
     assert!(near(b.min, 6.0, 4.0) && near(b.max, 14.0, 16.0), "{b:?}");
-    // A fillet too large for the rectangle falls back to sharp corners, still centred.
+    // A fillet too large for the rectangle leaves sharp corners, each one two coincident vertices
+    // as in AutoCAD, still centred.
     s.execute("rectang", &json!({"center": true, "p1": [10, 10], "p2": [14, 16], "fillet": 5})).unwrap();
-    assert_eq!(rect_pts(&s).len(), 4);
+    let pts = rect_pts(&s);
+    assert!(pts.len() == 8 && pts.chunks(2).all(|c| c[0] == c[1]), "{pts:?}");
     let b = cadcraft_geom::Bounds2::from_points(rect_pts(&s));
     assert!(near(b.min, 6.0, 4.0) && near(b.max, 14.0, 16.0), "{b:?}");
 }
@@ -705,8 +943,9 @@ fn rectang_center_mode_command_line() {
     assert!(s.running.is_none(), "{}", s.prompt_text());
     let b = cadcraft_geom::Bounds2::from_points(rect_pts(&s));
     assert!(near(b.min, 6.0, 4.0) && near(b.max, 14.0, 16.0), "{b:?}");
-    // Area too: the rectangle of that area is centred on the first point.
-    s.cmdline("rectang ce 10,10 a 96 l 8").unwrap();
+    // Area too: the rectangle of that area is centred on the first point (without the fillet
+    // remembered from above, which would take its corners off the area).
+    s.cmdline("rectang f 0 ce 10,10 a 96 l 8").unwrap();
     assert!(s.running.is_none(), "{}", s.prompt_text());
     let b = cadcraft_geom::Bounds2::from_points(rect_pts(&s));
     assert!(near(b.min, 6.0, 4.0) && near(b.max, 14.0, 16.0), "{b:?}");
diff --git a/crates/engine/src/cmd/helpers.rs b/crates/engine/src/cmd/helpers.rs
--- a/crates/engine/src/cmd/helpers.rs
+++ b/crates/engine/src/cmd/helpers.rs
@@ -62,45 +62,6 @@ pub fn polygon_from_edge(p1: Vec2, p2: Vec2, sides: usize) -> Vec<PolyVertex> {
     pts.into_iter().map(PolyVertex::new).collect()
 }
 
-/// Rectangle vertices with fillet radius or chamfer distances at every corner.
-pub fn rect_with_corners(a: Vec2, b: Vec2, fillet: f64, chamfer: (f64, f64)) -> Vec<PolyVertex> {
-    let (x0, x1) = (a.x.min(b.x), a.x.max(b.x));
-    let (y0, y1) = (a.y.min(b.y), a.y.max(b.y));
-    let w = x1 - x0;
-    let h = y1 - y0;
-    if fillet > 0.0 && fillet * 2.0 <= w.min(h) + 1e-12 {
-        let r = fillet;
-        let bul = cadcraft_geom::arc_to_bulge(std::f64::consts::FRAC_PI_2);
-        return vec![
-            PolyVertex::new(Vec2::new(x0 + r, y0)),
-            PolyVertex::with_bulge(Vec2::new(x1 - r, y0), bul),
-            PolyVertex::new(Vec2::new(x1, y0 + r)),
-            PolyVertex::with_bulge(Vec2::new(x1, y1 - r), bul),
-            PolyVertex::new(Vec2::new(x1 - r, y1)),
-            PolyVertex::with_bulge(Vec2::new(x0 + r, y1), bul),
-            PolyVertex::new(Vec2::new(x0, y1 - r)),
-            PolyVertex::with_bulge(Vec2::new(x0, y0 + r), bul),
-        ];
-    }
-    let (c1, c2) = chamfer;
-    if c1 > 0.0 && c2 > 0.0 && c1 + c1 <= w + 1e-12 && c2 + c2 <= h + 1e-12 {
-        return [
-            Vec2::new(x0 + c1, y0),
-            Vec2::new(x1 - c1, y0),
-            Vec2::new(x1, y0 + c2),
-            Vec2::new(x1, y1 - c2),
-            Vec2::new(x1 - c1, y1),
-            Vec2::new(x0 + c1, y1),
-            Vec2::new(x0, y1 - c2),
-            Vec2::new(x0, y0 + c2),
-        ]
-        .into_iter()
-        .map(PolyVertex::new)
-        .collect();
-    }
-    rect_vertices(Vec2::new(x0, y0), Vec2::new(x1, y1))
-}
-
 // ---------- the user's support files ----------
 
 /// Largest support file (linetype, hatch pattern or alias file) read.
diff --git a/crates/engine/src/last_used.rs b/crates/engine/src/last_used.rs
--- a/crates/engine/src/last_used.rs
+++ b/crates/engine/src/last_used.rs
@@ -25,6 +25,8 @@ pub struct LastUsed {
     pub mleader_block: String,
     /// BREAKLINE's Block, Size and Extension.
     pub breakline: cmd::BreaklineOptions,
+    /// RECTANG's chamfer, fillet, width, elevation, thickness and rotation.
+    pub rectang: cmd::RectangModes,
 }
 
 impl Default for LastUsed {
@@ -39,6 +41,7 @@ impl Default for LastUsed {
             mleader: MLeaderOptions::default(),
             mleader_block: String::new(),
             breakline: cmd::BreaklineOptions::default(),
+            rectang: cmd::RectangModes::default(),
         }
     }
 }
