@@ -148,6 +148,10 @@ struct _EomScrollViewPrivate {
148148 GdkRGBA * override_bg_color ;
149149
150150 cairo_surface_t * background_surface ;
151+
152+ /* Two-pass filtering */
153+ GSource * hq_redraw_timeout_source ;
154+ gboolean force_unfiltered ;
151155};
152156
153157static void scroll_by (EomScrollView * view , int xofs , int yofs );
@@ -1183,6 +1187,45 @@ eom_scroll_view_focus_out_event (GtkWidget *widget,
11831187 return FALSE;
11841188}
11851189
1190+ static gboolean _hq_redraw_cb (gpointer user_data )
1191+ {
1192+ EomScrollViewPrivate * priv = EOM_SCROLL_VIEW (user_data )-> priv ;
1193+
1194+ priv -> force_unfiltered = FALSE;
1195+ gtk_widget_queue_draw (GTK_WIDGET (priv -> display ));
1196+
1197+ priv -> hq_redraw_timeout_source = NULL ;
1198+ return G_SOURCE_REMOVE ;
1199+ }
1200+
1201+ static void
1202+ _clear_hq_redraw_timeout (EomScrollView * view )
1203+ {
1204+ EomScrollViewPrivate * priv = view -> priv ;
1205+
1206+ if (priv -> hq_redraw_timeout_source != NULL ) {
1207+ g_source_unref (priv -> hq_redraw_timeout_source );
1208+ g_source_destroy (priv -> hq_redraw_timeout_source );
1209+ }
1210+
1211+ priv -> hq_redraw_timeout_source = NULL ;
1212+ }
1213+
1214+ static void
1215+ _set_hq_redraw_timeout (EomScrollView * view )
1216+ {
1217+ GSource * source ;
1218+
1219+ _clear_hq_redraw_timeout (view );
1220+
1221+ source = g_timeout_source_new (200 );
1222+ g_source_set_callback (source , & _hq_redraw_cb , view , NULL );
1223+
1224+ g_source_attach (source , NULL );
1225+
1226+ view -> priv -> hq_redraw_timeout_source = source ;
1227+ }
1228+
11861229static gboolean
11871230display_draw (GtkWidget * widget , cairo_t * cr , gpointer data )
11881231{
@@ -1308,13 +1351,29 @@ display_draw (GtkWidget *widget, cairo_t *cr, gpointer data)
13081351 } else
13091352#endif /* HAVE_RSVG */
13101353 {
1354+ cairo_filter_t interp_type ;
1355+
1356+ if (!DOUBLE_EQUAL (priv -> zoom , 1.0 ) && priv -> force_unfiltered )
1357+ {
1358+ interp_type = CAIRO_FILTER_NEAREST ;
1359+ _set_hq_redraw_timeout (view );
1360+ }
1361+ else
1362+ {
1363+ if (is_zoomed_in (view ))
1364+ interp_type = priv -> interp_type_in ;
1365+ else
1366+ interp_type = priv -> interp_type_out ;
1367+
1368+ _clear_hq_redraw_timeout (view );
1369+ priv -> force_unfiltered = TRUE;
1370+ }
13111371 cairo_scale (cr , priv -> zoom , priv -> zoom );
13121372 cairo_set_source_surface (cr , priv -> surface , xofs /priv -> zoom , yofs /priv -> zoom );
13131373 cairo_pattern_set_extend (cairo_get_source (cr ), CAIRO_EXTEND_PAD );
1314- if (is_zoomed_in (view ))
1315- cairo_pattern_set_filter (cairo_get_source (cr ), priv -> interp_type_in );
1316- else if (is_zoomed_out (view ))
1317- cairo_pattern_set_filter (cairo_get_source (cr ), priv -> interp_type_out );
1374+ if (is_zoomed_in (view ) || is_zoomed_out (view ))
1375+ cairo_pattern_set_filter (cairo_get_source (cr ), interp_type );
1376+
13181377 cairo_paint (cr );
13191378 }
13201379
@@ -1880,6 +1939,8 @@ eom_scroll_view_dispose (GObject *object)
18801939 view = EOM_SCROLL_VIEW (object );
18811940 priv = view -> priv ;
18821941
1942+ _clear_hq_redraw_timeout (view );
1943+
18831944 if (priv -> idle_id != 0 ) {
18841945 g_source_remove (priv -> idle_id );
18851946 priv -> idle_id = 0 ;
0 commit comments