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.
This commit is contained in:
Michael Natterer 2016-03-26 22:50:10 +01:00
parent 7529fd987c
commit e76f7174fc
8 changed files with 86 additions and 33 deletions

View File

@ -27,6 +27,7 @@
#include <gegl.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#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;
}

View File

@ -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,

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}