[gimp] app: cache bounding box of GimpVectors object



commit ec2be9b415fab986d67211ff4a0f04b1bb3a6c34
Author: Sven Neumann <sven gimp org>
Date:   Fri Sep 17 21:31:55 2010 +0200

    app: cache bounding box of GimpVectors object
    
    Cache the bounding box of the GimpVectors similar to the bezier
    representation.

 app/vectors/gimpvectors.c |   93 ++++++++++++++++++++++++++------------------
 app/vectors/gimpvectors.h |   14 +++++-
 2 files changed, 66 insertions(+), 41 deletions(-)
---
diff --git a/app/vectors/gimpvectors.c b/app/vectors/gimpvectors.c
index 52c45b7..ea3596e 100644
--- a/app/vectors/gimpvectors.c
+++ b/app/vectors/gimpvectors.c
@@ -248,6 +248,9 @@ gimp_vectors_init (GimpVectors *vectors)
   vectors->last_stroke_ID = 0;
   vectors->freeze_count   = 0;
   vectors->precision      = 0.2;
+
+  vectors->bezier_desc    = NULL;
+  vectors->bounds_valid   = FALSE;
 }
 
 static void
@@ -614,6 +617,9 @@ gimp_vectors_real_freeze (GimpVectors *vectors)
       g_slice_free (GimpBezierDesc, vectors->bezier_desc);
       vectors->bezier_desc = NULL;
     }
+
+  /*  invalidate bounds  */
+  vectors->bounds_valid = FALSE;
 }
 
 static void
@@ -1026,60 +1032,71 @@ gimp_vectors_real_get_distance (const GimpVectors *vectors,
 }
 
 gboolean
-gimp_vectors_bounds (const GimpVectors  *vectors,
-                     gdouble            *x1,
-                     gdouble            *y1,
-                     gdouble            *x2,
-                     gdouble            *y2)
+gimp_vectors_bounds (GimpVectors *vectors,
+                     gdouble     *x1,
+                     gdouble     *y1,
+                     gdouble     *x2,
+                     gdouble     *y2)
 {
-  GimpStroke *stroke;
-  gboolean    has_strokes = FALSE;
-
   g_return_val_if_fail (GIMP_IS_VECTORS (vectors), FALSE);
-  g_return_val_if_fail (x1 != NULL, FALSE);
-  g_return_val_if_fail (y1 != NULL, FALSE);
-  g_return_val_if_fail (x2 != NULL, FALSE);
-  g_return_val_if_fail (y2 != NULL, FALSE);
-
-  for (stroke = gimp_vectors_stroke_get_next (vectors, NULL);
-       stroke;
-       stroke = gimp_vectors_stroke_get_next (vectors, stroke))
+  g_return_val_if_fail (x1 != NULL && y1 != NULL &&
+                        x2 != NULL && y2 != NULL, FALSE);
+
+  if (! vectors->bounds_valid)
     {
-      GArray   *stroke_coords;
-      gboolean  closed;
+      GimpStroke *stroke;
 
-      stroke_coords = gimp_stroke_interpolate (stroke, 1.0, &closed);
+      vectors->bounds_empty = TRUE;
+      vectors->bounds_x1 = vectors->bounds_x2 = 0.0;
+      vectors->bounds_x1 = vectors->bounds_x2 = 0.0;
 
-      if (stroke_coords)
+      for (stroke = gimp_vectors_stroke_get_next (vectors, NULL);
+           stroke;
+           stroke = gimp_vectors_stroke_get_next (vectors, stroke))
         {
-          GimpCoords point;
-          gint       i;
+          GArray   *stroke_coords;
+          gboolean  closed;
+
+          stroke_coords = gimp_stroke_interpolate (stroke, 1.0, &closed);
 
-          if (! has_strokes && stroke_coords->len > 0)
+          if (stroke_coords)
             {
-              point = g_array_index (stroke_coords, GimpCoords, 0);
+              GimpCoords point;
+              gint       i;
 
-              *x1 = *x2 = point.x;
-              *y1 = *y2 = point.y;
+              if (vectors->bounds_empty && stroke_coords->len > 0)
+                {
+                  point = g_array_index (stroke_coords, GimpCoords, 0);
 
-              has_strokes = TRUE;
-            }
+                  vectors->bounds_x1 = vectors->bounds_x2 = point.x;
+                  vectors->bounds_y1 = vectors->bounds_y2 = point.y;
 
-          for (i = 0; i < stroke_coords->len; i++)
-            {
-              point = g_array_index (stroke_coords, GimpCoords, i);
+                  vectors->bounds_empty = FALSE;
+                }
 
-              *x1 = MIN (*x1, point.x);
-              *y1 = MIN (*y1, point.y);
-              *x2 = MAX (*x2, point.x);
-              *y2 = MAX (*y2, point.y);
-            }
+              for (i = 0; i < stroke_coords->len; i++)
+                {
+                  point = g_array_index (stroke_coords, GimpCoords, i);
+
+                  vectors->bounds_x1 = MIN (vectors->bounds_x1, point.x);
+                  vectors->bounds_y1 = MIN (vectors->bounds_y1, point.y);
+                  vectors->bounds_x2 = MAX (vectors->bounds_x2, point.x);
+                  vectors->bounds_y2 = MAX (vectors->bounds_y2, point.y);
+                }
 
-          g_array_free (stroke_coords, TRUE);
+              g_array_free (stroke_coords, TRUE);
+            }
         }
+
+      vectors->bounds_valid = TRUE;
     }
 
-  return has_strokes;
+  *x1 = vectors->bounds_x1;
+  *y1 = vectors->bounds_y1;
+  *x2 = vectors->bounds_x2;
+  *y2 = vectors->bounds_y2;
+
+  return (! vectors->bounds_empty);
 }
 
 gint
diff --git a/app/vectors/gimpvectors.h b/app/vectors/gimpvectors.h
index a5ca52c..a27d986 100644
--- a/app/vectors/gimpvectors.h
+++ b/app/vectors/gimpvectors.h
@@ -37,13 +37,20 @@ struct _GimpVectors
 {
   GimpItem        parent_instance;
 
-  GList          *strokes;        /* The List of GimpStrokes        */
+  GList          *strokes;        /* The List of GimpStrokes      */
   gint            last_stroke_ID;
 
   gint            freeze_count;
   gdouble         precision;
 
-  GimpBezierDesc *bezier_desc;    /* Cached bezier representation   */
+  GimpBezierDesc *bezier_desc;    /* Cached bezier representation */
+
+  gboolean        bounds_valid;   /* Cached bounding box          */
+  gboolean        bounds_empty;
+  gdouble         bounds_x1;
+  gdouble         bounds_y1;
+  gdouble         bounds_x2;
+  gdouble         bounds_y2;
 };
 
 struct _GimpVectorsClass
@@ -158,7 +165,8 @@ gdouble         gimp_vectors_get_length         (const GimpVectors  *vectors,
                                                  const GimpAnchor   *start);
 gdouble         gimp_vectors_get_distance       (const GimpVectors  *vectors,
                                                  const GimpCoords   *coord);
-gboolean        gimp_vectors_bounds             (const GimpVectors  *vectors,
+
+gboolean        gimp_vectors_bounds             (GimpVectors        *vectors,
                                                  gdouble            *x1,
                                                  gdouble            *y1,
                                                  gdouble            *x2,



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