From 9779f11f4801628b38d17fa78d638f6a75d6257d Mon Sep 17 00:00:00 2001 From: ulteq Date: Fri, 29 Dec 2017 21:27:21 +0100 Subject: Fix zoom ratio calculation This simplifies the logic behind the automatic zoom ratio calculation, which is used by both --auto-zoom and --scale-down. --- src/winwidget.c | 123 +++++++++----------------------------------------------- 1 file changed, 20 insertions(+), 103 deletions(-) (limited to 'src') diff --git a/src/winwidget.c b/src/winwidget.c index beae9fa..a8bcc0a 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -328,6 +328,7 @@ void winwidget_create_window(winwidget ret, int w, int h) opt.geom_h = h; opt.geom_flags |= WidthValue | HeightValue; } + return; } @@ -422,7 +423,6 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) int sx, sy, sw, sh, dx, dy, dw, dh; int calc_w, calc_h; int antialias = 0; - int need_center = winwid->had_resize; if (!winwid->full_screen && resize) { winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0); @@ -438,6 +438,9 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) D(("winwidget_render_image resize %d force_alias %d im %dx%d\n", resize, force_alias, winwid->im_w, winwid->im_h)); + /* winwidget_setup_pixmaps(winwid) resets the winwid->had_resize flag */ + int had_resize = winwid->had_resize || resize; + winwidget_setup_pixmaps(winwid); if (!winwid->full_screen && ((gib_imlib_image_has_alpha(winwid->im)) @@ -447,110 +450,19 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) || (winwid->has_rotated))) feh_draw_checks(winwid); - if (!winwid->full_screen && opt.zoom_mode && (winwid->type != WIN_TYPE_THUMBNAIL) - && (winwid->zoom == 1.0) && ! (opt.geom_flags & (WidthValue | HeightValue)) - && (winwid->w > winwid->im_w) && (winwid->h > winwid->im_h)) - feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h); + if (had_resize && !opt.keep_zoom_vp && (winwid->type != WIN_TYPE_THUMBNAIL)) { + double required_zoom = 1.0; + feh_calc_needed_zoom(&required_zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); - /* - * In case of a resize, the geomflags (and im_w, im_h) get updated by - * the ConfigureNotify handler. - */ - if (need_center && !winwid->full_screen && (winwid->type != WIN_TYPE_THUMBNAIL) - && (opt.geom_flags & (WidthValue | HeightValue)) - && ((winwid->w < winwid->im_w) || (winwid->h < winwid->im_h))) - feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h); + winwid->zoom = opt.default_zoom ? (0.01 * opt.default_zoom) : 1.0; + if ((opt.scale_down || (winwid->full_screen && !opt.default_zoom)) + && winwid->zoom > required_zoom) + winwid->zoom = required_zoom; + else if ((opt.zoom_mode && required_zoom > 1) + && (!opt.default_zoom || required_zoom < winwid->zoom)) + winwid->zoom = required_zoom; - if (resize && (winwid->type != WIN_TYPE_THUMBNAIL) && - (winwid->full_screen || (opt.geom_flags & (WidthValue | HeightValue)))) { - int smaller; /* Is the image smaller than screen? */ - int max_w = 0, max_h = 0; - - if (winwid->full_screen) { - max_w = scr->width; - max_h = scr->height; -#ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) { - max_w = xinerama_screens[xinerama_screen].width; - max_h = xinerama_screens[xinerama_screen].height; - } -#endif /* HAVE_LIBXINERAMA */ - } else { - if (opt.geom_flags & WidthValue) { - max_w = opt.geom_w; - } - if (opt.geom_flags & HeightValue) { - max_h = opt.geom_h; - } - } - - D(("Calculating for fullscreen/fixed geom render\n")); - smaller = ((winwid->im_w < max_w) - && (winwid->im_h < max_h)); - - if (!smaller || opt.zoom_mode) { - /* contributed by Jens Laas - * What it does: - * zooms images by a fixed amount but never larger than the screen. - * - * Why: - * This is nice if you got a collection of images where some - * are small and can stand a small zoom. Large images are unaffected. - * - * When does it work, and how? - * You have to be in fullscreen mode _and_ have auto-zoom turned on. - * "feh -FZ --zoom 130 imagefile" will do the trick. - * -zoom percent - the new switch. - * 100 = orignal size, - * 130 is 30% larger. - */ - if (opt.default_zoom) { - double old_zoom = winwid->zoom; - - winwid->zoom = 0.01 * opt.default_zoom; - if (opt.default_zoom != 100) { - if ((winwid->im_h * winwid->zoom) > max_h) - winwid->zoom = old_zoom; - else if ((winwid->im_w * winwid->zoom) > max_w) - winwid->zoom = old_zoom; - } - - winwid->im_x = ((int) - (max_w - (winwid->im_w * winwid->zoom))) >> 1; - winwid->im_y = ((int) - (max_h - (winwid->im_h * winwid->zoom))) >> 1; - } else { - /* Image is larger than the screen (so wants shrinking), or it's - smaller but wants expanding to fill it */ - double ratio = feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, max_w, max_h); - - if (ratio > 1.0) { - /* height is the factor */ - winwid->im_x = 0; - winwid->im_y = ((int) - (max_h - (winwid->im_h * winwid->zoom))) >> 1; - } else { - /* width is the factor */ - winwid->im_x = ((int) - (max_w - (winwid->im_w * winwid->zoom))) >> 1; - winwid->im_y = 0; - } - } - } else { - /* my modification to jens hack, allow --zoom without auto-zoom mode */ - if (opt.default_zoom) { - winwid->zoom = 0.01 * opt.default_zoom; - } else { - winwid->zoom = 1.0; - } - /* Just center the image in the window */ - winwid->im_x = (int) (max_w - (winwid->im_w * winwid->zoom)) >> 1; - winwid->im_y = (int) (max_h - (winwid->im_h * winwid->zoom)) >> 1; - } - } - else if (need_center && !winwid->full_screen - && (winwid->type != WIN_TYPE_THUMBNAIL) && !opt.keep_zoom_vp) { winwid->im_x = (int) (winwid->w - (winwid->im_w * winwid->zoom)) >> 1; winwid->im_y = (int) (winwid->h - (winwid->im_h * winwid->zoom)) >> 1; } @@ -564,7 +476,7 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) * solution considering a future refactoring of this function. */ - if (need_center || resize) { + if (had_resize) { if ((opt.offset_flags & XValue) && (winwid->im_w * winwid->zoom) > winwid->w) { if (opt.offset_flags & XNegative) { winwid->im_x = winwid->w - (winwid->im_w * winwid->zoom) - opt.offset_x; @@ -581,6 +493,11 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) } } + winwid->had_resize = 0; + + if (opt.keep_zoom_vp) + winwidget_sanitise_offsets(winwid); + /* Now we ensure only to render the area we're looking at */ dx = winwid->im_x; dy = winwid->im_y; -- cgit v1.2.3