widgetry/tools/
screenshot.rs1use abstutil::Timer;
2
3use crate::runner::State;
4use crate::{Prerender, ScreenDims, SharedAppState};
5
6pub(crate) fn screenshot_everything<A: 'static + SharedAppState>(
8 state: &mut State<A>,
9 dir_path: &str,
10 prerender: &Prerender,
11 zoom: f64,
12 dims: ScreenDims,
13) -> anyhow::Result<()> {
14 if dims.width > state.canvas.window_width || dims.height > state.canvas.window_height {
15 bail!(
16 "Can't take screenshots of dims {:?} when the window is only {:?}",
17 dims,
18 state.canvas.get_window_dims()
19 );
20 }
21
22 let mut timer = Timer::new("capturing screen");
23 let num_tiles_x = (state.canvas.map_dims.0 * zoom / dims.width).ceil() as usize;
24 let num_tiles_y = (state.canvas.map_dims.1 * zoom / dims.height).ceil() as usize;
25 let orig_zoom = state.canvas.cam_zoom;
26 let orig_x = state.canvas.cam_x;
27 let orig_y = state.canvas.cam_y;
28
29 timer.start_iter("capturing images", num_tiles_x * num_tiles_y);
30 state.canvas.cam_zoom = zoom;
31 fs_err::create_dir_all(dir_path)?;
32
33 let free_memory_frequency = 10;
37 let mut cnt = 0;
38
39 for tile_y in 0..num_tiles_y {
40 for tile_x in 0..num_tiles_x {
41 timer.next();
42 state.canvas.cam_x = (tile_x as f64) * dims.width;
43 state.canvas.cam_y = (tile_y as f64) * dims.height;
44
45 cnt += 1;
46 if cnt % free_memory_frequency == 0 {
47 state.free_memory();
48 }
49
50 let suffix = state.draw(prerender, true).unwrap_or_else(String::new);
51
52 if tile_x == 0 && tile_y == 0 {
55 state.draw(prerender, true);
56 }
57
58 let filename = format!(
59 "{}/{:02}x{:02}{}.png",
60 dir_path,
61 tile_x + 1,
62 tile_y + 1,
63 suffix
64 );
65 prerender.inner.screencap(dims, filename.clone())?;
66 }
67 }
68
69 state.canvas.cam_zoom = orig_zoom;
70 state.canvas.cam_x = orig_x;
71 state.canvas.cam_y = orig_y;
72 Ok(())
73}