[gimp] app: refactor the canvas items to return a GdkRegion as extents



commit 96bdf1fec53fa9bb9ab039b81a00c7364d884b39
Author: Michael Natterer <mitch gimp org>
Date:   Sun Sep 19 23:20:36 2010 +0200

    app: refactor the canvas items to return a GdkRegion as extents
    
    instead of invalidating the canvas themselves.

 app/display/gimpcanvasitem.c      |   78 +++++++++++++++++++++++++++++--------
 app/display/gimpcanvasitem.h      |   39 ++++++++++--------
 app/display/gimpcanvasrectangle.c |   58 ++++++++++++++--------------
 3 files changed, 113 insertions(+), 62 deletions(-)
---
diff --git a/app/display/gimpcanvasitem.c b/app/display/gimpcanvasitem.c
index 2cd1905..019eb29 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);
 }
 
+GdkRegion *
+gimp_canvas_item_get_extents (GimpCanvasItem   *item,
+                              GimpDisplayShell *shell)
+{
+  g_return_val_if_fail (GIMP_IS_CANVAS_ITEM (item), NULL);
+  g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
+
+  return GIMP_CANVAS_ITEM_GET_CLASS (item)->get_extents (item, shell);
+}
+
+
+/*  protexted functions  */
+
 void
-gimp_canvas_item_invalidate (GimpCanvasItem   *item,
-                             GimpDisplayShell *shell)
+_gimp_canvas_item_set_extents (GimpCanvasItem *item,
+                               gdouble         x,
+                               gdouble         y,
+                               gdouble         width,
+                               gdouble         height)
 {
-  g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
-  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+  GimpCanvasItemPrivate *private = GET_PRIVATE (item);
 
-  GIMP_CANVAS_ITEM_GET_CLASS (item)->invalidate (item, shell);
+  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 285d2df..1c48cc1 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 463b09e..a77f700 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 *



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]