From a2339e70fdac1db7453cb008c4e37acdb5468f02 Mon Sep 17 00:00:00 2001 From: Lu Xu Date: Sat, 25 Sep 2021 08:10:29 +0300 Subject: [PATCH] Use zoom steps instead of hard-coding levels (#92) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: NRK Co-authored-by: Berke Kocaoğlu --- commands.c | 8 ++------ config.def.h | 11 ++++------ image.c | 58 ++++++++++------------------------------------------ nsxiv.h | 8 +++++--- 4 files changed, 22 insertions(+), 63 deletions(-) diff --git a/commands.c b/commands.c index 15859fa..42e78da 100644 --- a/commands.c +++ b/commands.c @@ -184,12 +184,8 @@ bool cg_zoom(arg_t d) { if (mode == MODE_THUMB) return tns_zoom(&tns, d); - else if (d > 0) - return img_zoom_in(&img); - else if (d < 0) - return img_zoom_out(&img); else - return false; + return img_zoom(&img, d); } bool cg_toggle_image_mark(arg_t _) @@ -380,7 +376,7 @@ bool ci_drag(arg_t mode) bool ci_set_zoom(arg_t zl) { - return img_zoom(&img, (prefix ? prefix : zl) / 100.0); + return img_zoom_to(&img, (prefix ? prefix : zl) / 100.0); } bool ci_fit_to_win(arg_t sm) diff --git a/config.def.h b/config.def.h index 0645b2b..19ea7bb 100644 --- a/config.def.h +++ b/config.def.h @@ -25,13 +25,10 @@ static const suffixmode_t TITLE_SUFFIXMODE = SUFFIX_BASENAME; #endif #ifdef _IMAGE_CONFIG -/* levels (in percent) to use when zooming via '-' and '+': - * (first/last value is used as min/max zoom level) - */ -static const float zoom_levels[] = { - 12.5, 25.0, 50.0, 75.0, - 100.0, 150.0, 200.0, 400.0, 800.0 -}; +/* zoom level of 1.0 means 100% */ +static const float ZOOM_MIN = 0.01; +static const float ZOOM_MAX = 20.0; +static const float ZOOM_STEP = 1.2599210498948732; /* 2^(1/3) */ /* default slideshow delay (in sec, overwritten via -S option): */ static const int SLIDESHOW_DELAY = 5; diff --git a/image.c b/image.c index 5e778d4..4fd1c36 100644 --- a/image.c +++ b/image.c @@ -42,19 +42,8 @@ enum { DEF_GIF_DELAY = 75 }; enum { DEF_WEBP_DELAY = 75 }; #endif -float zoom_min; -float zoom_max; - -static int zoomdiff(img_t *img, float z) -{ - return (int) ((img->w * z - img->w * img->zoom) + (img->h * z - img->h * img->zoom)); -} - void img_init(img_t *img, win_t *win) { - zoom_min = zoom_levels[0] / 100.0; - zoom_max = zoom_levels[ARRLEN(zoom_levels) - 1] / 100.0; - imlib_context_set_display(win->env.dpy); imlib_context_set_visual(win->env.vis); imlib_context_set_colormap(win->env.cmap); @@ -63,8 +52,8 @@ void img_init(img_t *img, win_t *win) img->win = win; img->scalemode = options->scalemode; img->zoom = options->zoom; - img->zoom = MAX(img->zoom, zoom_min); - img->zoom = MIN(img->zoom, zoom_max); + img->zoom = MAX(img->zoom, ZOOM_MIN); + img->zoom = MIN(img->zoom, ZOOM_MAX); img->checkpan = false; img->dirty = false; img->aa = ANTI_ALIAS; @@ -569,9 +558,9 @@ bool img_fit(img_t *img) z = MIN(zw, zh); break; } - z = MIN(z, img->scalemode == SCALE_DOWN ? 1.0 : zoom_max); + z = MIN(z, img->scalemode == SCALE_DOWN ? 1.0 : ZOOM_MAX); - if (zoomdiff(img, z) != 0) { + if (ABS(img->zoom - z) > 1.0/MAX(img->w, img->h)) { img->zoom = z; img->dirty = true; return true; @@ -687,16 +676,10 @@ bool img_fit_win(img_t *img, scalemode_t sm) } } -bool img_zoom(img_t *img, float z) +bool img_zoom_to(img_t *img, float z) { - z = MAX(z, zoom_min); - z = MIN(z, zoom_max); - - img->scalemode = SCALE_ZOOM; - - if (zoomdiff(img, z) != 0) { - int x, y; - + int x, y; + if (ZOOM_MIN <= z && z <= ZOOM_MAX) { win_cursor_pos(img->win, &x, &y); if (x < 0 || x >= img->win->w || y < 0 || y >= img->win->h) { x = img->win->w / 2; @@ -705,6 +688,7 @@ bool img_zoom(img_t *img, float z) img->x = x - (x - img->x) * z / img->zoom; img->y = y - (y - img->y) * z / img->zoom; img->zoom = z; + img->scalemode = SCALE_ZOOM; img->checkpan = true; img->dirty = true; return true; @@ -713,30 +697,10 @@ bool img_zoom(img_t *img, float z) } } -bool img_zoom_in(img_t *img) +bool img_zoom(img_t *img, int d) { - int i; - float z; - - for (i = 0; i < ARRLEN(zoom_levels); i++) { - z = zoom_levels[i] / 100.0; - if (zoomdiff(img, z) > 0) - return img_zoom(img, z); - } - return false; -} - -bool img_zoom_out(img_t *img) -{ - int i; - float z; - - for (i = ARRLEN(zoom_levels) - 1; i >= 0; i--) { - z = zoom_levels[i] / 100.0; - if (zoomdiff(img, z) < 0) - return img_zoom(img, z); - } - return false; + const float z = img->zoom * (d > 0 ? ZOOM_STEP : 1/ZOOM_STEP); + return img_zoom_to(img, z); } bool img_pos(img_t *img, float x, float y) diff --git a/nsxiv.h b/nsxiv.h index be7ffe6..c148b24 100644 --- a/nsxiv.h +++ b/nsxiv.h @@ -39,6 +39,9 @@ #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif +#ifndef ABS +#define ABS(a) ((a) > 0 ? (a) : -(a)) +#endif #define ARRLEN(a) (sizeof(a) / sizeof((a)[0])) @@ -246,9 +249,8 @@ bool img_load(img_t*, const fileinfo_t*); CLEANUP void img_close(img_t*, bool); void img_render(img_t*); bool img_fit_win(img_t*, scalemode_t); -bool img_zoom(img_t*, float); -bool img_zoom_in(img_t*); -bool img_zoom_out(img_t*); +bool img_zoom(img_t*, int); +bool img_zoom_to(img_t*, float); bool img_pos(img_t*, float, float); bool img_move(img_t*, float, float); bool img_pan(img_t*, direction_t, int);