M3: a snapshot uses the scale the page is drawn at (#5716)

Review of #5761: the scale came from zoom × device pixels, without the
96/72 the viewer draws at, and was capped at 8, so a snapshot zoomed in
held fewer pixels than the screen showed: 417 against 534 for 100 pt at
400%. It now takes the viewer's own render scale, and the tile limit is
what stops it. The roadmap entry says when 300 ppi can't be reached.
This commit is contained in:
Hasan
2026-11-05 19:21:03 +05:00
parent 280584cc72
commit 7380241724
3 changed files with 11 additions and 7 deletions
+1 -1
View File
@@ -243,7 +243,7 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md
- **2026-11-02 (M10, #5743):** macOS print jobs name their title and owner (`com.apple.print.JobInfo.PMJobName`, `PMJobOwner`), as the system print dialog does, because a Kyocera filter crashes on a job without them. Checked by a test and through `doc_print` against a stand-in `lp`; not yet on a physical printer.
- **2026-11-02 (M3, #5716):** A snapshot is drawn at 300 ppi, or at the zoom if that is finer, so one taken zoomed out stays readable. A choice of resolution and a selection that stays active remain.
- **2026-11-02 (M3, #5716):** A snapshot is drawn at 300 ppi, or at the zoom if that is finer, so one taken zoomed out stays readable; an area too large for one 4096-pixel tile comes out as fine as a tile allows (about 147 ppi for 2000 pt). A choice of resolution and a selection that stays active remain.
- **2026-11-02 (M14, #5737, #5460):** Preferences can turn off the update check at start. It stays on by default, and Help ▸ Check for updates still asks.
- **2026-11-01 (M7, #5657):** Header/footer, watermark and background additions and replacements stage the complete call before committing. Synthetic later-page failures preserve exact incremental bytes, object count, dirty state and allocation cursor; success controls retain other marks and shared/inherited resources. Estimates unchanged.
+1 -1
View File
@@ -126,7 +126,7 @@ impl PdfCraftApp {
let view = &self.views[index];
let doc = self.session.get(view.id).ok_or("no document")?;
let ppp = self.ctx.as_ref().map_or(2.0, |c| c.pixels_per_point());
let scale = snapshot_scale((view.zoom * ppp).clamp(0.5, 8.0), view_rect[2] - view_rect[0], view_rect[3] - view_rect[1]);
let scale = snapshot_scale(view.render_scale(ppp), view_rect[2] - view_rect[0], view_rect[3] - view_rect[1]);
let tile = Tile {
x: (view_rect[0] * scale).floor().max(0.0) as u32,
y: (view_rect[1] * scale).floor().max(0.0) as u32,
+9 -5
View File
@@ -986,11 +986,15 @@ fn a_snapshot_keeps_its_resolution_when_zoomed_out() {
let (_, _, px) = h.state().last_snapshot.clone().expect("a snapshot");
assert!(px.as_chunks::<4>().0.iter().any(|p| p[0] < 100), "the text is in it");
// Zoomed in past the minimum, a snapshot still has what the screen shows.
h.state_mut().set_option("zoom", "800").unwrap();
h.run_steps(2);
let (w, _) = h.state_mut().snapshot(i, 0, [15.0, 125.0, 180.0, 160.0]).expect("a snapshot");
assert!(w > sizes[0].0, "{w}");
// Zoomed in past the minimum, a snapshot has every pixel the screen shows, however far.
let ppp = h.ctx.pixels_per_point();
for zoom in [400.0_f32, 1600.0] {
h.state_mut().set_option("zoom", &zoom.to_string()).unwrap();
h.run_steps(2);
let (w, _) = h.state_mut().snapshot(i, 0, [15.0, 125.0, 180.0, 160.0]).expect("a snapshot");
let on_screen = (165.0 * zoom / 100.0 * pdfcraft_ui_egui::canvas::PT * ppp).ceil() as u32;
assert!(w.abs_diff(on_screen) <= 1, "{w} pixels at {zoom}%, {on_screen} on screen");
}
}
/// #5716: at 300 ppi this page is more than the renderer draws in one tile, which would cut off