Use zoom steps instead of hard-coding levels (#92)

Co-authored-by: NRK <nrk@disroot.org>
Co-authored-by: Berke Kocaoğlu <berke.kocaoglu@metu.edu.tr>
This commit is contained in:
Lu Xu 2021-09-25 08:10:29 +03:00 committed by NRK
parent 696f68753f
commit a2339e70fd
4 changed files with 22 additions and 63 deletions

View file

@ -184,12 +184,8 @@ bool cg_zoom(arg_t d)
{ {
if (mode == MODE_THUMB) if (mode == MODE_THUMB)
return tns_zoom(&tns, d); return tns_zoom(&tns, d);
else if (d > 0)
return img_zoom_in(&img);
else if (d < 0)
return img_zoom_out(&img);
else else
return false; return img_zoom(&img, d);
} }
bool cg_toggle_image_mark(arg_t _) bool cg_toggle_image_mark(arg_t _)
@ -380,7 +376,7 @@ bool ci_drag(arg_t mode)
bool ci_set_zoom(arg_t zl) 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) bool ci_fit_to_win(arg_t sm)

View file

@ -25,13 +25,10 @@ static const suffixmode_t TITLE_SUFFIXMODE = SUFFIX_BASENAME;
#endif #endif
#ifdef _IMAGE_CONFIG #ifdef _IMAGE_CONFIG
/* levels (in percent) to use when zooming via '-' and '+': /* zoom level of 1.0 means 100% */
* (first/last value is used as min/max zoom level) static const float ZOOM_MIN = 0.01;
*/ static const float ZOOM_MAX = 20.0;
static const float zoom_levels[] = { static const float ZOOM_STEP = 1.2599210498948732; /* 2^(1/3) */
12.5, 25.0, 50.0, 75.0,
100.0, 150.0, 200.0, 400.0, 800.0
};
/* default slideshow delay (in sec, overwritten via -S option): */ /* default slideshow delay (in sec, overwritten via -S option): */
static const int SLIDESHOW_DELAY = 5; static const int SLIDESHOW_DELAY = 5;

56
image.c
View file

@ -42,19 +42,8 @@ enum { DEF_GIF_DELAY = 75 };
enum { DEF_WEBP_DELAY = 75 }; enum { DEF_WEBP_DELAY = 75 };
#endif #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) 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_display(win->env.dpy);
imlib_context_set_visual(win->env.vis); imlib_context_set_visual(win->env.vis);
imlib_context_set_colormap(win->env.cmap); imlib_context_set_colormap(win->env.cmap);
@ -63,8 +52,8 @@ void img_init(img_t *img, win_t *win)
img->win = win; img->win = win;
img->scalemode = options->scalemode; img->scalemode = options->scalemode;
img->zoom = options->zoom; img->zoom = options->zoom;
img->zoom = MAX(img->zoom, zoom_min); img->zoom = MAX(img->zoom, ZOOM_MIN);
img->zoom = MIN(img->zoom, zoom_max); img->zoom = MIN(img->zoom, ZOOM_MAX);
img->checkpan = false; img->checkpan = false;
img->dirty = false; img->dirty = false;
img->aa = ANTI_ALIAS; img->aa = ANTI_ALIAS;
@ -569,9 +558,9 @@ bool img_fit(img_t *img)
z = MIN(zw, zh); z = MIN(zw, zh);
break; 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->zoom = z;
img->dirty = true; img->dirty = true;
return 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); win_cursor_pos(img->win, &x, &y);
if (x < 0 || x >= img->win->w || y < 0 || y >= img->win->h) { if (x < 0 || x >= img->win->w || y < 0 || y >= img->win->h) {
x = img->win->w / 2; 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->x = x - (x - img->x) * z / img->zoom;
img->y = y - (y - img->y) * z / img->zoom; img->y = y - (y - img->y) * z / img->zoom;
img->zoom = z; img->zoom = z;
img->scalemode = SCALE_ZOOM;
img->checkpan = true; img->checkpan = true;
img->dirty = true; img->dirty = true;
return 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; const float z = img->zoom * (d > 0 ? ZOOM_STEP : 1/ZOOM_STEP);
float z; return img_zoom_to(img, 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;
} }
bool img_pos(img_t *img, float x, float y) bool img_pos(img_t *img, float x, float y)

View file

@ -39,6 +39,9 @@
#ifndef MAX #ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif #endif
#ifndef ABS
#define ABS(a) ((a) > 0 ? (a) : -(a))
#endif
#define ARRLEN(a) (sizeof(a) / sizeof((a)[0])) #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); CLEANUP void img_close(img_t*, bool);
void img_render(img_t*); void img_render(img_t*);
bool img_fit_win(img_t*, scalemode_t); bool img_fit_win(img_t*, scalemode_t);
bool img_zoom(img_t*, float); bool img_zoom(img_t*, int);
bool img_zoom_in(img_t*); bool img_zoom_to(img_t*, float);
bool img_zoom_out(img_t*);
bool img_pos(img_t*, float, float); bool img_pos(img_t*, float, float);
bool img_move(img_t*, float, float); bool img_move(img_t*, float, float);
bool img_pan(img_t*, direction_t, int); bool img_pan(img_t*, direction_t, int);