From 2ea3bca0939ca91f861acdc00930ca2322a078e8 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Sat, 8 Aug 2026 02:45:46 +0300 Subject: [PATCH] feat(properties): stop offering a height the style has fixed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A text style with a non-zero height fixes the size of everything drawn in it — the CAD that writes the file skips the height prompt for such a style, and shows the height without letting it be changed. OCS offered the field either way, so a drawing could be edited into disagreeing with its own style. The height row is now read-only when the style fixes it, for TEXT, MTEXT and both attribute kinds. `num_prop` already draws a numeric row either way, so the value still reads the same, just grey. The panel builders are handed an entity, not the document it came from, and widening that trait would touch every entity type. The lookup rides beside the unit context instead, seeded from the same place, since it answers the same kind of question: something the drawing settles that a row needs in order to render itself. Co-Authored-By: Claude Opus 5 --- src/app/properties.rs | 5 +++++ src/entities/attribute.rs | 16 ++++++++++++++-- src/entities/common.rs | 32 ++++++++++++++++++++++++++++++++ src/entities/mtext.rs | 8 +++++++- src/entities/text.rs | 9 ++++++++- 5 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/app/properties.rs b/src/app/properties.rs index 1bfa1bc9e..f7a40df88 100644 --- a/src/app/properties.rs +++ b/src/app/properties.rs @@ -93,6 +93,11 @@ impl OpenCADStudio { crate::entities::common::UnitContext::from_header(h), ); } + { + // Which text styles fix their own height — the height rows read it + // to decide whether they are editable. + crate::entities::common::set_fixed_text_heights(&self.tabs[i].scene.document); + } let layer_names: Vec = self.tabs[i] .scene diff --git a/src/entities/attribute.rs b/src/entities/attribute.rs index 0d9d2aca6..b0910983d 100644 --- a/src/entities/attribute.rs +++ b/src/entities/attribute.rs @@ -468,7 +468,13 @@ impl PropertyEditable for AttributeDefinition { .collect(), }, }, - edit(t!("Height").as_ref(), "att_h", self.height), + // Fixed by the style when the style fixes its height. + crate::entities::common::num_prop( + t!("Height").as_ref(), + "att_h", + self.height, + crate::entities::common::style_fixed_height(&self.text_style).is_none(), + ), edit_angle(t!("Rotation").as_ref(), "att_rot", self.rotation.to_degrees()), edit(t!("Width factor").as_ref(), "att_wf", self.width_factor), edit_angle(t!("Obliquing").as_ref(), "att_ob", self.oblique_angle.to_degrees()), @@ -739,7 +745,13 @@ impl PropertyEditable for AttributeEntity { "atte_annotative", bool_yn(self.flags.annotative), ), - edit(t!("Height").as_ref(), "atte_h", self.height), + // Fixed by the style when the style fixes its height. + crate::entities::common::num_prop( + t!("Height").as_ref(), + "atte_h", + self.height, + crate::entities::common::style_fixed_height(&self.text_style).is_none(), + ), edit_angle(t!("Rotation").as_ref(), "atte_rot", self.rotation.to_degrees()), edit(t!("Width factor").as_ref(), "atte_wf", self.width_factor), edit_angle(t!("Obliquing").as_ref(), "atte_ob", self.oblique_angle.to_degrees()), diff --git a/src/entities/common.rs b/src/entities/common.rs index 6d1315ceb..8a18702c5 100644 --- a/src/entities/common.rs +++ b/src/entities/common.rs @@ -53,6 +53,38 @@ thread_local! { }) }; } +thread_local! { + /// Text styles that fix their own height, by lowercased name. + /// + /// A style with a non-zero height fixes the size of everything drawn in it + /// — the CAD that writes the file skips the height prompt for such a style, + /// and the properties palette shows the height without letting it be + /// changed. The panel builders are handed an entity, not the document it + /// came from, so the lookup rides here beside the unit context, seeded from + /// the same place. + static FIXED_TEXT_HEIGHTS: std::cell::RefCell> = + std::cell::RefCell::new(rustc_hash::FxHashMap::default()); +} + +/// Record which text styles fix their height, from the drawing's style table. +pub fn set_fixed_text_heights(document: &acadrust::CadDocument) { + FIXED_TEXT_HEIGHTS.with(|cell| { + let mut map = cell.borrow_mut(); + map.clear(); + for style in document.text_styles.iter() { + if style.height > 0.0 { + map.insert(style.name.to_ascii_lowercase(), style.height); + } + } + }); +} + +/// The height `style` fixes, or `None` when it leaves the height to the entity. +pub fn style_fixed_height(style: &str) -> Option { + let key = style.trim().to_ascii_lowercase(); + FIXED_TEXT_HEIGHTS.with(|cell| cell.borrow().get(&key).copied()) +} + /// Set the per-thread unit context. Properties helpers consult it when /// they format f64 values into display strings. pub fn set_unit_context(ctx: UnitContext) { diff --git a/src/entities/mtext.rs b/src/entities/mtext.rs index 74b2dfcbb..0abf0adef 100644 --- a/src/entities/mtext.rs +++ b/src/entities/mtext.rs @@ -311,7 +311,13 @@ fn properties(t: &MText, text_style_names: &[String]) -> Vec { .collect(), }, }, - edit(t!("Text height").as_ref(), "height", t.height), + // Fixed by the style when the style says so — see Text. + crate::entities::common::num_prop( + t!("Text height").as_ref(), + "height", + t.height, + crate::entities::common::style_fixed_height(&t.style).is_none(), + ), edit_angle(t!("Rotation").as_ref(), "rotation", t.rotation.to_degrees()), edit(t!("Line space factor").as_ref(), "line_spacing", t.line_spacing_factor), edit(t!("Line space distance").as_ref(), "line_space_distance", line_space_distance), diff --git a/src/entities/text.rs b/src/entities/text.rs index 7b47673ea..e8eed635e 100644 --- a/src/entities/text.rs +++ b/src/entities/text.rs @@ -325,7 +325,14 @@ fn properties(t: &Text, text_style_names: &[String]) -> Vec { .collect(), }, }, - edit(t!("Height").as_ref(), "height", t.height), + // A style that fixes its height fixes this text's too, so the + // value shows but cannot be changed here. + crate::entities::common::num_prop( + t!("Height").as_ref(), + "height", + t.height, + crate::entities::common::style_fixed_height(&t.style).is_none(), + ), edit_angle(t!("Rotation").as_ref(), "rotation", t.rotation.to_degrees()), edit(t!("Width factor").as_ref(), "width_factor", t.width_factor), edit_angle(t!("Obliquing").as_ref(), "oblique_angle", t.oblique_angle.to_degrees()),