feat(mline): render multilines from their MLINESTYLE + complex linetypes

Multilines were drawn with a fixed ±scale/2 two-line guess in the entity
colour, ignoring the MLINESTYLE entirely, so a drawing's custom style (per-
element offsets, colours and linetypes) was lost — a red/yellow multiline
rendered as a white box.

- mline.rs: resolve the MLINESTYLE (by style_handle, then name) and build one
  parallel line per element from its offset x scale + justification shift.
- tessellate.rs: special-case MLINE (like Leader) to emit one WireModel per
  element in the element's own colour, CPU-dashing every element through
  apply_along so the parallel lines stay in phase.
- linetypes.rs: render a drawing's OWN complex linetypes (embedded text/shape),
  document definition first and the bundled .lin catalog only as a fallback, so
  a file-defined text linetype like PLYN shows its text.
- Run the dash/glyph layout in a local frame (f64 origin subtracted, re-split to
  double-single after) so spacing stays precise at UTM coordinates, and pass
  tracking = 1.0 so embedded text keeps its letter spacing.

Cargo.lock pins acadrust to the MLINE->MLINESTYLE handle-link reader fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-07-16 18:44:15 +03:00
1 parent e85e2aeb78
commit 0e18b5bb33
6 files changed
+454 -75

No files matched your search

+2 -2
View File
@@ -682,12 +682,12 @@ pub(crate) fn tessellate_entity(
// linetype assigned, so we only consult the first wire here — multi-wire
// returns come exclusively from MTEXT colour splits which can't trigger
// this path.
if let Some(clt) = crate::io::linetypes::complex_lt(lt_name) {
if let Some(clt) = crate::io::linetypes::resolve_complex_lt(document, lt_name) {
if let Some(base) = bases.first() {
let mut wires = text::complex_lt::apply_along(
&base.name,
&base.points,
clt,
&clt,
(lt_scale * pslt_factor).max(1e-4),
entity_color,
sel,