# HG changeset patch # User nadvornik # Date 1220563149 0 # Node ID 86148ec8a2996ee01ac44968c0d379255408b1b3 # Parent ab24c46aa6e4d53e2c6c976c2605cf4bc62d75c6 fixed various problems with preserving viewport on image change, options->image.scroll_reset_method should work again (it needs to be added to the preferences dialog) diff -r ab24c46aa6e4 -r 86148ec8a299 src/layout_image.c --- a/src/layout_image.c Wed Sep 03 21:54:49 2008 +0000 +++ b/src/layout_image.c Thu Sep 04 21:19:09 2008 +0000 @@ -919,15 +919,10 @@ void layout_image_set_fd(LayoutWindow *lw, FileData *fd) { - gdouble sx, sy; if (!layout_valid(&lw)) return; - image_get_scroll_center(lw->image, &sx, &sy); - image_change_fd(lw->image, fd, image_zoom_get_default(lw->image)); - image_set_scroll_center(lw->image, sx, sy); - layout_list_sync_fd(lw, fd); layout_image_slideshow_continue_check(lw); layout_bars_new_image(lw); @@ -1045,12 +1040,9 @@ void layout_image_refresh(LayoutWindow *lw) { - gdouble sx, sy; if (!layout_valid(&lw)) return; - image_get_scroll_center(lw->image, &sx, &sy); image_reload(lw->image); - image_set_scroll_center(lw->image, sx, sy); } void layout_image_color_profile_set(LayoutWindow *lw, diff -r ab24c46aa6e4 -r 86148ec8a299 src/options.c --- a/src/options.c Wed Sep 03 21:54:49 2008 +0000 +++ b/src/options.c Thu Sep 04 21:19:09 2008 +0000 @@ -77,7 +77,7 @@ options->image.max_autofit_size = 100; options->image.max_window_size = 90; options->image.read_buffer_size = IMAGE_LOADER_READ_BUFFER_SIZE_DEFAULT; - options->image.scroll_reset_method = SCROLL_RESET_TOPLEFT; + options->image.scroll_reset_method = SCROLL_RESET_NOCHANGE; options->image.tile_cache_max = 10; options->image.image_cache_max = 128; /* 4 x 10MPix */ options->image.use_custom_border_color = FALSE; diff -r ab24c46aa6e4 -r 86148ec8a299 src/pixbuf-renderer.c --- a/src/pixbuf-renderer.c Wed Sep 03 21:54:49 2008 +0000 +++ b/src/pixbuf-renderer.c Thu Sep 04 21:19:09 2008 +0000 @@ -511,6 +511,9 @@ pr->orientation = 1; + pr->norm_center_x = 0.5; + pr->norm_center_y = 0.5; + gtk_widget_set_double_buffered(box, FALSE); g_signal_connect_after(G_OBJECT(box), "size_allocate", G_CALLBACK(pr_size_cb), pr); @@ -3093,6 +3096,19 @@ *------------------------------------------------------------------- */ +static void pixbuf_renderer_sync_scroll_center(PixbufRenderer *pr) +{ + gint src_x, src_y; + if (!pr->width || !pr->height) return; + + src_x = pr->x_scroll + pr->vis_width / 2; + src_y = pr->y_scroll + pr->vis_height / 2; + + pr->norm_center_x = (gdouble)src_x / pr->width; + pr->norm_center_y = (gdouble)src_y / pr->height; +} + + static gint pr_scroll_clamp(PixbufRenderer *pr) { gint old_xs; @@ -3127,6 +3143,8 @@ pr->y_scroll = CLAMP(pr->y_scroll, 0, pr->height - pr->vis_height); } + pixbuf_renderer_sync_scroll_center(pr); + return (old_xs != pr->x_scroll || old_ys != pr->y_scroll); } @@ -3159,6 +3177,8 @@ pr->y_offset = 0; } + pixbuf_renderer_sync_scroll_center(pr); + return (old_vw != pr->vis_width || old_vh != pr->vis_height); } @@ -3268,6 +3288,8 @@ } if (redrawn) *redrawn = (invalidate || invalid); + pixbuf_renderer_sync_scroll_center(pr); + return TRUE; } @@ -3283,7 +3305,9 @@ gboolean force = !!(flags & PR_ZOOM_FORCE); gboolean new = !!(flags & PR_ZOOM_NEW); PrZoomFlags clamp_flags = flags; - + gdouble old_center_x = pr->norm_center_x; + gdouble old_center_y = pr->norm_center_y; + old_scale = pr->scale; if (center_point) { @@ -3310,7 +3334,9 @@ switch (pr->scroll_reset) { case PR_SCROLL_RESET_NOCHANGE: - /* maintain old scroll position, do nothing */ + /* maintain old scroll position */ + pr->x_scroll = ((gdouble)pr->image_width * old_center_x * pr->scale) - pr->vis_width / 2; + pr->y_scroll = ((gdouble)pr->image_height * old_center_y * pr->scale) - pr->vis_height / 2; break; case PR_SCROLL_RESET_CENTER: /* center new image */ @@ -3461,6 +3487,9 @@ pr->y_scroll += y; pr_scroll_clamp(pr); + + pixbuf_renderer_sync_scroll_center(pr); + if (pr->x_scroll == old_x && pr->y_scroll == old_y) return; pr_scroll_notify_signal(pr); @@ -3576,20 +3605,8 @@ void pixbuf_renderer_get_scroll_center(PixbufRenderer *pr, gdouble *x, gdouble *y) { - gint src_x, src_y; - - src_x = pr->x_scroll + pr->vis_width / 2; - src_y = pr->y_scroll + pr->vis_height / 2; - - if (pr->width) - *x = (gdouble)src_x / pr->width; - else - *x = 0.5; /* center */ - - if (pr->height) - *y = (gdouble)src_y / pr->height; - else - *y = 0.5; /* center */ + *x = pr->norm_center_x; + *y = pr->norm_center_y; } void pixbuf_renderer_set_scroll_center(PixbufRenderer *pr, gdouble x, gdouble y) diff -r ab24c46aa6e4 -r 86148ec8a299 src/pixbuf-renderer.h --- a/src/pixbuf-renderer.h Wed Sep 03 21:54:49 2008 +0000 +++ b/src/pixbuf-renderer.h Thu Sep 04 21:19:09 2008 +0000 @@ -68,6 +68,9 @@ gint x_scroll; /* scroll offset of image (into width, height to start drawing) */ gint y_scroll; + gdouble norm_center_x; /* coordinates of viewport center in the image, in range 0.0 - 1.0 */ + gdouble norm_center_y; /* these coordinates are used for PR_SCROLL_RESET_NOCHANGE and should be preserved over periods with NULL pixbuf */ + gdouble subpixel_x_scroll; /* subpixel scroll alignment, used to prevent acumulation of rounding errors */ gdouble subpixel_y_scroll;