mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-11 13:24:35 +00:00
fix(ui): bookmark_position keeps a sliver page when nothing else shows; the rail test checks the rail's real edges (#5636)
A page showing under a pixel at the window's top is ignored in favour of the next page, but still chosen when no other page shows. The rail test no longer tolerates 2 pt of overflow: it compares the page and zoom fields with the rail's own edges. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cab29b4f19
commit
461200e74a
2 files changed
+13
-7
No files matched your search
@@ -33,12 +33,16 @@ impl DocView {
|
||||
// nearest one below.
|
||||
let top = self.viewport_screen.top();
|
||||
// A page showing less than a pixel is rounding, not what the reader is looking at: a jump
|
||||
// to the next page leaves the previous one's bottom edge within a pixel of the top.
|
||||
let showing = || self.screen_xforms.iter().filter(|(_, xf)| xf.rect.bottom() > top + 1.0);
|
||||
let (page, xf) = showing()
|
||||
.filter(|(_, xf)| xf.rect.top() <= top)
|
||||
.min_by_key(|(p, _)| *p)
|
||||
.or_else(|| showing().min_by(|a, b| a.1.rect.top().total_cmp(&b.1.rect.top()).then(a.0.cmp(&b.0))))?;
|
||||
// to the next page leaves the previous one's bottom edge within a pixel of the top. Such a
|
||||
// sliver still counts when nothing else shows (the last page at the very end).
|
||||
let pick = |slack: f32| {
|
||||
let showing = || self.screen_xforms.iter().filter(move |(_, xf)| xf.rect.bottom() > top + slack);
|
||||
showing()
|
||||
.filter(|(_, xf)| xf.rect.top() <= top)
|
||||
.min_by_key(|(p, _)| *p)
|
||||
.or_else(|| showing().min_by(|a, b| a.1.rect.top().total_cmp(&b.1.rect.top()).then(a.0.cmp(&b.0))))
|
||||
};
|
||||
let (page, xf) = pick(1.0).or_else(|| pick(0.0))?;
|
||||
let p = info.pages.get(*page)?;
|
||||
// Above the page (in the gap before it) is the page's own top. The window's vertical is
|
||||
// the view's y, or its x when the view is turned a quarter.
|
||||
|
||||
@@ -1433,11 +1433,13 @@ fn typing_in_one_tab_never_reaches_another_tabs_added_text() {
|
||||
fn rail_page_and_zoom_fields_match_and_fit_the_rail() {
|
||||
let mut h = harness();
|
||||
h.run_steps(3);
|
||||
// The rail is 49 pt wide at the window's right edge (1400 pt wide), inside a 1 pt border.
|
||||
let (rail_left, rail_right) = (1400.0 - 49.0 + 1.0, 1400.0 - 1.0);
|
||||
let rail = h.get_by_label("Bookmarks").rect();
|
||||
let (page, zoom) = (h.get_by_label("Current page").rect(), h.get_by_label("Zoom").rect());
|
||||
assert_eq!((page.width(), page.height()), (zoom.width(), zoom.height()), "{page:?} vs {zoom:?}");
|
||||
for r in [page, zoom] {
|
||||
assert!(r.left() >= rail.left() - 2.0 && r.right() <= rail.right() + 2.0, "{r:?} is cut off by the rail ({rail:?})");
|
||||
assert!(r.left() >= rail_left && r.right() <= rail_right, "{r:?} is cut off by the rail ({rail_left}..{rail_right})");
|
||||
assert!((r.center().x - rail.center().x).abs() < 1.0, "{r:?} is off the rail's centre ({rail:?})");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user