mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-26 11:56:50 -06:00
* Build: line tables only in dev, no debug info for dependencies * Tests: one integration-test binary per crate Each crate's tests/*.rs becomes a module of tests/it/main.rs. Files that install process-wide state (the file io hooks, user aliases, SAVETIME and SAVEFILEPATH, user linetype and pattern files, registered fonts) stay their own test binaries. * xtask ci: nextest, tests without examples, one wasm check call
80 lines
2.6 KiB
Rust
80 lines
2.6 KiB
Rust
//! An R2018+ MTEXT can carry an embedded object (group 101) that repeats its geometry with
|
|
//! other meanings: there, 10 is the X-axis direction and 11 the insertion point. AutoCAD writes
|
|
//! one for MTEXT with column settings, and the DWG bridge does too. Reading 11 from it as the
|
|
//! direction turned the text towards its own insertion point (#667).
|
|
|
|
use cadcraft_doc::{Common, Drawing, EntityKind, MText, Space};
|
|
use cadcraft_geom::Vec3;
|
|
use cadcraft_io::{read_dxf, write_dxf};
|
|
|
|
/// An MTEXT at (30, 17) with `rotation`, written by CADCraft, then given an embedded object
|
|
/// as AutoCAD writes it: direction `dir` in 10/20/30 and the insertion point in 11/21/31.
|
|
fn with_embedded_object(rotation: f64, dir: (f64, f64)) -> String {
|
|
let mut d = Drawing::new_metric();
|
|
let t = MText {
|
|
insert: Vec3::new(30.0, 17.0, 0.0),
|
|
height: 0.5,
|
|
width: 6.0,
|
|
attach: 1,
|
|
rotation,
|
|
style: "Standard".into(),
|
|
contents: "Core Layer\\PThickness 1mm".into(),
|
|
line_spacing: 1.0,
|
|
line_spacing_exact: false,
|
|
columns: None,
|
|
};
|
|
d.add(&Space::Model, Common::default(), EntityKind::MText(t)).unwrap();
|
|
let dxf = write_dxf(&d);
|
|
let (dx, dy) = (dir.0.to_string(), dir.1.to_string());
|
|
let groups = [
|
|
(101, "Embedded Object"),
|
|
(70, "1"),
|
|
(10, &dx),
|
|
(20, &dy),
|
|
(30, "0.0"),
|
|
(11, "30.0"),
|
|
(21, "17.0"),
|
|
(31, "0.0"),
|
|
(40, "6.0"),
|
|
(41, "0.0"),
|
|
(42, "5.0"),
|
|
(43, "1.0"),
|
|
(71, "2"),
|
|
(72, "1"),
|
|
(44, "6.0"),
|
|
(45, "0.5"),
|
|
(73, "0"),
|
|
(74, "0"),
|
|
(46, "0.0"),
|
|
];
|
|
let embedded: String = groups.iter().map(|(code, value)| format!("{code:>3}\r\n{value}\r\n")).collect();
|
|
let start = dxf.find("AcDbMText").unwrap();
|
|
let end = start + dxf[start..].find("\r\n 0\r\n").unwrap() + 2;
|
|
format!("{}{embedded}{}", &dxf[..end], &dxf[end..])
|
|
}
|
|
|
|
fn read_rotation(dxf: &str) -> f64 {
|
|
let back = read_dxf(dxf.as_bytes()).unwrap();
|
|
match back.model.iter().find_map(|e| match &e.kind {
|
|
EntityKind::MText(t) => Some(t.rotation),
|
|
_ => None,
|
|
}) {
|
|
Some(r) => r,
|
|
None => panic!("no mtext"),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn embedded_object_insertion_point_is_not_the_direction() {
|
|
let dxf = with_embedded_object(0.0, (1.0, 0.0));
|
|
assert!(dxf.contains("Embedded Object"));
|
|
assert_eq!(read_rotation(&dxf), 0.0);
|
|
}
|
|
|
|
#[test]
|
|
fn rotated_mtext_keeps_its_rotation_with_an_embedded_object() {
|
|
let r = 0.5_f64;
|
|
let dxf = with_embedded_object(r, (r.cos(), r.sin()));
|
|
assert!((read_rotation(&dxf) - r).abs() < 1e-9);
|
|
}
|