Take two roundings out of where a box comes from
Traced what was left of the warm-against-cold difference after fixed point. It is not accumulation and not one place: it is the same box reached two ways, and each way rounds where the other does not. `Scroll` was writing a box it had been given back out as its own length in pixels. That is the same box in another form, and centring a part in `rel 1` lands a step from centring it in `px 900`, because halving a difference is not halving each part of it. Content that fills the viewport and has not been scrolled is now handed back as it came, which makes the shrinker's `repaint` and `resize-repaint` cases agree exactly rather than within a step. `Span` placed each child a step from where the last one ended, so the rounding of every share was carried along the row. A position is now the fixed parts before it -- a sum, exact -- plus one rounded share of the room. Measured: two hundred equal shares of a 1000 px row ended at 999.999 and now end at 1000, and `tests/cases/layout.rs` pins it at 2, 3, 7, 64 and 200. What is left is a step per level of nesting between the two ways, which is what the fuzzers now allow: four of the five shrinker cases pass at one step and the fifth is five spans deep. Closing it needs one way of asking where a box is, which is a bigger change than this. Checked: fmt, clippy, 103 tests, all five shrinker cases at 300 seeds, 100 generated seeds, five examples byte-identical at 1920x1200. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9d8415d65f
commit
bdab55824f
6 files changed
+90
-25
No files matched your search
@@ -285,6 +285,43 @@ fn an_uneven_nesting_still_gives_every_share_the_same_length() {
|
||||
}
|
||||
}
|
||||
|
||||
/// However many ways a row is divided, the shares add up to the row: each
|
||||
/// one is the fixed parts before it plus a share of the room, rather than a
|
||||
/// step from where the last one ended, so the roundings do not accumulate
|
||||
/// along it. Chained, two hundred of them ended a step short of the edge.
|
||||
#[test]
|
||||
fn a_row_of_equal_shares_fills_it_exactly() {
|
||||
for n in [2usize, 3, 7, 64, 200] {
|
||||
let mut h = Harness::new((1000, 100));
|
||||
let mut ids = Vec::new();
|
||||
let mut kids: Vec<StrongWidget> = Vec::new();
|
||||
for _ in 0..n {
|
||||
let kid = rect(Color::RED).add(&mut h.rsc);
|
||||
ids.push(kid.id());
|
||||
kids.push(kid.add_strong(&mut h.rsc));
|
||||
}
|
||||
let span = Span {
|
||||
children: kids,
|
||||
dir: Dir::RIGHT,
|
||||
gap: Px::ZERO,
|
||||
}
|
||||
.add(&mut h.rsc);
|
||||
h.set_root(span);
|
||||
h.frame();
|
||||
|
||||
for (i, id) in ids.iter().enumerate() {
|
||||
let at = h.region(id).expect("a share drew nothing").top_left.x;
|
||||
let want = Px::from_f32(1000.0 * (i as f32) / (n as f32));
|
||||
assert!(
|
||||
(at - want).abs() <= Px::STEP,
|
||||
"{n} shares: the {i}th starts at {at:?}, not {want:?}"
|
||||
);
|
||||
}
|
||||
let end = h.region(ids.last().unwrap()).unwrap().bot_right.x;
|
||||
assert_eq!(end, Px::from_int(1000), "{n} shares do not reach the edge");
|
||||
}
|
||||
}
|
||||
|
||||
/// Where the shader puts an edge: the two parts of a scalar are floored
|
||||
/// apart, so a fraction and a pixel offset snap independently, and each is
|
||||
/// taken to the boundary it composes to within half a step of. Kept in step
|
||||
|
||||
Reference in new issue
Block a user