mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-24 10:56:51 -06:00
Dimensions: text that does not fit follows DIMTMOVE, over the dimension line (with a leader for 1) instead of past the second extension line (#2015)
* Dimensions: text that does not fit follows DIMTMOVE, over the dimension line (with a leader for 1) instead of past the second extension line (fixes #1998) * Dimensions: tighter check that the line is not carried out to moved text; drop a guard that never changed the outcome (#1998)
This commit is contained in:
@@ -623,6 +623,8 @@ pub fn dimension_geometry_with(d: &Dimension, st: &DimStyle, dimscale: f64, font
|
||||
let text_outside = !text_in;
|
||||
text_angle = if text_outside { if st.text_outside_horizontal { 0.0 } else { along_ang } } else { inside_ang };
|
||||
let half = extent(text_angle);
|
||||
// DIMTMOVE 1 / 2: text that doesn't fit is moved off the dimension line, which stays put.
|
||||
let moved = text_outside && st.text_move != 0;
|
||||
// DIMSOXD: arrowheads that don't fit inside are left out.
|
||||
let outside_arrows = !arrows_inside && !st.suppress_outside_arrows;
|
||||
// Text centre along the dimension line.
|
||||
@@ -662,6 +664,12 @@ pub fn dimension_geometry_with(d: &Dimension, st: &DimStyle, dimscale: f64, font
|
||||
text_angle = readable(e.angle());
|
||||
let outward = if just == 3 { -u } else { u };
|
||||
text_mid = f + e * (st.ext_extend * k + gap + tw / 2.0) + outward * (gap + tht / 2.0);
|
||||
} else if moved {
|
||||
// Over the middle of the line, clear of the arrowheads, on the side away from the
|
||||
// measured points; with DIMTMOVE 1 it starts there and a leader joins it.
|
||||
let mid = f1.mid(f2);
|
||||
let lift = off_along(side_out) + 2.0 * asz.max(tsz);
|
||||
text_mid = if st.text_move == 1 { mid + side_out * lift + u * half } else { mid + side_out * (lift + off_along(side_out)) };
|
||||
} else if !d.user_text_pos {
|
||||
text_mid = along_c + offset;
|
||||
}
|
||||
@@ -722,7 +730,7 @@ pub fn dimension_geometry_with(d: &Dimension, st: &DimStyle, dimscale: f64, font
|
||||
to_text(&mut g, if outside_arrows { f2 + u * stub } else { f2 });
|
||||
}
|
||||
// DIMTMOVE 1: a leader from the dimension line to text moved off it.
|
||||
if d.user_text_pos && st.text_move == 1 && has_text {
|
||||
if (d.user_text_pos || moved) && st.text_move == 1 && has_text {
|
||||
let base = f1.mid(f2);
|
||||
let off = (text_mid - base).dot(n).abs();
|
||||
if off > tht / 2.0 + gap + 1e-9 {
|
||||
@@ -1211,6 +1219,37 @@ mod tests {
|
||||
assert!(g.text_pos.x > 0.5, "text beyond the second extension line: {}", g.text_pos.x);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn text_that_does_not_fit_follows_dimtmove_2() {
|
||||
// Vertical, measured points left of the line: the text goes over the middle of the
|
||||
// line, on the side away from them, and the line is not carried out to it.
|
||||
let d = lin((0.0, 0.0), (0.0, 0.5), (5.0, 0.0), std::f64::consts::FRAC_PI_2);
|
||||
let g = dimension_geometry(&d, &st_with(|s| s.text_move = 2), 1.0);
|
||||
assert!((g.text_pos.y - 0.25).abs() < 1e-9 && g.text_pos.x > 5.2, "{:?}", g.text_pos);
|
||||
assert!(g.lines_of(LineRole::Dim).flatten().all(|p| p.y <= 0.5 + 1e-9 && p.x <= 5.0 + 1e-9), "no leader, no line out to the text");
|
||||
// Horizontal, measured points above the line: below it.
|
||||
let d = lin((0.0, 10.0), (0.5, 10.0), (0.0, 5.0), 0.0);
|
||||
let g = dimension_geometry(&d, &st_with(|s| s.text_move = 2), 1.0);
|
||||
assert!((g.text_pos.x - 0.25).abs() < 1e-9 && g.text_pos.y < 4.8, "{:?}", g.text_pos);
|
||||
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 text_that_does_not_fit_follows_dimtmove_1() {
|
||||
// Moved off the line with a leader from the middle of the dimension line.
|
||||
let d = lin((0.0, 0.0), (0.5, 0.0), (0.0, 5.0), 0.0);
|
||||
let g = dimension_geometry(&d, &st_with(|s| s.text_move = 1), 1.0);
|
||||
assert!(g.text_pos.y > 5.2, "{:?}", g.text_pos);
|
||||
let mid = Vec2::new(0.25, 5.0);
|
||||
assert!(g.lines_of(LineRole::Dim).any(|l| l.len() == 2 && l[0].dist(mid) < 1e-9 && l[1].y > 5.1), "leader");
|
||||
// Text placed with DIMTEDIT stays where it is.
|
||||
let mut placed = d.clone();
|
||||
placed.user_text_pos = true;
|
||||
placed.text_mid = Vec3::new(3.0, 7.0, 0.0);
|
||||
let g = dimension_geometry(&placed, &st_with(|s| s.text_move = 1), 1.0);
|
||||
assert!(g.text_pos.dist(Vec2::new(3.0, 7.0)) < 1e-9, "{:?}", g.text_pos);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tolerance_and_limits() {
|
||||
let d = lin((0.0, 0.0), (10.0, 0.0), (0.0, 5.0), 0.0);
|
||||
|
||||
Reference in New Issue
Block a user