@@ -72,7 +72,7 @@ struct PageConstraints {
7272 r_to_l : bool
7373}
7474
75- #[ derive( Default , Debug ) ]
75+ #[ derive( Default , Debug , Clone , Copy ) ]
7676struct Zoom {
7777 // just how much 'zoom' you have. 0 means it fills the screen (instead of fits), such
7878 // that one axis is fully on-screen
@@ -86,7 +86,7 @@ struct Zoom {
8686}
8787impl Zoom {
8888 /// Returns the zoom factor, where 1 is the default and means fill-screen
89- fn factor ( & self ) -> f32 {
89+ fn factor ( self ) -> f32 {
9090 // TODO: Make these configurable once we have a good way to set options after startup
9191 const ZOOM_RATE : f32 = 1.1 ;
9292 const ZOOM_RATE_GRANULAR : f32 = 1.05 ;
@@ -274,17 +274,41 @@ impl Tui {
274274 / 2 ;
275275 } ;
276276
277- // TODO: Detect max zoom-out in zoom levels
278277 if img_page_w_ratio < img_page_h_ratio {
279- // vertical scroll / tall image. zooming out means decreasing the width of the page area
278+ // To detect if we're already at fit-screen, we perform a first
279+ // pass on `img_area` that emulates the last call to
280+ // `render_zoomed` by subtracting from the `zoom`'s level. This
281+ // holds because the `img_area` that gets passed is always the
282+ // same.
283+ let mut first_pass_area = img_area;
284+ let mut first_pass_zoom = * zoom;
285+ if first_pass_zoom. level . is_negative ( ) {
286+ first_pass_zoom. step_in ( ) ;
287+ }
288+ let first_pass_zoom_factor = first_pass_zoom. factor ( ) ;
289+ shrink_move_page (
290+ & mut first_pass_area. width ,
291+ & mut first_pass_area. x ,
292+ first_pass_zoom_factor. max ( 1.0 / img_page_h_ratio)
293+ ) ;
294+ log:: debug!( "first_pass_area: {first_pass_area:#?}" ) ;
295+ // vertical scroll / tall image. zooming out means decreasing
296+ // the width of the page area
280297 shrink_move_page (
281298 & mut img_area. width ,
282299 & mut img_area. x ,
283300 // disallow zooming out past fit-screen
284301 zoom_factor. max ( 1.0 / img_page_h_ratio)
285302 ) ;
303+ log:: debug!( "img_area: {img_area:#?}" ) ;
304+ // The moment the image area is left unmodified, we've hit
305+ // fit-screen and the zoom level ought be normalized.
306+ if first_pass_area == img_area {
307+ zoom. step_in ( ) ;
308+ }
286309 } else {
287- // horizontal scroll / wide image. zooming out means decreasing the width of the page area
310+ // horizontal scroll / wide image. zooming out means decreasing
311+ // the height of the page area
288312 shrink_move_page (
289313 & mut img_area. height ,
290314 & mut img_area. y ,
0 commit comments