summaryrefslogtreecommitdiffstats
path: root/src/display/sp-canvas.cpp
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2016-04-13 13:56:01 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2016-04-13 13:56:01 +0000
commit9e005239a9a2c93f40b1ac0e1a8e711ec7a2234e (patch)
treef030955471a1017e33438ac9f62bde29c4e565fa /src/display/sp-canvas.cpp
parentspw-utilities: Fix gtk_widget_set_margin_* API #Hackfest2016 (diff)
downloadinkscape-9e005239a9a2c93f40b1ac0e1a8e711ec7a2234e.tar.gz
inkscape-9e005239a9a2c93f40b1ac0e1a8e711ec7a2234e.zip
Fix canvas flicker while dragging objects. #Hackfest2016
(bzr r14829)
Diffstat (limited to 'src/display/sp-canvas.cpp')
-rw-r--r--src/display/sp-canvas.cpp44
1 files changed, 11 insertions, 33 deletions
diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp
index a311de7f1..3a801826b 100644
--- a/src/display/sp-canvas.cpp
+++ b/src/display/sp-canvas.cpp
@@ -1798,8 +1798,14 @@ void SPCanvas::endForcedFullRedraws()
gboolean SPCanvas::handle_draw(GtkWidget *widget, cairo_t *cr) {
SPCanvas *canvas = SP_CANVAS(widget);
+ // Blit from the backing store, without regard for the clean region.
+ // This is necessary because GTK clears the widget for us, which causes
+ // severe flicker while drawing if we don't blit the old contents.
+ cairo_set_source_surface(cr, canvas->_backing_store, 0, 0);
+ cairo_paint(cr);
+
cairo_rectangle_list_t *rects = cairo_copy_clip_rectangle_list(cr);
- cairo_region_t *draw_region = cairo_region_create();
+ cairo_region_t *dirty_region = cairo_region_create();
for (int i = 0; i < rects->num_rectangles; i++) {
cairo_rectangle_t rectangle = rects->rectangles[i];
@@ -1807,44 +1813,16 @@ gboolean SPCanvas::handle_draw(GtkWidget *widget, cairo_t *cr) {
rectangle.width, rectangle.height);
Geom::IntRect ir = dr.roundOutwards();
cairo_rectangle_int_t irect = { ir.left(), ir.top(), ir.width(), ir.height() };
- cairo_region_union_rectangle(draw_region, &irect);
+ cairo_region_union_rectangle(dirty_region, &irect);
}
cairo_rectangle_list_destroy(rects);
-
- cairo_region_t *draw_dirty = cairo_region_copy(draw_region);
- cairo_region_subtract(draw_dirty, canvas->_clean_region);
- cairo_region_intersect(draw_region, canvas->_clean_region);
-
- // Draw the background
- cairo_save(cr);
- cairo_translate(cr, -canvas->_x0, -canvas->_y0);
- cairo_set_source(cr, canvas->_background);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint(cr);
- cairo_restore(cr);
-
- // Draw the clean portion
- if (!cairo_region_is_empty(draw_region)) {
- cairo_region_translate(draw_region, -canvas->_x0, -canvas->_y0);
- cairo_save(cr);
- int n_rects = cairo_region_num_rectangles(draw_region);
- for (int i = 0; i < n_rects; ++i) {
- cairo_rectangle_int_t crect;
- cairo_region_get_rectangle(draw_region, i, &crect);
- cairo_rectangle(cr, crect.x, crect.y, crect.width, crect.height);
- }
- cairo_clip(cr);
- cairo_set_source_surface(cr, canvas->_backing_store, 0, 0);
- cairo_paint(cr);
- cairo_restore(cr);
- }
+ cairo_region_subtract(dirty_region, canvas->_clean_region);
// Render the dirty portion in the background
- if (!cairo_region_is_empty(draw_dirty)) {
+ if (!cairo_region_is_empty(dirty_region)) {
canvas->addIdle();
}
- cairo_region_destroy(draw_region);
- cairo_region_destroy(draw_dirty);
+ cairo_region_destroy(dirty_region);
return TRUE;
}