0001-Fix-displaying-images-with-GTK3.patch 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. From 2a497a06d9297712778b9bfde3f21a2bd867967c Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Ball=C3=B3=20Gy=C3=B6rgy?= <ballogyor@gmail.com>
  3. Date: Tue, 21 Feb 2017 01:06:06 +0100
  4. Subject: [PATCH] Fix displaying images with GTK3
  5. We have to use the cairo context provided by the draw event, otherwise the scrolling does not work properly.
  6. Don't paint the whole image when scale == 1, it's unneeded and slow.
  7. ---
  8. src/image-view.c | 86 +++++++++++++++++++++++++++++---------------------------
  9. 1 file changed, 44 insertions(+), 42 deletions(-)
  10. diff --git a/src/image-view.c b/src/image-view.c
  11. index b367f2a..820b843 100644
  12. --- a/src/image-view.c
  13. +++ b/src/image-view.c
  14. @@ -24,11 +24,10 @@
  15. static void image_view_finalize(GObject *iv);
  16. static void image_view_clear( ImageView* iv );
  17. -static gboolean on_idle( ImageView* iv );
  18. static void calc_image_area( ImageView* iv );
  19. -static void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type );
  20. #if GTK_CHECK_VERSION(3, 0, 0)
  21. +static void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type, cairo_t* cr );
  22. static void image_view_paint( ImageView* iv, cairo_t* cr );
  23. @@ -37,6 +36,8 @@ static void on_get_preferred_height( GtkWidget* widget, gint* minimal_height, gi
  24. static gboolean on_draw_event(GtkWidget* widget, cairo_t* cr);
  25. #else // GTK2
  26. +static gboolean on_idle( ImageView* iv );
  27. +static void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type );
  28. static void image_view_paint( ImageView* iv, GdkEventExpose* evt );
  29. @@ -268,16 +269,13 @@ void image_view_paint( ImageView* iv, cairo_t *cr )
  30. {
  31. cairo_rectangle_int_t rectangle;
  32. cairo_region_get_rectangle(region, i, &rectangle);
  33. - paint( iv, &rectangle, GDK_INTERP_NEAREST );
  34. + paint( iv, &rectangle, GDK_INTERP_NEAREST, cr );
  35. }
  36. cairo_region_destroy (region);
  37. -
  38. - if( 0 == iv->idle_handler )
  39. - iv->idle_handler = g_idle_add( (GSourceFunc)on_idle, iv );
  40. }
  41. }
  42. -#else
  43. +#else // GTK2
  44. gboolean on_expose_event( GtkWidget* widget, GdkEventExpose* evt )
  45. {
  46. @@ -390,6 +388,8 @@ void image_view_set_scale( ImageView* iv, gdouble new_scale, GdkInterpType type
  47. }
  48. }
  49. +#if GTK_CHECK_VERSION(3, 0, 0)
  50. +#else // GTK2
  51. gboolean on_idle( ImageView* iv )
  52. {
  53. GDK_THREADS_ENTER();
  54. @@ -435,6 +435,7 @@ gboolean on_idle( ImageView* iv )
  55. iv->idle_handler = 0;
  56. return FALSE;
  57. }
  58. +#endif
  59. void calc_image_area( ImageView* iv )
  60. {
  61. @@ -460,7 +461,11 @@ void calc_image_area( ImageView* iv )
  62. }
  63. }
  64. +#if GTK_CHECK_VERSION(3, 0, 0)
  65. +void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type, cairo_t* cr )
  66. +#else // GTK2
  67. void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type )
  68. +#endif
  69. {
  70. GdkRectangle rect;
  71. if( ! gdk_rectangle_intersect( invalid_rect, &iv->img_area, &rect ) )
  72. @@ -470,51 +475,48 @@ void paint( ImageView* iv, GdkRectangle* invalid_rect, GdkInterpType type )
  73. int dest_y;
  74. GdkPixbuf* src_pix = NULL;
  75. - if( iv->scale == 1.0 ) // original size
  76. - {
  77. - src_pix = (GdkPixbuf*)g_object_ref( iv->pix );
  78. - dest_x = iv->img_area.x;
  79. - dest_y = iv->img_area.y;
  80. - }
  81. - else // scaling is needed
  82. + GdkPixbuf* scaled_pix = NULL;
  83. +
  84. + dest_x = rect.x;
  85. + dest_y = rect.y;
  86. +
  87. + rect.x -= iv->img_area.x;
  88. + rect.y -= iv->img_area.y;
  89. +
  90. + int src_x = (int)floor( ((gdouble)rect.x) / iv->scale + 0.5 );
  91. + int src_y = (int)floor( ((gdouble)rect.y) / iv->scale + 0.5 );
  92. + int src_w = (int)floor( ((gdouble)rect.width) / iv->scale + 0.5 );
  93. + int src_h = (int)floor( ((gdouble)rect.height) / iv->scale + 0.5 );
  94. + if( src_y > gdk_pixbuf_get_height( iv->pix ) )
  95. + src_y = gdk_pixbuf_get_height( iv->pix );
  96. + if( src_x + src_w > gdk_pixbuf_get_width( iv->pix ) )
  97. + src_w = gdk_pixbuf_get_width( iv->pix ) - src_x;
  98. + if( src_y + src_h > gdk_pixbuf_get_height( iv->pix ) )
  99. + src_h = gdk_pixbuf_get_height( iv->pix ) - src_y;
  100. + //g_debug("orig src: x=%d, y=%d, w=%d, h=%d",
  101. + // src_x, src_y, src_w, src_h );
  102. +
  103. + if ((src_w > 0) && (src_h > 0))
  104. {
  105. - dest_x = rect.x;
  106. - dest_y = rect.y;
  107. -
  108. - rect.x -= iv->img_area.x;
  109. - rect.y -= iv->img_area.y;
  110. -
  111. - GdkPixbuf* scaled_pix = NULL;
  112. - int src_x = (int)floor( ((gdouble)rect.x) / iv->scale + 0.5 );
  113. - int src_y = (int)floor( ((gdouble)rect.y) / iv->scale + 0.5 );
  114. - int src_w = (int)floor( ((gdouble)rect.width) / iv->scale + 0.5 );
  115. - int src_h = (int)floor( ((gdouble)rect.height) / iv->scale + 0.5 );
  116. - if( src_y > gdk_pixbuf_get_height( iv->pix ) )
  117. - src_y = gdk_pixbuf_get_height( iv->pix );
  118. - if( src_x + src_w > gdk_pixbuf_get_width( iv->pix ) )
  119. - src_w = gdk_pixbuf_get_width( iv->pix ) - src_x;
  120. - if( src_y + src_h > gdk_pixbuf_get_height( iv->pix ) )
  121. - src_h = gdk_pixbuf_get_height( iv->pix ) - src_y;
  122. - //g_debug("orig src: x=%d, y=%d, w=%d, h=%d",
  123. - // src_x, src_y, src_w, src_h );
  124. -
  125. - if ((src_w > 0) && (src_h > 0))
  126. - {
  127. - src_pix = gdk_pixbuf_new_subpixbuf( iv->pix, src_x, src_y, src_w, src_h );
  128. - scaled_pix = gdk_pixbuf_scale_simple( src_pix, rect.width, rect.height, type );
  129. - g_object_unref( src_pix );
  130. - src_pix = scaled_pix;
  131. - }
  132. -
  133. + src_pix = gdk_pixbuf_new_subpixbuf( iv->pix, src_x, src_y, src_w, src_h );
  134. + scaled_pix = gdk_pixbuf_scale_simple( src_pix, rect.width, rect.height, type );
  135. + g_object_unref( src_pix );
  136. + src_pix = scaled_pix;
  137. }
  138. if( G_LIKELY(src_pix) )
  139. {
  140. GtkWidget* widget = (GtkWidget*)iv;
  141. +#if GTK_CHECK_VERSION(3, 0, 0)
  142. +#else // GTK2
  143. cairo_t *cr = gdk_cairo_create (gtk_widget_get_window(widget));
  144. +#endif
  145. gdk_cairo_set_source_pixbuf (cr, src_pix, dest_x, dest_y);
  146. cairo_paint (cr);
  147. +#if GTK_CHECK_VERSION(3, 0, 0)
  148. +#else // GTK2
  149. cairo_destroy (cr);
  150. +#endif
  151. g_object_unref( src_pix );
  152. }
  153. --
  154. 2.11.1