diff --git a/src/app/plugin_host.rs b/src/app/plugin_host.rs index 5ac7204c2..0e08b5ae7 100644 --- a/src/app/plugin_host.rs +++ b/src/app/plugin_host.rs @@ -269,24 +269,14 @@ impl<'a> HostSession<'a> { return None; } - let resolved_lt = if let Some(ref lt_name) = config.linetype { - let matched = doc - .line_types - .iter() - .find(|lt| lt.name.eq_ignore_ascii_case(lt_name)) - .map(|lt| lt.name.clone()); - if let Some(m) = matched { - m - } else { - crate::io::linetypes::populate_document(doc); - doc.line_types - .iter() - .find(|lt| lt.name.eq_ignore_ascii_case(lt_name)) - .map(|lt| lt.name.clone()) - .unwrap_or_else(|| lt_name.clone()) - } - } else { - "Continuous".to_string() + let resolved_lt = match config.linetype { + // A name the drawing does not carry would leave the LAYER record + // pointing at no LTYPE, so it is refused rather than written. + Some(ref lt_name) => match resolve_linetype(doc, lt_name) { + Some(name) => name, + None => return None, + }, + None => "Continuous".to_string(), }; let mut layer = acadrust::tables::Layer::new(trimmed); @@ -325,27 +315,12 @@ impl<'a> HostSession<'a> { return false; } - let resolved_lt = if let Some(ref lt_name) = config.linetype { - let doc = self.document_mut(); - let matched = doc - .line_types - .iter() - .find(|lt| lt.name.eq_ignore_ascii_case(lt_name)) - .map(|lt| lt.name.clone()); - if let Some(m) = matched { - Some(m) - } else { - crate::io::linetypes::populate_document(doc); - Some( - doc.line_types - .iter() - .find(|lt| lt.name.eq_ignore_ascii_case(lt_name)) - .map(|lt| lt.name.clone()) - .unwrap_or_else(|| lt_name.clone()), - ) - } - } else { - None + let resolved_lt = match config.linetype { + Some(ref lt_name) => match resolve_linetype(self.document_mut(), lt_name) { + Some(name) => Some(name), + None => return false, + }, + None => None, }; let doc = self.document_mut(); @@ -397,6 +372,17 @@ impl<'a> HostSession<'a> { } } +/// The stored spelling of `name` in the drawing's linetype table, loading the +/// standard linetypes first when it is not there yet. `None` when the drawing +/// cannot supply it: a layer must not reference a linetype that does not exist. +fn resolve_linetype(doc: &mut acadrust::CadDocument, name: &str) -> Option { + let stored = |doc: &acadrust::CadDocument| doc.line_types.get(name).map(|lt| lt.name.clone()); + stored(doc).or_else(|| { + crate::io::linetypes::populate_document(doc); + stored(doc) + }) +} + /// The stable contract a plugin's `dispatch` sees. Each method forwards to the /// inherent `HostSession` method of the same name (inherent methods take /// resolution priority, so this is plain delegation, not recursion). The diff --git a/src/entities/shape.rs b/src/entities/shape.rs index 7b4b1b8f1..12cb0f4cc 100644 --- a/src/entities/shape.rs +++ b/src/entities/shape.rs @@ -119,7 +119,7 @@ fn shx_polylines( // glyph named like this shape. if !name.is_empty() { for style in document.text_styles.iter() { - if style.name.is_empty() && !style.font_file.trim().is_empty() { + if style.is_shape_file && !style.font_file.trim().is_empty() { if let Some(p) = try_style(style) { return Some(p); } diff --git a/src/io/mod.rs b/src/io/mod.rs index 7afc5868f..646c0d536 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -2368,21 +2368,13 @@ fn fix_viewport_status_flags(doc: &mut CadDocument) { } } -/// The acadrust DXF reader stores several rotation fields directly from DXF -/// group code 50 in degrees, while DWG and our own creation code store radians. -/// Apply to_radians() on load so tessellation can call cos/sin uniformly. +/// The acadrust DXF reader still stores Shape rotation directly from group +/// code 50 in degrees, while DWG and our own creation code store radians. +/// Dimension angles and ATTRIB/ATTDEF rotation are converted inside the +/// reader, so arms for them here would convert twice. fn fix_dxf_dimension_rotations(doc: &mut CadDocument) { for entity in doc.entities_mut() { match entity { - // Dimension angles (rotation / text / oblique) are converted - // degrees->radians inside the acadrust DXF reader now, so a - // dimension arm here would double-convert. - EntityType::AttributeDefinition(a) => { - a.rotation = a.rotation.to_radians(); - } - EntityType::AttributeEntity(a) => { - a.rotation = a.rotation.to_radians(); - } EntityType::Shape(s) => { s.rotation = s.rotation.to_radians(); }