summaryrefslogtreecommitdiff
blob: b832d364b3eda5c8ac75b6a5c91b7ee3d3e51788 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
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