fix(text): respect object annotative state
This commit is contained in:
parent
0c5d6af1d0
commit
6aaf1ff123
3 changed files with 68 additions and 9 deletions
|
|
@ -1108,6 +1108,14 @@ impl super::OpenCADStudio {
|
|||
let Some(ed) = self.mtext_editor.take() else { return false };
|
||||
let body_empty = ed.content.text().trim().is_empty();
|
||||
let mut mt = ed.build_mtext();
|
||||
let annotative = ed.editing.is_none()
|
||||
&& crate::scene::annotative::text_style_is_annotative(
|
||||
&self.tabs[i].scene.document,
|
||||
&mt.style,
|
||||
);
|
||||
if annotative {
|
||||
mt.is_annotative = true;
|
||||
}
|
||||
if body_empty {
|
||||
// Empty content: drop a new entity; leave an edited one untouched.
|
||||
self.refresh_properties();
|
||||
|
|
@ -1141,7 +1149,17 @@ impl super::OpenCADStudio {
|
|||
// Align new MText to the active UCS (text runs along the UCS X axis).
|
||||
mt.rotation = self.tabs[i].ucs_rotation_angle();
|
||||
self.push_undo_snapshot(i, "MTEXT");
|
||||
self.commit_entity(EntityType::MText(mt));
|
||||
let handle = self.commit_entity_handle(EntityType::MText(mt));
|
||||
if annotative {
|
||||
let scale = self.tabs[i].scene.current_annotation_scale_handle();
|
||||
if let (Some(handle), Some(scale)) = (handle, scale) {
|
||||
crate::scene::annotative::create_annotation_context(
|
||||
&mut self.tabs[i].scene.document,
|
||||
handle,
|
||||
scale,
|
||||
);
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
}
|
||||
self.refresh_properties();
|
||||
|
|
@ -1163,6 +1181,14 @@ impl super::OpenCADStudio {
|
|||
),
|
||||
None => return,
|
||||
};
|
||||
let annotative = editing.is_none()
|
||||
&& crate::scene::annotative::text_style_is_annotative(
|
||||
&self.tabs[i].scene.document,
|
||||
&mt.style,
|
||||
);
|
||||
if annotative {
|
||||
mt.is_annotative = true;
|
||||
}
|
||||
if body_empty {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1195,6 +1221,16 @@ impl super::OpenCADStudio {
|
|||
self.push_undo_snapshot(i, "MTEXT");
|
||||
let handle = self.commit_entity_handle(EntityType::MText(mt));
|
||||
self.tabs[i].dirty = true;
|
||||
if annotative {
|
||||
let scale = self.tabs[i].scene.current_annotation_scale_handle();
|
||||
if let (Some(handle), Some(scale)) = (handle, scale) {
|
||||
crate::scene::annotative::create_annotation_context(
|
||||
&mut self.tabs[i].scene.document,
|
||||
handle,
|
||||
scale,
|
||||
);
|
||||
}
|
||||
}
|
||||
// Bind the editor to the fresh entity so the next Apply updates it.
|
||||
if let (Some(h), Some(ed)) = (handle, self.mtext_editor.as_mut()) {
|
||||
ed.editing = Some(h);
|
||||
|
|
|
|||
|
|
@ -227,10 +227,24 @@ impl super::OpenCADStudio {
|
|||
if !cur_style.is_empty() {
|
||||
t.style = cur_style;
|
||||
}
|
||||
let annotative = crate::scene::annotative::text_style_is_annotative(
|
||||
&self.tabs[i].scene.document,
|
||||
&t.style,
|
||||
);
|
||||
// Align new text to the active UCS (baseline along the UCS X axis).
|
||||
t.rotation = self.tabs[i].ucs_rotation_angle();
|
||||
self.push_undo_snapshot(i, "TEXT");
|
||||
self.commit_entity(EntityType::Text(t));
|
||||
let handle = self.commit_entity_handle(EntityType::Text(t));
|
||||
if annotative {
|
||||
let scale = self.tabs[i].scene.current_annotation_scale_handle();
|
||||
if let (Some(handle), Some(scale)) = (handle, scale) {
|
||||
crate::scene::annotative::create_annotation_context(
|
||||
&mut self.tabs[i].scene.document,
|
||||
handle,
|
||||
scale,
|
||||
);
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
}
|
||||
self.refresh_properties();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
//! tessellation bake (which scales annotative content by the current annotation
|
||||
//! scale) must agree on *which* entities are annotative — so that logic lives
|
||||
//! here, once. An entity is annotative if it carries a per-object annotation
|
||||
//! context, the legacy annotative XDATA, or an annotative style.
|
||||
//! context, legacy annotative XDATA, or an entity-level annotative flag. Text
|
||||
//! style state is consulted only while creating a new text object: changing a
|
||||
//! style later must not retroactively scale existing text.
|
||||
|
||||
use acadrust::entities::{EntityCommon, EntityType};
|
||||
use acadrust::objects::{
|
||||
|
|
@ -73,8 +75,8 @@ pub fn root_named_dict_handle(doc: &mut CadDocument) -> Handle {
|
|||
/// (MTEXT, MULTILEADER). Turning it off also strips the per-object annotation
|
||||
/// context and legacy markers via [`clear_annotation_context`] so the object
|
||||
/// stops resolving annotative; turning it on leaves the base geometry as the
|
||||
/// single (implicit, current-scale) representation. Other entity types get
|
||||
/// their annotative state from a style and are not toggled here.
|
||||
/// single (implicit, current-scale) representation. TEXT uses a context rather
|
||||
/// than a native flag; other entity types are not toggled here.
|
||||
pub fn set_entity_annotative(doc: &mut CadDocument, handle: Handle, want: bool) {
|
||||
if let Some(e) = doc.get_entity_mut(handle) {
|
||||
match e {
|
||||
|
|
@ -963,7 +965,12 @@ fn name_matches(style_name: &str, name: &str) -> bool {
|
|||
|| (name.trim().is_empty() && style_name.eq_ignore_ascii_case("Standard"))
|
||||
}
|
||||
|
||||
fn text_style_annotative(doc: &CadDocument, name: &str) -> bool {
|
||||
/// Whether `name` currently names an annotative text style.
|
||||
///
|
||||
/// Creation paths use this to stamp a new TEXT/MTEXT with its own annotation
|
||||
/// context. Render-time detection deliberately does not use it: an existing
|
||||
/// non-annotative object may still reference a style later made annotative.
|
||||
pub fn text_style_is_annotative(doc: &CadDocument, name: &str) -> bool {
|
||||
doc.text_styles
|
||||
.iter()
|
||||
.find(|s| name_matches(&s.name, name))
|
||||
|
|
@ -1037,10 +1044,12 @@ pub fn is_annotative(doc: &CadDocument, entity: &EntityType) -> bool {
|
|||
if xd.get_record("AcAnnoPO").is_some() || xd.get_record("AcAnnotativeData").is_some() {
|
||||
return true;
|
||||
}
|
||||
// Annotative via the assigned style (or the entity's own flag).
|
||||
// Annotative via the entity's own flag or assigned non-text style.
|
||||
// Text styles can be made annotative without converting existing text;
|
||||
// those objects must keep their stored height until explicitly updated.
|
||||
match entity {
|
||||
EntityType::Text(t) => text_style_annotative(doc, &t.style),
|
||||
EntityType::MText(t) => t.is_annotative || text_style_annotative(doc, &t.style),
|
||||
EntityType::Text(_) => false,
|
||||
EntityType::MText(t) => t.is_annotative,
|
||||
EntityType::Dimension(d) => dim_style_annotative(doc, &d.base().style_name),
|
||||
EntityType::Leader(l) => dim_style_annotative(doc, &l.dimension_style),
|
||||
EntityType::MultiLeader(ml) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue