Skip to content

Commit 06f737b

Browse files
authored
Prevent zoomout in both dimensions using double-pass system (#150)
1 parent 95c2420 commit 06f737b

1 file changed

Lines changed: 29 additions & 23 deletions

File tree

src/tui.rs

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ impl Tui {
262262
let img_page_w_ratio = img_section_w / initial_page_w;
263263
let img_page_h_ratio = img_section_h / initial_page_h;
264264

265-
let shrink_move_page = |dim: &mut u16, pos: &mut u16, axis_zoom_factor: f32| {
265+
fn shrink_move_page(dim: &mut u16, pos: &mut u16, axis_zoom_factor: f32) {
266266
let old_dim = *dim;
267267
// The axis zoom factor tells us what portion of the axis
268268
// we need to show.
@@ -272,50 +272,56 @@ impl Tui {
272272
.checked_sub(*dim)
273273
.expect("zooming out should shrink the image")
274274
/ 2;
275-
};
275+
}
276276

277-
if img_page_w_ratio < img_page_h_ratio {
277+
fn shrink_move_two_pass(
278+
zoom: &mut Zoom,
279+
dim: &mut u16,
280+
pos: &mut u16,
281+
zoom_factor: f32,
282+
axis_zoom_factor: f32
283+
) {
278284
// To detect if we're already at fit-screen, we perform a first
279285
// pass on `img_area` that emulates the last call to
280286
// `render_zoomed` by subtracting from the `zoom`'s level. This
281287
// holds because the `img_area` that gets passed is always the
282288
// same.
283-
let mut first_pass_area = img_area;
289+
let mut first_pass_dim = *dim;
290+
let mut first_pass_pos = *pos;
284291
let mut first_pass_zoom = *zoom;
292+
285293
if first_pass_zoom.level.is_negative() {
286294
first_pass_zoom.step_in();
287295
}
288296
let first_pass_zoom_factor = first_pass_zoom.factor();
289297
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)
298+
&mut first_pass_dim,
299+
&mut first_pass_pos,
300+
first_pass_zoom_factor.max(1.0 / axis_zoom_factor)
293301
);
294-
log::debug!("first_pass_area: {first_pass_area:#?}");
302+
303+
log::debug!("first_pass_dim: {first_pass_dim}, first_pass_pos: {first_pass_pos}");
295304
// vertical scroll / tall image. zooming out means decreasing
296305
// the width of the page area
297-
shrink_move_page(
298-
&mut img_area.width,
299-
&mut img_area.x,
300-
// disallow zooming out past fit-screen
301-
zoom_factor.max(1.0 / img_page_h_ratio)
302-
);
303-
log::debug!("img_area: {img_area:#?}");
306+
// use `max` to disallow zooming out past fit-screen
307+
shrink_move_page(dim, pos, zoom_factor.max(1.0 / axis_zoom_factor));
308+
309+
log::debug!("new dim: {dim}, new pos: {pos}");
304310
// The moment the image area is left unmodified, we've hit
305311
// fit-screen and the zoom level ought be normalized.
306-
if first_pass_area == img_area {
312+
if first_pass_dim == *dim && first_pass_pos == *pos {
307313
zoom.step_in();
308314
}
315+
}
316+
317+
let (dim, pos, axis_zoom_factor) = if img_page_w_ratio < img_page_h_ratio {
318+
(&mut img_area.width, &mut img_area.x, img_page_h_ratio)
309319
} else {
310320
// horizontal scroll / wide image. zooming out means decreasing
311321
// the height of the page area
312-
shrink_move_page(
313-
&mut img_area.height,
314-
&mut img_area.y,
315-
// disallow zooming out past fit-screen
316-
zoom_factor.max(1.0 / img_page_w_ratio)
317-
);
318-
}
322+
(&mut img_area.height, &mut img_area.y, img_page_w_ratio)
323+
};
324+
shrink_move_two_pass(zoom, dim, pos, zoom_factor, axis_zoom_factor);
319325
}
320326
log::debug!("after adjustment, page area is {img_area:#?}");
321327

0 commit comments

Comments
 (0)