diff --git a/game/src/debug/mod.rs b/game/src/debug/mod.rs index 8414d195e8..50b1399dd4 100644 --- a/game/src/debug/mod.rs +++ b/game/src/debug/mod.rs @@ -12,7 +12,7 @@ use map_model::{osm, ControlTrafficSignal, IntersectionID, NORMAL_LANE_THICKNESS use sim::Sim; use widgetry::{ lctrl, Btn, Cached, Checkbox, Choice, Color, DrawBaselayer, Drawable, EventCtx, GeomBatch, - GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, State, Text, UpdateType, + GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, ScreenDims, State, Text, UpdateType, VerticalAlignment, Widget, }; @@ -59,7 +59,7 @@ impl DebugMode { Checkbox::switch(ctx, "show route for all agents", Key::R, false), Widget::col(vec![ Btn::text_fg("unhide everything").build_def(ctx, lctrl(Key::H)), - Btn::text_fg("screenshot everything").build_def(ctx, None), + Btn::text_fg("screenshot everything (for leaflet)").build_def(ctx, None), Btn::text_fg("screenshot all of the everything").build_def(ctx, None), Btn::text_fg("search OSM metadata").build_def(ctx, Key::Slash), Btn::text_fg("clear OSM search results").build_def(ctx, lctrl(Key::Slash)), @@ -222,8 +222,8 @@ impl State for DebugMode { self.search_results = None; self.reset_info(ctx); } - "screenshot everything" => { - screenshot_everything(ctx, app); + "screenshot everything (for leaflet)" => { + screenshot_everything(ctx, app, ScreenDims::new(256.0, 256.0)); return Transition::Keep; } "screenshot all of the everything" => { @@ -784,7 +784,7 @@ impl State for ScreenshotTest { } } else { self.screenshot_done = true; - screenshot_everything(ctx, app); + screenshot_everything(ctx, app, ctx.canvas.get_window_dims()); // TODO Sometimes this still gets stuck and needs a mouse wiggle for input event? Transition::Keep } @@ -792,10 +792,11 @@ impl State for ScreenshotTest { fn draw(&self, _: &mut GfxCtx, _: &App) {} } -fn screenshot_everything(ctx: &mut EventCtx, app: &App) { +fn screenshot_everything(ctx: &mut EventCtx, app: &App, dims: ScreenDims) { let name = app.primary.map.get_name(); ctx.request_update(UpdateType::ScreenCaptureEverything { dir: format!("screenshots/{}/{}", name.city, name.map), zoom: 3.0, + dims, }); } diff --git a/widgetry/src/backend_glow.rs b/widgetry/src/backend_glow.rs index 560a82761f..125fa9bb4d 100644 --- a/widgetry/src/backend_glow.rs +++ b/widgetry/src/backend_glow.rs @@ -363,9 +363,9 @@ impl PrerenderInnards { self.window_adapter.draw_finished(gfc_ctx_innards) } - pub(crate) fn screencap(&self, canvas: &Canvas, filename: String) -> anyhow::Result<()> { - let width = canvas.window_width as u32; - let height = canvas.window_height as u32; + pub(crate) fn screencap(&self, dims: ScreenDims, filename: String) -> anyhow::Result<()> { + let width = dims.width as u32; + let height = dims.height as u32; let mut img = image::DynamicImage::new_rgba8(width, height); let pixels = img.as_mut_rgba8().unwrap(); diff --git a/widgetry/src/event_ctx.rs b/widgetry/src/event_ctx.rs index e95d38940c..ed063c09cd 100644 --- a/widgetry/src/event_ctx.rs +++ b/widgetry/src/event_ctx.rs @@ -15,7 +15,11 @@ pub enum UpdateType { InputOnly, Game, Pan, - ScreenCaptureEverything { dir: String, zoom: f64 }, + ScreenCaptureEverything { + dir: String, + zoom: f64, + dims: ScreenDims, + }, } pub struct EventCtx<'a> { diff --git a/widgetry/src/lib.rs b/widgetry/src/lib.rs index 6f6e593c63..dd073b1c97 100644 --- a/widgetry/src/lib.rs +++ b/widgetry/src/lib.rs @@ -25,6 +25,8 @@ //#![warn(missing_docs)] +#[macro_use] +extern crate anyhow; #[macro_use] extern crate log; diff --git a/widgetry/src/runner.rs b/widgetry/src/runner.rs index 0ca9b2dece..2aa39f5459 100644 --- a/widgetry/src/runner.rs +++ b/widgetry/src/runner.rs @@ -124,7 +124,7 @@ impl State { } } - // Returns naming hint. Logically consumes the number of uploads. + /// Returns naming hint. Logically consumes the number of uploads. pub(crate) fn draw(&mut self, prerender: &Prerender, screenshot: bool) -> Option { let mut g = GfxCtx::new(prerender, &self.canvas, &self.style, screenshot); @@ -358,8 +358,10 @@ pub fn run< running = true; } UpdateType::Pan => {} - UpdateType::ScreenCaptureEverything { dir, zoom } => { - if let Err(err) = screenshot_everything(&mut state, &dir, &prerender, zoom) { + UpdateType::ScreenCaptureEverything { dir, zoom, dims } => { + if let Err(err) = + screenshot_everything(&mut state, &dir, &prerender, zoom, dims) + { error!("Couldn't screenshot everything: {}", err); } } diff --git a/widgetry/src/tools/screenshot.rs b/widgetry/src/tools/screenshot.rs index 7771a5f9e7..0fb15673f7 100644 --- a/widgetry/src/tools/screenshot.rs +++ b/widgetry/src/tools/screenshot.rs @@ -1,7 +1,7 @@ use abstutil::Timer; use crate::runner::State; -use crate::{Prerender, SharedAppState}; +use crate::{Prerender, ScreenDims, SharedAppState}; /// Take a screenshot of the entire canvas, tiling it based on the window's width and height. pub(crate) fn screenshot_everything( @@ -9,10 +9,19 @@ pub(crate) fn screenshot_everything( dir_path: &str, prerender: &Prerender, zoom: f64, + dims: ScreenDims, ) -> anyhow::Result<()> { + if dims.width > state.canvas.window_width || dims.height > state.canvas.window_height { + bail!( + "Can't take screenshots of dims {:?} when the window is only {:?}", + dims, + state.canvas.get_window_dims() + ); + } + let mut timer = Timer::new("capturing screen"); - let num_tiles_x = (state.canvas.map_dims.0 * zoom / state.canvas.window_width).ceil() as usize; - let num_tiles_y = (state.canvas.map_dims.1 * zoom / state.canvas.window_height).ceil() as usize; + let num_tiles_x = (state.canvas.map_dims.0 * zoom / dims.width).ceil() as usize; + let num_tiles_y = (state.canvas.map_dims.1 * zoom / dims.height).ceil() as usize; let orig_zoom = state.canvas.cam_zoom; let orig_x = state.canvas.cam_x; let orig_y = state.canvas.cam_y; @@ -26,8 +35,8 @@ pub(crate) fn screenshot_everything( for tile_y in 0..num_tiles_y { for tile_x in 0..num_tiles_x { timer.next(); - state.canvas.cam_x = (tile_x as f64) * state.canvas.window_width; - state.canvas.cam_y = (tile_y as f64) * state.canvas.window_height; + state.canvas.cam_x = (tile_x as f64) * dims.width; + state.canvas.cam_y = (tile_y as f64) * dims.height; let suffix = state.draw(prerender, true).unwrap_or_else(String::new); let filename = format!( @@ -37,7 +46,7 @@ pub(crate) fn screenshot_everything( tile_y + 1, suffix ); - prerender.inner.screencap(&state.canvas, filename)?; + prerender.inner.screencap(dims, filename)?; } }