From e76f7174fcc5428a4bb997eb5e5984b01899f777 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Sat, 26 Mar 2016 22:50:10 +0100 Subject: [PATCH] Bug 761270 - layer boundary not re-drawn correctly on scrolling Pass the display scroll offset down to gimp_cairo_stipple_pattern_create() and set it as offset on the created cairo pattern, so stipple patterns look the same no matter how the display is scrolled. --- app/core/gimp-cairo.c | 15 +++++++- app/core/gimp-cairo.h | 4 ++- app/display/gimpcanvas-style.c | 51 +++++++++++++++++---------- app/display/gimpcanvas-style.h | 20 ++++++++--- app/display/gimpcanvasgrid.c | 5 ++- app/display/gimpcanvasguide.c | 5 ++- app/display/gimpcanvaslayerboundary.c | 13 ++++--- app/display/gimpdisplayshell-draw.c | 6 ++-- 8 files changed, 86 insertions(+), 33 deletions(-) diff --git a/app/core/gimp-cairo.c b/app/core/gimp-cairo.c index c39b162109..ef24a904b7 100644 --- a/app/core/gimp-cairo.c +++ b/app/core/gimp-cairo.c @@ -27,6 +27,7 @@ #include #include +#include "libgimpmath/gimpmath.h" #include "libgimpcolor/gimpcolor.h" #include "core-types.h" @@ -40,7 +41,9 @@ static cairo_user_data_key_t surface_data_key = { 0, }; cairo_pattern_t * gimp_cairo_stipple_pattern_create (const GimpRGB *fg, const GimpRGB *bg, - gint index) + gint index, + gdouble offset_x, + gdouble offset_y) { cairo_surface_t *surface; cairo_pattern_t *pattern; @@ -84,6 +87,16 @@ gimp_cairo_stipple_pattern_create (const GimpRGB *fg, cairo_surface_destroy (surface); + if (offset_x != 0.0 || offset_y != 0.0) + { + cairo_matrix_t matrix; + + cairo_matrix_init_translate (&matrix, + fmod (offset_x, 8), + fmod (offset_y, 8)); + cairo_pattern_set_matrix (pattern, &matrix); + } + return pattern; } diff --git a/app/core/gimp-cairo.h b/app/core/gimp-cairo.h index 1c9e1b1e91..1b49e18eed 100644 --- a/app/core/gimp-cairo.h +++ b/app/core/gimp-cairo.h @@ -27,7 +27,9 @@ cairo_pattern_t * gimp_cairo_stipple_pattern_create (const GimpRGB *fg, const GimpRGB *bg, - gint index); + gint index, + gdouble offset_x, + gdouble offset_y); void gimp_cairo_add_arc (cairo_t *cr, gdouble center_x, diff --git a/app/display/gimpcanvas-style.c b/app/display/gimpcanvas-style.c index 458aca268a..e80bb5ab24 100644 --- a/app/display/gimpcanvas-style.c +++ b/app/display/gimpcanvas-style.c @@ -91,7 +91,9 @@ void gimp_canvas_set_guide_style (GtkWidget *canvas, cairo_t *cr, GimpGuideStyle style, - gboolean active) + gboolean active, + gdouble offset_x, + gdouble offset_y) { cairo_pattern_t *pattern; GimpRGB normal_fg; @@ -134,13 +136,11 @@ gimp_canvas_set_guide_style (GtkWidget *canvas, cairo_set_line_width (cr, line_width); if (active) - pattern = gimp_cairo_stipple_pattern_create (&active_fg, - &active_bg, - 0); + pattern = gimp_cairo_stipple_pattern_create (&active_fg, &active_bg, 0, + offset_x, offset_y); else - pattern = gimp_cairo_stipple_pattern_create (&normal_fg, - &normal_bg, - 0); + pattern = gimp_cairo_stipple_pattern_create (&normal_fg, &normal_bg, 0, + offset_x, offset_y); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); @@ -165,7 +165,9 @@ gimp_canvas_set_sample_point_style (GtkWidget *canvas, void gimp_canvas_set_grid_style (GtkWidget *canvas, cairo_t *cr, - GimpGrid *grid) + GimpGrid *grid, + gdouble offset_x, + gdouble offset_y) { GimpRGB fg; GimpRGB bg; @@ -188,13 +190,15 @@ gimp_canvas_set_grid_style (GtkWidget *canvas, { gimp_grid_get_bgcolor (grid, &bg); - pattern = gimp_cairo_stipple_pattern_create (&fg, &bg, 0); + pattern = gimp_cairo_stipple_pattern_create (&fg, &bg, 0, + offset_x, offset_y); } else { gimp_rgba_set (&bg, 0.0, 0.0, 0.0, 0.0); - pattern = gimp_cairo_stipple_pattern_create (&fg, &bg, 0); + pattern = gimp_cairo_stipple_pattern_create (&fg, &bg, 0, + offset_x, offset_y); } cairo_set_source (cr, pattern); @@ -230,7 +234,9 @@ gimp_canvas_set_pen_style (GtkWidget *canvas, void gimp_canvas_set_layer_style (GtkWidget *canvas, cairo_t *cr, - GimpLayer *layer) + GimpLayer *layer, + gdouble offset_x, + gdouble offset_y) { cairo_pattern_t *pattern; @@ -246,19 +252,22 @@ gimp_canvas_set_layer_style (GtkWidget *canvas, { pattern = gimp_cairo_stipple_pattern_create (&layer_mask_fg, &layer_mask_bg, - 0); + 0, + offset_x, offset_y); } else if (gimp_viewable_get_children (GIMP_VIEWABLE (layer))) { pattern = gimp_cairo_stipple_pattern_create (&layer_group_fg, &layer_group_bg, - 0); + 0, + offset_x, offset_y); } else { pattern = gimp_cairo_stipple_pattern_create (&layer_fg, &layer_bg, - 0); + 0, + offset_x, offset_y); } cairo_set_source (cr, pattern); @@ -267,7 +276,9 @@ gimp_canvas_set_layer_style (GtkWidget *canvas, void gimp_canvas_set_selection_out_style (GtkWidget *canvas, - cairo_t *cr) + cairo_t *cr, + gdouble offset_x, + gdouble offset_y) { cairo_pattern_t *pattern; @@ -279,7 +290,8 @@ gimp_canvas_set_selection_out_style (GtkWidget *canvas, pattern = gimp_cairo_stipple_pattern_create (&selection_out_fg, &selection_out_bg, - 0); + 0, + offset_x, offset_y); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); } @@ -287,7 +299,9 @@ gimp_canvas_set_selection_out_style (GtkWidget *canvas, void gimp_canvas_set_selection_in_style (GtkWidget *canvas, cairo_t *cr, - gint index) + gint index, + gdouble offset_x, + gdouble offset_y) { cairo_pattern_t *pattern; @@ -299,7 +313,8 @@ gimp_canvas_set_selection_in_style (GtkWidget *canvas, pattern = gimp_cairo_stipple_pattern_create (&selection_in_fg, &selection_in_bg, - index); + index, + offset_x, offset_y); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); } diff --git a/app/display/gimpcanvas-style.h b/app/display/gimpcanvas-style.h index 301f940ff9..2de2fff320 100644 --- a/app/display/gimpcanvas-style.h +++ b/app/display/gimpcanvas-style.h @@ -25,25 +25,35 @@ void gimp_canvas_set_guide_style (GtkWidget *canvas, cairo_t *cr, GimpGuideStyle style, - gboolean active); + gboolean active, + gdouble offset_x, + gdouble offset_y); void gimp_canvas_set_sample_point_style (GtkWidget *canvas, cairo_t *cr, gboolean active); void gimp_canvas_set_grid_style (GtkWidget *canvas, cairo_t *cr, - GimpGrid *grid); + GimpGrid *grid, + gdouble offset_x, + gdouble offset_y); void gimp_canvas_set_pen_style (GtkWidget *canvas, cairo_t *cr, const GimpRGB *color, gint width); void gimp_canvas_set_layer_style (GtkWidget *canvas, cairo_t *cr, - GimpLayer *layer); + GimpLayer *layer, + gdouble offset_x, + gdouble offset_y); void gimp_canvas_set_selection_out_style (GtkWidget *canvas, - cairo_t *cr); + cairo_t *cr, + gdouble offset_x, + gdouble offset_y); void gimp_canvas_set_selection_in_style (GtkWidget *canvas, cairo_t *cr, - gint index); + gint index, + gdouble offset_x, + gdouble offset_y); void gimp_canvas_set_vectors_bg_style (GtkWidget *canvas, cairo_t *cr, gboolean active); diff --git a/app/display/gimpcanvasgrid.c b/app/display/gimpcanvasgrid.c index fa26f9648f..ed329774e1 100644 --- a/app/display/gimpcanvasgrid.c +++ b/app/display/gimpcanvasgrid.c @@ -379,8 +379,11 @@ gimp_canvas_grid_stroke (GimpCanvasItem *item, if (private->grid_style) { + GimpDisplayShell *shell = gimp_canvas_item_get_shell (item); + gimp_canvas_set_grid_style (gimp_canvas_item_get_canvas (item), cr, - private->grid); + private->grid, + shell->offset_x, shell->offset_y); cairo_stroke (cr); } else diff --git a/app/display/gimpcanvasguide.c b/app/display/gimpcanvasguide.c index a3cda883c6..52a3622b6d 100644 --- a/app/display/gimpcanvasguide.c +++ b/app/display/gimpcanvasguide.c @@ -250,9 +250,12 @@ gimp_canvas_guide_stroke (GimpCanvasItem *item, if (private->style != GIMP_GUIDE_STYLE_NONE) { + GimpDisplayShell *shell = gimp_canvas_item_get_shell (item); + gimp_canvas_set_guide_style (gimp_canvas_item_get_canvas (item), cr, private->style, - gimp_canvas_item_get_highlight (item)); + gimp_canvas_item_get_highlight (item), + shell->offset_x, shell->offset_y); cairo_stroke (cr); } else diff --git a/app/display/gimpcanvaslayerboundary.c b/app/display/gimpcanvaslayerboundary.c index d64d6e31f8..a5e444cbf5 100644 --- a/app/display/gimpcanvaslayerboundary.c +++ b/app/display/gimpcanvaslayerboundary.c @@ -121,7 +121,8 @@ gimp_canvas_layer_boundary_finalize (GObject *object) GimpCanvasLayerBoundaryPrivate *private = GET_PRIVATE (object); if (private->layer) - g_object_remove_weak_pointer (G_OBJECT (private->layer), (gpointer)&private->layer); + g_object_remove_weak_pointer (G_OBJECT (private->layer), + (gpointer) &private->layer); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -138,10 +139,12 @@ gimp_canvas_layer_boundary_set_property (GObject *object, { case PROP_LAYER: if (private->layer) - g_object_remove_weak_pointer (G_OBJECT (private->layer), (gpointer)&private->layer); + g_object_remove_weak_pointer (G_OBJECT (private->layer), + (gpointer) &private->layer); private->layer = g_value_get_object (value); /* don't ref */ if (private->layer) - g_object_add_weak_pointer (G_OBJECT (private->layer), (gpointer)&private->layer); + g_object_add_weak_pointer (G_OBJECT (private->layer), + (gpointer) &private->layer); break; case PROP_EDIT_MASK: private->edit_mask = g_value_get_boolean (value); @@ -202,9 +205,11 @@ gimp_canvas_layer_boundary_stroke (GimpCanvasItem *item, cairo_t *cr) { GimpCanvasLayerBoundaryPrivate *private = GET_PRIVATE (item); + GimpDisplayShell *shell = gimp_canvas_item_get_shell (item); gimp_canvas_set_layer_style (gimp_canvas_item_get_canvas (item), cr, - private->layer); + private->layer, + shell->offset_x, shell->offset_y); cairo_stroke (cr); } diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c index 643a673c37..9d0da93688 100644 --- a/app/display/gimpdisplayshell-draw.c +++ b/app/display/gimpdisplayshell-draw.c @@ -54,7 +54,8 @@ gimp_display_shell_draw_selection_out (GimpDisplayShell *shell, g_return_if_fail (cr != NULL); g_return_if_fail (segs != NULL && n_segs > 0); - gimp_canvas_set_selection_out_style (shell->canvas, cr); + gimp_canvas_set_selection_out_style (shell->canvas, cr, + shell->offset_x, shell->offset_y); gimp_cairo_add_segments (cr, segs, n_segs); cairo_stroke (cr); @@ -70,7 +71,8 @@ gimp_display_shell_draw_selection_in (GimpDisplayShell *shell, g_return_if_fail (cr != NULL); g_return_if_fail (mask != NULL); - gimp_canvas_set_selection_in_style (shell->canvas, cr, index); + gimp_canvas_set_selection_in_style (shell->canvas, cr, index, + shell->offset_x, shell->offset_y); cairo_mask (cr, mask); }