From cdcee12a541101a4685ac2057eccfdc01851e5c7 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Fri, 13 Nov 2026 11:17:38 +0000 Subject: [PATCH] Expose linear units through DXF drawing builder --- crates/dxf/src/model/write.rs | 13 +++++++------ crates/dxf/tests/model_write.rs | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/crates/dxf/src/model/write.rs b/crates/dxf/src/model/write.rs index 17ceec7a3..6d2879cd9 100644 --- a/crates/dxf/src/model/write.rs +++ b/crates/dxf/src/model/write.rs @@ -1414,8 +1414,6 @@ pub struct Drawing<'a> { pub insunits: i64, /// `$MEASUREMENT`: metric (R2000 and later). pub metric: bool, - /// `$LUNITS` (linear display format), when the caller needs a non-default value. - pub linear_units: Option, /// `[x0, y0, x1, y1]` of the content: `$EXTMIN`/`$EXTMAX`, and the view the file opens at. pub extents: [f64; 4], /// `$LIMMIN`/`$LIMMAX`. @@ -1457,7 +1455,6 @@ impl Default for Drawing<'_> { code_page: String::new(), insunits: 0, metric: true, - linear_units: None, extents: [0.0, 0.0, 1.0, 1.0], limits: [0.0, 0.0, 420.0, 297.0], header: Vec::new(), @@ -1481,6 +1478,13 @@ const MODEL: &str = "*Model_Space"; const PAPER: &str = "*Paper_Space"; impl Drawing<'_> { + /// Set `$LUNITS` without making callers construct low-level group tags. + pub fn with_linear_units(mut self, units: i64) -> Self { + self.header.retain(|(name, _)| !name.eq_ignore_ascii_case("$LUNITS")); + self.header.push(("$LUNITS".into(), vec![Tag::i(70, units)])); + self + } + /// The whole file as tags, ending with `0 EOF`, and how many entities were left out /// ([`EntityKind::Other`], and a MULTILEADER before 2007 or an ACAD_TABLE before 2004, which it has no groups for: pass /// those in `raw_entities`). @@ -1627,9 +1631,6 @@ impl Drawing<'_> { vars.push(("$INSUNITS", vec![Tag::i(70, self.insunits)])); vars.push(("$MEASUREMENT", vec![Tag::i(70, i64::from(self.metric))])); } - if let Some(linear_units) = self.linear_units { - vars.push(("$LUNITS", vec![Tag::i(70, linear_units)])); - } w.section("HEADER"); let given = |name: &str| self.header.iter().any(|(n, _)| n.eq_ignore_ascii_case(name)); // The version and the handle seed are the writer's to say. diff --git a/crates/dxf/tests/model_write.rs b/crates/dxf/tests/model_write.rs index 80136c85b..8ece9c5bb 100644 --- a/crates/dxf/tests/model_write.rs +++ b/crates/dxf/tests/model_write.rs @@ -586,7 +586,6 @@ fn the_file_around_the_content() { ], raw_entities: raw, extents: [0.0, 0.0, 100.0, 50.0], - linear_units: Some(2), header: vec![ ("$LTSCALE".into(), vec![Tag::f(40, 2.0)]), ("$INSUNITS".into(), vec![Tag::i(70, 6)]), @@ -597,7 +596,8 @@ fn the_file_around_the_content() { raw_objects: vec![Tag::s(0, "DICTIONARY"), Tag::s(5, "901"), Tag::s(330, "A")], raw_classes: vec![Tag::s(0, "CLASS"), Tag::s(1, "IMAGEDEF")], ..Drawing::default() - }; + } + .with_linear_units(2); let (tags, skipped) = drawing.tags(); assert_eq!(skipped, 1, "the entity with no groups to write"); assert_eq!(tags.last().map(|t| (t.code, t.str())), Some((0, "EOF".to_string())));