From 96bdf1fec53fa9bb9ab039b81a00c7364d884b39 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Sun, 19 Sep 2010 23:20:36 +0200 Subject: [PATCH] app: refactor the canvas items to return a GdkRegion as extents instead of invalidating the canvas themselves. --- app/display/gimpcanvasitem.c | 80 ++++++++++++++++++++++++------- app/display/gimpcanvasitem.h | 39 ++++++++------- app/display/gimpcanvasrectangle.c | 58 +++++++++++----------- 3 files changed, 114 insertions(+), 63 deletions(-) diff --git a/app/display/gimpcanvasitem.c b/app/display/gimpcanvasitem.c index 2cd19057a8..019eb2921b 100644 --- a/app/display/gimpcanvasitem.c +++ b/app/display/gimpcanvasitem.c @@ -22,18 +22,36 @@ #include "display-types.h" +#include "libgimpmath/gimpmath.h" + #include "gimpcanvasitem.h" #include "gimpdisplayshell.h" #include "gimpdisplayshell-style.h" +typedef struct _GimpCanvasItemPrivate GimpCanvasItemPrivate; + +struct _GimpCanvasItemPrivate +{ + gdouble extents_x; + gdouble extents_y; + gdouble extents_width; + gdouble extents_height; +}; + +#define GET_PRIVATE(item) \ + G_TYPE_INSTANCE_GET_PRIVATE (item, \ + GIMP_TYPE_CANVAS_ITEM, \ + GimpCanvasItemPrivate) + + /* local function prototypes */ -static void gimp_canvas_item_real_draw (GimpCanvasItem *item, - GimpDisplayShell *shell, - cairo_t *cr); -static void gimp_canvas_item_real_invalidate (GimpCanvasItem *item, - GimpDisplayShell *shell); +static void gimp_canvas_item_real_draw (GimpCanvasItem *item, + GimpDisplayShell *shell, + cairo_t *cr); +static GdkRegion * gimp_canvas_item_real_get_extents (GimpCanvasItem *item, + GimpDisplayShell *shell); G_DEFINE_TYPE (GimpCanvasItem, gimp_canvas_item, @@ -45,8 +63,10 @@ G_DEFINE_TYPE (GimpCanvasItem, gimp_canvas_item, static void gimp_canvas_item_class_init (GimpCanvasItemClass *klass) { - klass->draw = gimp_canvas_item_real_draw; - klass->invalidate = gimp_canvas_item_real_invalidate; + klass->draw = gimp_canvas_item_real_draw; + klass->get_extents = gimp_canvas_item_real_get_extents; + + g_type_class_add_private (klass, sizeof (GimpCanvasItemPrivate)); } static void @@ -62,11 +82,19 @@ gimp_canvas_item_real_draw (GimpCanvasItem *item, g_warn_if_reached (); } -static void -gimp_canvas_item_real_invalidate (GimpCanvasItem *item, - GimpDisplayShell *shell) +static GdkRegion * +gimp_canvas_item_real_get_extents (GimpCanvasItem *item, + GimpDisplayShell *shell) { - g_warn_if_reached (); + GimpCanvasItemPrivate *private = GET_PRIVATE (item); + GdkRectangle rectangle; + + rectangle.x = floor (private->extents_x); + rectangle.y = floor (private->extents_y); + rectangle.width = ceil (private->extents_width); + rectangle.height = ceil (private->extents_height); + + return gdk_region_rectangle (&rectangle); } @@ -88,14 +116,32 @@ gimp_canvas_item_draw (GimpCanvasItem *item, cairo_restore (cr); } -void -gimp_canvas_item_invalidate (GimpCanvasItem *item, - GimpDisplayShell *shell) +GdkRegion * +gimp_canvas_item_get_extents (GimpCanvasItem *item, + GimpDisplayShell *shell) { - g_return_if_fail (GIMP_IS_CANVAS_ITEM (item)); - g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + g_return_val_if_fail (GIMP_IS_CANVAS_ITEM (item), NULL); + g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL); - GIMP_CANVAS_ITEM_GET_CLASS (item)->invalidate (item, shell); + return GIMP_CANVAS_ITEM_GET_CLASS (item)->get_extents (item, shell); +} + + +/* protexted functions */ + +void +_gimp_canvas_item_set_extents (GimpCanvasItem *item, + gdouble x, + gdouble y, + gdouble width, + gdouble height) +{ + GimpCanvasItemPrivate *private = GET_PRIVATE (item); + + private->extents_x = x; + private->extents_y = y; + private->extents_width = width; + private->extents_height = height; } void diff --git a/app/display/gimpcanvasitem.h b/app/display/gimpcanvasitem.h index 285d2df550..1c48cc1c4c 100644 --- a/app/display/gimpcanvasitem.h +++ b/app/display/gimpcanvasitem.h @@ -45,31 +45,36 @@ struct _GimpCanvasItemClass { GimpObjectClass parent_class; - void (* draw) (GimpCanvasItem *item, - GimpDisplayShell *shell, - cairo_t *cr); - void (* invalidate) (GimpCanvasItem *item, - GimpDisplayShell *shell); + void (* draw) (GimpCanvasItem *item, + GimpDisplayShell *shell, + cairo_t *cr); + GdkRegion * (* get_extents) (GimpCanvasItem *item, + GimpDisplayShell *shell); }; -GType gimp_canvas_item_get_type (void) G_GNUC_CONST; +GType gimp_canvas_item_get_type (void) G_GNUC_CONST; -void gimp_canvas_item_draw (GimpCanvasItem *item, - GimpDisplayShell *shell, - cairo_t *cr); -void gimp_canvas_item_invalidate (GimpCanvasItem *item, - GimpDisplayShell *shell); +void gimp_canvas_item_draw (GimpCanvasItem *item, + GimpDisplayShell *shell, + cairo_t *cr); +GdkRegion * gimp_canvas_item_get_extents (GimpCanvasItem *item, + GimpDisplayShell *shell); /* protected */ -void _gimp_canvas_item_stroke (GimpCanvasItem *item, - GimpDisplayShell *shell, - cairo_t *cr); -void _gimp_canvas_item_fill (GimpCanvasItem *item, - GimpDisplayShell *shell, - cairo_t *cr); +void _gimp_canvas_item_set_extents (GimpCanvasItem *item, + gdouble x, + gdouble y, + gdouble width, + gdouble height); +void _gimp_canvas_item_stroke (GimpCanvasItem *item, + GimpDisplayShell *shell, + cairo_t *cr); +void _gimp_canvas_item_fill (GimpCanvasItem *item, + GimpDisplayShell *shell, + cairo_t *cr); #endif /* __GIMP_CANVAS_ITEM_H__ */ diff --git a/app/display/gimpcanvasrectangle.c b/app/display/gimpcanvasrectangle.c index 463b09e6e7..a77f700ac0 100644 --- a/app/display/gimpcanvasrectangle.c +++ b/app/display/gimpcanvasrectangle.c @@ -61,19 +61,19 @@ struct _GimpCanvasRectanglePrivate /* local function prototypes */ -static void gimp_canvas_rectangle_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void gimp_canvas_rectangle_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); -static void gimp_canvas_rectangle_draw (GimpCanvasItem *item, - GimpDisplayShell *shell, - cairo_t *cr); -static void gimp_canvas_rectangle_invalidate (GimpCanvasItem *item, - GimpDisplayShell *shell); +static void gimp_canvas_rectangle_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_canvas_rectangle_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void gimp_canvas_rectangle_draw (GimpCanvasItem *item, + GimpDisplayShell *shell, + cairo_t *cr); +static GdkRegion * gimp_canvas_rectangle_get_extents (GimpCanvasItem *item, + GimpDisplayShell *shell); G_DEFINE_TYPE (GimpCanvasRectangle, gimp_canvas_rectangle, @@ -92,7 +92,7 @@ gimp_canvas_rectangle_class_init (GimpCanvasRectangleClass *klass) object_class->get_property = gimp_canvas_rectangle_get_property; item_class->draw = gimp_canvas_rectangle_draw; - item_class->invalidate = gimp_canvas_rectangle_invalidate; + item_class->get_extents = gimp_canvas_rectangle_get_extents; g_object_class_install_property (object_class, PROP_X, g_param_spec_double ("x", NULL, NULL, @@ -251,25 +251,25 @@ gimp_canvas_rectangle_draw (GimpCanvasItem *item, cairo_rectangle (cr, x, y, w, h); if (private->filled) - _gimp_canvas_item_fill (item, shell, cr); + { + _gimp_canvas_item_set_extents (item, x, y, w, h); + _gimp_canvas_item_fill (item, shell, cr); + } else - _gimp_canvas_item_stroke (item, shell, cr); + { + _gimp_canvas_item_set_extents (item, x - 1.5, y - 1.5, w + 3.0, h + 3.0); + _gimp_canvas_item_stroke (item, shell, cr); + } } -static void -gimp_canvas_rectangle_invalidate (GimpCanvasItem *item, - GimpDisplayShell *shell) +static GdkRegion * +gimp_canvas_rectangle_get_extents (GimpCanvasItem *item, + GimpDisplayShell *shell) { - GimpCanvasRectanglePrivate *private = GET_PRIVATE (item); - gdouble x, y; - gdouble w, h; - - gimp_canvas_rectangle_transform (item, shell, &x, &y, &w, &h); - - if (private->filled) - gimp_display_shell_expose_area (shell, x, y, w, h); - else - gimp_display_shell_expose_area (shell, x - 1.5, y - 1.5, w + 1.5, h + 1.5); + /* TODO: for large unfilled rectangles, construct a region which + * contains only the four sides + */ + return GIMP_CANVAS_ITEM_CLASS (parent_class)->get_extents (item, shell); } GimpCanvasItem *