address review: skip the tab-stop lookup for a NaN position

This commit is contained in:
Dylan M. Taylor
2026-11-03 21:53:42 +00:00
parent 99d8a31a84
commit 8d41ee15a2
+14 -1
View File
@@ -307,7 +307,8 @@ pub(crate) fn tab_segment(cells: &[Cell], i: usize) -> (f64, f64) {
/// moving back, as PowerPoint does; past the last stop, to the next default stop.
pub(crate) fn tab_advance(x: f64, stops: &[Tab], default_tab: f64, seg: (f64, f64)) -> f64 {
// `stops` is in position order (`tabs_of`): the next stop is the first past x.
if let Some(s) = stops.get(stops.partition_point(|s| s.pos <= x + 0.5)) {
// A NaN `x` (a NaN spacing upstream) skips the lookup and takes the finite default-stop path.
if let Some(s) = stops.get(stops.partition_point(|s| s.pos <= x + 0.5)).filter(|_| !x.is_nan()) {
let to = s.pos - x;
return match s.align {
TabAlign::Left => to,
@@ -320,3 +321,15 @@ pub(crate) fn tab_advance(x: f64, stops: &[Tab], default_tab: f64, seg: (f64, f6
let next = ((x / d).floor() + 1.0) * d;
(next - x).max(1.0)
}
#[cfg(test)]
mod tab_tests {
use super::*;
#[test]
fn a_nan_position_takes_the_finite_default_stop() {
let stops = [Tab { pos: 100.0, align: TabAlign::Left }];
assert!(tab_advance(f64::NAN, &stops, 72.0, (0.0, 0.0)).is_finite());
assert_eq!(tab_advance(10.0, &stops, 72.0, (0.0, 0.0)), 90.0);
}
}