Stop DIMTMOVE 2 text taking the DIMTAD 1 clearance twice (#2302)

Fixes #2222

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
NetterSilver
2026-10-29 21:31:13 -04:00
committed by GitHub
co-authored by Claude Opus 5.5 Brandon Thomas
parent 3243271d4e
commit 0d9e62bc9a
2 changed files with 33 additions and 6 deletions
+10 -6
View File
@@ -150,11 +150,13 @@ fn position_linear_text(config: &DimConfig<'_>, state: &mut LinearDimState) {
};
state.side_out = if (config.dimension.defpt.xy() - state.p1).dot(state.n) >= 0.0 { state.n } else { -state.n };
state.text_axis = Vec2::from_angle(state.angle);
let off_along = |axis: Vec2| {
let glyph_extent = state.text_width * state.text_axis.dot(axis).abs() / 2.0
+ state.text_height * state.text_axis.perp().dot(axis).abs() * if st.text_above == 1 { 0.6 } else { 0.5 };
config.gap + glyph_extent
let clearance = |axis: Vec2, across: f64| {
config.gap
+ state.text_width * state.text_axis.dot(axis).abs() / 2.0
+ state.text_height * state.text_axis.perp().dot(axis).abs() * across
};
// Empirical #2004 match: 0.595× height with SHX and 0.601× with TrueType.
let off_along = |axis: Vec2| clearance(axis, if st.text_above == 1 { 0.6 } else { 0.5 });
let above = if state.angle.abs() < 1e-12 && state.n.y.abs() > 1e-9 {
if state.n.y > 0.0 { state.n } else { -state.n }
} else if state.angle.abs() < 1e-12 {
@@ -181,11 +183,13 @@ fn position_linear_text(config: &DimConfig<'_>, state: &mut LinearDimState) {
+ outward * (config.gap + state.text_height / 2.0);
} else if state.moved {
let mid = state.f1.mid(state.f2);
let lift = off_along(state.side_out) + 2.0 * config.arrow_size.max(config.tick_size);
// Half the text height either way, whatever DIMTAD says (#2222).
let clear = clearance(state.side_out, 0.5);
let lift = clear + 2.0 * config.arrow_size.max(config.tick_size);
state.text_mid = if st.text_move == 1 {
mid + state.side_out * lift + state.u * state.half_extent
} else {
mid + state.side_out * (lift + off_along(state.side_out))
mid + state.side_out * (lift + clear)
};
} else if !config.dimension.user_text_pos {
state.text_mid = state.along_center + state.offset;
+23
View File
@@ -233,6 +233,29 @@ fn text_that_does_not_fit_follows_dimtmove_2() {
assert!(g.lines_of(LineRole::Dim).flatten().all(|p| p.x <= 0.5 + 1e-9 && p.y >= 5.0 - 1e-9), "no leader, no line out to the text");
}
#[test]
fn dimtmove_2_text_clearance_matches_autocad() {
// #2222: the 0.10 dimension of #1998 in the #2004 1:50 style. AutoCAD 2026 recomputes the
// moved text at about 0.358 from the dimension line (0.658214, 0.05).
let st = st_with(|s| {
s.scale = 50.0;
s.text_height = 0.0025;
s.text_gap = 0.0008;
s.arrow_size = 0.0015;
s.text_above = 1;
s.text_inside_horizontal = false;
s.text_outside_horizontal = false;
s.decimals = 2;
s.text_move = 2;
});
let d = lin((0.0, 0.0), (0.0, 0.10), (0.30, 0.0), std::f64::consts::FRAC_PI_2);
let g = dimension_geometry(&d, &st, 50.0);
assert!(g.text_pos.dist(Vec2::new(0.658214, 0.05)) < 0.005, "vertical: {:?}", g.text_pos);
let d = lin((0.0, 0.0), (0.10, 0.0), (0.0, -0.30), 0.0);
let g = dimension_geometry(&d, &st, 50.0);
assert!(g.text_pos.dist(Vec2::new(0.05, -0.658214)) < 0.005, "horizontal: {:?}", g.text_pos);
}
#[test]
fn text_that_does_not_fit_follows_dimtmove_1() {
// Moved off the line with a leader from the middle of the dimension line.