fix(forms): comb detection ignores repeated boxes (#6077)

This commit is contained in:
Dylan M. Taylor authored and GitHub committed 2026-11-09 18:19:30 +08:00
1 parent 5f4003e562
commit f64c853a3a
1 file changed
+17
+17
View File
@@ -391,6 +391,8 @@ fn label_for(words: &[Word], rect: [f64; 4], right_of: bool) -> String {
/// enough: dates split into day and month groups of two cells. Cells are square or taller
/// than wide; an empty table of wider cells is not a comb.
fn combs(boxes: &[[f64; 4]]) -> Vec<([f64; 4], usize)> {
// A repeated box adds nothing to a row, but every repeat would be searched against every cell.
let mut seen = std::collections::HashSet::new();
let cells: Vec<[f64; 4]> = boxes
.iter()
.copied()
@@ -398,6 +400,7 @@ fn combs(boxes: &[[f64; 4]]) -> Vec<([f64; 4], usize)> {
let (w, h) = (r[2] - r[0], r[3] - r[1]);
(5.0..=30.0).contains(&w) && (8.0..=40.0).contains(&h) && w <= h * 1.2
})
.filter(|r| seen.insert(r.map(f64::to_bits)))
.collect();
// `b` comes right after `a` in a row: same size, its left edge on a's right edge.
let follows = |a: &[f64; 4], b: &[f64; 4]| {
@@ -521,3 +524,17 @@ pub fn detect(words: &[Word], shapes: &Shapes, existing: &[[f64; 4]], taken: &[S
}
out
}
#[cfg(test)]
mod comb_tests {
use super::combs;
#[test]
fn repeated_boxes_do_not_change_or_multiply_a_comb() {
let row = [[10.0, 10.0, 20.0, 22.0], [20.0, 10.0, 30.0, 22.0], [30.0, 10.0, 40.0, 22.0]];
let mut many = row.to_vec();
many.extend(std::iter::repeat_n(row[1], 5000));
assert_eq!(combs(&row), vec![([10.0, 10.0, 40.0, 22.0], 3)]);
assert_eq!(combs(&many), combs(&row));
}
}