@@ -40,6 +40,8 @@ fehkey *feh_str_to_kb(char *action);
4040
4141feh_event_handler * ev_handler [LASTEvent ];
4242
43+ static const double zoom_rate = M_LN2 / 128.0 ;
44+
4345static void feh_event_handle_ButtonPress (XEvent * ev );
4446static void feh_event_handle_ButtonRelease (XEvent * ev );
4547static void feh_event_handle_LeaveNotify (XEvent * ev );
@@ -242,29 +244,31 @@ static void feh_event_handle_ButtonPress(XEvent * ev)
242244 D (("click offset is %d,%d\n" , ev -> xbutton .x , ev -> xbutton .y ));
243245 winwid -> click_offset_x = ev -> xbutton .x ;
244246 winwid -> click_offset_y = ev -> xbutton .y ;
245- winwid -> old_zoom = winwid -> zoom ;
247+ winwid -> old_step = round ( log ( winwid -> zoom ) / zoom_rate ) ;
246248
247249 /* required to adjust the image position in zoom mode */
248250 winwid -> im_click_offset_x = (winwid -> click_offset_x
249- - winwid -> im_x ) / winwid -> old_zoom ;
251+ - winwid -> im_x ) / winwid -> zoom ;
250252 winwid -> im_click_offset_y = (winwid -> click_offset_y
251- - winwid -> im_y ) / winwid -> old_zoom ;
253+ - winwid -> im_y ) / winwid -> zoom ;
252254
253255 } else if (feh_is_bb (EVENT_zoom_in , button , state )) {
254256 D (("Zoom_In Button Press event\n" ));
255257 D (("click offset is %d,%d\n" , ev -> xbutton .x , ev -> xbutton .y ));
258+ if (winwid -> zoom >= ZOOM_MAX || opt .step_rate <= 0 )
259+ return ;
260+
256261 winwid -> click_offset_x = ev -> xbutton .x ;
257262 winwid -> click_offset_y = ev -> xbutton .y ;
258- winwid -> old_zoom = winwid -> zoom ;
259263
260264 /* required to adjust the image position in zoom mode */
261265 winwid -> im_click_offset_x = (winwid -> click_offset_x
262- - winwid -> im_x ) / winwid -> old_zoom ;
266+ - winwid -> im_x ) / winwid -> zoom ;
263267 winwid -> im_click_offset_y = (winwid -> click_offset_y
264- - winwid -> im_y ) / winwid -> old_zoom ;
268+ - winwid -> im_y ) / winwid -> zoom ;
265269
266270 /* copied from zoom_in, keyevents.c */
267- winwid -> zoom = winwid -> zoom * opt .zoom_rate ;
271+ winwid -> zoom = exp ( ++ winwid -> zoom_step * opt .step_rate ) ;
268272
269273 if (winwid -> zoom > ZOOM_MAX )
270274 winwid -> zoom = ZOOM_MAX ;
@@ -281,18 +285,20 @@ static void feh_event_handle_ButtonPress(XEvent * ev)
281285 } else if (feh_is_bb (EVENT_zoom_out , button , state )) {
282286 D (("Zoom_Out Button Press event\n" ));
283287 D (("click offset is %d,%d\n" , ev -> xbutton .x , ev -> xbutton .y ));
288+ if (winwid -> zoom <= ZOOM_MIN || opt .step_rate <= 0 )
289+ return ;
290+
284291 winwid -> click_offset_x = ev -> xbutton .x ;
285292 winwid -> click_offset_y = ev -> xbutton .y ;
286- winwid -> old_zoom = winwid -> zoom ;
287293
288294 /* required to adjust the image position in zoom mode */
289295 winwid -> im_click_offset_x = (winwid -> click_offset_x
290- - winwid -> im_x ) / winwid -> old_zoom ;
296+ - winwid -> im_x ) / winwid -> zoom ;
291297 winwid -> im_click_offset_y = (winwid -> click_offset_y
292- - winwid -> im_y ) / winwid -> old_zoom ;
298+ - winwid -> im_y ) / winwid -> zoom ;
293299
294300 /* copied from zoom_out, keyevents.c */
295- winwid -> zoom = winwid -> zoom / opt .zoom_rate ;
301+ winwid -> zoom = exp ( -- winwid -> zoom_step * opt .step_rate ) ;
296302
297303 if (winwid -> zoom < ZOOM_MIN )
298304 winwid -> zoom = ZOOM_MIN ;
@@ -400,11 +406,16 @@ static void feh_event_handle_ButtonRelease(XEvent * ev)
400406 opt .mode = MODE_NORMAL ;
401407 winwid -> mode = MODE_NORMAL ;
402408
403- if ((feh_is_bb (EVENT_zoom , button , state ))
404- && (ev -> xbutton .x == winwid -> click_offset_x )
405- && (ev -> xbutton .y == winwid -> click_offset_y )) {
406- winwid -> zoom = 1.0 ;
407- winwidget_center_image (winwid );
409+ if ((feh_is_bb (EVENT_zoom , button , state ))) {
410+ if ((ev -> xbutton .x == winwid -> click_offset_x )
411+ && (ev -> xbutton .y == winwid -> click_offset_y )) {
412+ winwid -> zoom = 1.0 ;
413+ winwid -> zoom_step = 0 ;
414+ winwidget_center_image (winwid );
415+ } else {
416+ winwid -> zoom_step = round (log (winwid -> zoom ) / opt .step_rate );
417+ winwidget_sanitise_offsets (winwid );
418+ }
408419 } else
409420 winwidget_sanitise_offsets (winwid );
410421
@@ -543,14 +554,8 @@ static void feh_event_handle_MotionNotify(XEvent * ev)
543554
544555 winwid = winwidget_get_from_window (ev -> xmotion .window );
545556 if (winwid ) {
546- if (ev -> xmotion .x > winwid -> click_offset_x )
547- winwid -> zoom = winwid -> old_zoom + (
548- ((double ) ev -> xmotion .x - (double ) winwid -> click_offset_x )
549- / 128.0 );
550- else
551- winwid -> zoom = winwid -> old_zoom - (
552- ((double ) winwid -> click_offset_x - (double ) ev -> xmotion .x )
553- / 128.0 );
557+ int step = winwid -> old_step + ev -> xmotion .x - winwid -> click_offset_x ;
558+ winwid -> zoom = exp (step * zoom_rate );
554559
555560 if (winwid -> zoom < ZOOM_MIN )
556561 winwid -> zoom = ZOOM_MIN ;
0 commit comments