123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- From 2a497a06d9297712778b9bfde3f21a2bd867967c Mon Sep 17 00:00:00 2001
- From: =?UTF-8?q?Ball=C3=B3=20Gy=C3=B6rgy?= <ballogyor@gmail.com>
- Date: Tue, 21 Feb 2017 01:06:06 +0100
- Subject: [PATCH] Fix displaying images with GTK3
- We have to use the cairo context provided by the draw event, otherwise the scrolling does not work properly.
- Don't paint the whole image when scale == 1, it's unneeded and slow.
- ---
- src/image-view.c | 86 +++++++++++++++++++++++++++++---------------------------
- 1 file changed, 44 insertions(+), 42 deletions(-)
- diff --git a/src/image-view.c b/src/image-view.c
- index b367f2a..820b843 100644
- --- a/src/image-view.c
- +++ b/src/image-view.c
- @@ -24,11 +24,10 @@
- static void image_view_finalize(GObject *iv);
-
- static void image_view_clear( ImageView* iv );
- -static gboolean on_idle( ImageView* iv );
- static void calc_image_area( ImageView* iv );
- -static void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type );
-
- #if GTK_CHECK_VERSION(3, 0, 0)
- +static void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type, cairo_t* cr );
-
- static void image_view_paint( ImageView* iv, cairo_t* cr );
-
- @@ -37,6 +36,8 @@ static void on_get_preferred_height( GtkWidget* widget, gint* minimal_height, gi
- static gboolean on_draw_event(GtkWidget* widget, cairo_t* cr);
-
- #else // GTK2
- +static gboolean on_idle( ImageView* iv );
- +static void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type );
-
- static void image_view_paint( ImageView* iv, GdkEventExpose* evt );
-
- @@ -268,16 +269,13 @@ void image_view_paint( ImageView* iv, cairo_t *cr )
- {
- cairo_rectangle_int_t rectangle;
- cairo_region_get_rectangle(region, i, &rectangle);
- - paint( iv, &rectangle, GDK_INTERP_NEAREST );
- + paint( iv, &rectangle, GDK_INTERP_NEAREST, cr );
- }
-
- cairo_region_destroy (region);
- -
- - if( 0 == iv->idle_handler )
- - iv->idle_handler = g_idle_add( (GSourceFunc)on_idle, iv );
- }
- }
- -#else
- +#else // GTK2
-
- gboolean on_expose_event( GtkWidget* widget, GdkEventExpose* evt )
- {
- @@ -390,6 +388,8 @@ void image_view_set_scale( ImageView* iv, gdouble new_scale, GdkInterpType type
- }
- }
-
- +#if GTK_CHECK_VERSION(3, 0, 0)
- +#else // GTK2
- gboolean on_idle( ImageView* iv )
- {
- GDK_THREADS_ENTER();
- @@ -435,6 +435,7 @@ gboolean on_idle( ImageView* iv )
- iv->idle_handler = 0;
- return FALSE;
- }
- +#endif
-
- void calc_image_area( ImageView* iv )
- {
- @@ -460,7 +461,11 @@ void calc_image_area( ImageView* iv )
- }
- }
-
- +#if GTK_CHECK_VERSION(3, 0, 0)
- +void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type, cairo_t* cr )
- +#else // GTK2
- void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type )
- +#endif
- {
- GdkRectangle rect;
- if( ! gdk_rectangle_intersect( invalid_rect, &iv->img_area, &rect ) )
- @@ -470,51 +475,48 @@ void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type )
- int dest_y;
-
- GdkPixbuf* src_pix = NULL;
- - if( iv->scale == 1.0 ) // original size
- - {
- - src_pix = (GdkPixbuf*)g_object_ref( iv->pix );
- - dest_x = iv->img_area.x;
- - dest_y = iv->img_area.y;
- - }
- - else // scaling is needed
- + GdkPixbuf* scaled_pix = NULL;
- +
- + dest_x = rect.x;
- + dest_y = rect.y;
- +
- + rect.x -= iv->img_area.x;
- + rect.y -= iv->img_area.y;
- +
- + int src_x = (int)floor( ((gdouble)rect.x) / iv->scale + 0.5 );
- + int src_y = (int)floor( ((gdouble)rect.y) / iv->scale + 0.5 );
- + int src_w = (int)floor( ((gdouble)rect.width) / iv->scale + 0.5 );
- + int src_h = (int)floor( ((gdouble)rect.height) / iv->scale + 0.5 );
- + if( src_y > gdk_pixbuf_get_height( iv->pix ) )
- + src_y = gdk_pixbuf_get_height( iv->pix );
- + if( src_x + src_w > gdk_pixbuf_get_width( iv->pix ) )
- + src_w = gdk_pixbuf_get_width( iv->pix ) - src_x;
- + if( src_y + src_h > gdk_pixbuf_get_height( iv->pix ) )
- + src_h = gdk_pixbuf_get_height( iv->pix ) - src_y;
- + //g_debug("orig src: x=%d, y=%d, w=%d, h=%d",
- + // src_x, src_y, src_w, src_h );
- +
- + if ((src_w > 0) && (src_h > 0))
- {
- - dest_x = rect.x;
- - dest_y = rect.y;
- -
- - rect.x -= iv->img_area.x;
- - rect.y -= iv->img_area.y;
- -
- - GdkPixbuf* scaled_pix = NULL;
- - int src_x = (int)floor( ((gdouble)rect.x) / iv->scale + 0.5 );
- - int src_y = (int)floor( ((gdouble)rect.y) / iv->scale + 0.5 );
- - int src_w = (int)floor( ((gdouble)rect.width) / iv->scale + 0.5 );
- - int src_h = (int)floor( ((gdouble)rect.height) / iv->scale + 0.5 );
- - if( src_y > gdk_pixbuf_get_height( iv->pix ) )
- - src_y = gdk_pixbuf_get_height( iv->pix );
- - if( src_x + src_w > gdk_pixbuf_get_width( iv->pix ) )
- - src_w = gdk_pixbuf_get_width( iv->pix ) - src_x;
- - if( src_y + src_h > gdk_pixbuf_get_height( iv->pix ) )
- - src_h = gdk_pixbuf_get_height( iv->pix ) - src_y;
- - //g_debug("orig src: x=%d, y=%d, w=%d, h=%d",
- - // src_x, src_y, src_w, src_h );
- -
- - if ((src_w > 0) && (src_h > 0))
- - {
- - src_pix = gdk_pixbuf_new_subpixbuf( iv->pix, src_x, src_y, src_w, src_h );
- - scaled_pix = gdk_pixbuf_scale_simple( src_pix, rect.width, rect.height, type );
- - g_object_unref( src_pix );
- - src_pix = scaled_pix;
- - }
- -
- + src_pix = gdk_pixbuf_new_subpixbuf( iv->pix, src_x, src_y, src_w, src_h );
- + scaled_pix = gdk_pixbuf_scale_simple( src_pix, rect.width, rect.height, type );
- + g_object_unref( src_pix );
- + src_pix = scaled_pix;
- }
-
- if( G_LIKELY(src_pix) )
- {
- GtkWidget* widget = (GtkWidget*)iv;
- +#if GTK_CHECK_VERSION(3, 0, 0)
- +#else // GTK2
- cairo_t *cr = gdk_cairo_create (gtk_widget_get_window(widget));
- +#endif
- gdk_cairo_set_source_pixbuf (cr, src_pix, dest_x, dest_y);
- cairo_paint (cr);
- +#if GTK_CHECK_VERSION(3, 0, 0)
- +#else // GTK2
- cairo_destroy (cr);
- +#endif
-
- g_object_unref( src_pix );
- }
- --
- 2.11.1
|