Files
cadcraft/crates/io/tests/it/text_left_justify.rs
aiongg 9cf115e808 CI: one test binary per crate, nextest, line tables only (#1989)
* 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
2026-10-23 13:34:26 -04:00

47 lines
2.5 KiB
Rust

//! Left-justified TEXT with a vertical alignment (TL, ML, BL) is placed by its alignment point
//! (DXF group 11), like every justification but baseline-left; group 10 is then a computed point
//! on the baseline (#342).
use cadcraft_doc::{EntityKind, Space, entity_bounds};
/// One TEXT, height 1, "AB", group 72 = 0 and group 73 = `v`, with group 10 at `p10`, group 11 at
/// `p11`, and `extra` group codes.
fn dxf(v: i32, p10: (f64, f64), p11: (f64, f64), extra: &str) -> String {
format!(
"0\nSECTION\n2\nENTITIES\n0\nTEXT\n8\n0\n10\n{}\n20\n{}\n40\n1\n1\nAB\n72\n0\n11\n{}\n21\n{}\n{extra}73\n{v}\n0\nENDSEC\n0\nEOF\n",
p10.0, p10.1, p11.0, p11.1
)
}
/// (rendered box, extents box) of the drawing's only object, as (min x, min y, max x, max y).
fn boxes(text: &str) -> ([f64; 4], [f64; 4]) {
let d = cadcraft_io::read(text.as_bytes(), "t.dxf").unwrap();
let r = cadcraft_render::build(&d, &Space::Model, &cadcraft_render::Options::default()).bounds;
let e = d.model.iter().find(|e| matches!(e.kind, EntityKind::Text(_))).map(|e| entity_bounds(&d, e, 0)).unwrap();
([r.min.x, r.min.y, r.max.x, r.max.y], [e.min.x, e.min.y, e.max.x, e.max.y])
}
fn near(a: f64, b: f64) -> bool {
(a - b).abs() < 1e-6
}
#[test]
fn left_justified_text_is_placed_by_its_alignment_point() {
// TL: the top-left of the text at the alignment point 0,0; the baseline one height lower.
let (r, e) = boxes(&dxf(3, (0.0, -1.0), (0.0, 0.0), ""));
assert!(near(r[0], 0.0) && near(r[3], 0.0), "TL drawn at {r:?}");
assert!(near(e[0], 0.0) && near(e[3], 0.0) && near(e[1], -1.0), "TL extents {e:?}");
// ML: the middle of the text height at the alignment point.
let (r, e) = boxes(&dxf(2, (0.0, -0.5), (0.0, 0.0), ""));
assert!(near(r[3], 0.5) && near(e[3], 0.5) && near(e[1], -0.5), "ML drawn at {r:?}, extents {e:?}");
// BL: the descender line at the alignment point, so the baseline ("AB" has no descenders) a
// third of the height above it.
let (r, e) = boxes(&dxf(1, (0.0, 1.0 / 3.0), (0.0, 0.0), ""));
assert!(near(r[1], 1.0 / 3.0) && near(e[1], 1.0 / 3.0) && near(e[3], 4.0 / 3.0), "BL drawn at {r:?}, extents {e:?}");
// Mirrored (extrusion 0,0,-1): the OCS points (-10,4) and (-10,5) are WCS (10,4) and (10,5);
// drawn readable, the text runs left from its alignment point with its top there.
let (r, _) = boxes(&dxf(3, (-10.0, 4.0), (-10.0, 5.0), "210\n0\n220\n0\n230\n-1\n"));
assert!(near(r[2], 10.0) && near(r[3], 5.0), "mirrored TL drawn at {r:?}");
}