Author: spouliot
Date: 2007-09-20 11:25:36 -0400 (Thu, 20 Sep 2007)
New Revision: 86065

Modified:
   trunk/moon/src/ChangeLog
   trunk/moon/src/geometry.cpp
   trunk/moon/src/moon-path.c
   trunk/moon/src/moon-path.h
   trunk/moon/src/shape.cpp
   trunk/moon/src/shape.h
Log:
2007-09-20  Sebastien Pouliot  <[EMAIL PROTECTED]> 

        * geometry.cpp: Avoid re-allocating path memory when possible.
        * moon-path.c|h: Added documentation and new moon_path_renew and 
        moon_path_clear functions to reduce memory re-allocations.
        * shape.cpp|h: Avoid re-allocating path memory when possible.



Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog    2007-09-20 14:56:27 UTC (rev 86064)
+++ trunk/moon/src/ChangeLog    2007-09-20 15:25:36 UTC (rev 86065)
@@ -1,3 +1,10 @@
+2007-09-20  Sebastien Pouliot  <[EMAIL PROTECTED]> 
+
+       * geometry.cpp: Avoid re-allocating path memory when possible.
+       * moon-path.c|h: Added documentation and new moon_path_renew and 
+       moon_path_clear functions to reduce memory re-allocations.
+       * shape.cpp|h: Avoid re-allocating path memory when possible.
+
 2007-09-20  Sebastien Pouliot  <[EMAIL PROTECTED]>
 
        * brush.cpp|h: Implemented MappingMode for RadialGradientBrush.

Modified: trunk/moon/src/geometry.cpp
===================================================================
--- trunk/moon/src/geometry.cpp 2007-09-20 14:56:27 UTC (rev 86064)
+++ trunk/moon/src/geometry.cpp 2007-09-20 15:25:36 UTC (rev 86065)
@@ -427,9 +427,7 @@
        double rx = ellipse_geometry_get_radius_x (this);
        double ry = ellipse_geometry_get_radius_y (this);
 
-       if (path)
-               moon_path_destroy (path);
-       path = moon_path_new (MOON_PATH_ELLIPSE_LENGTH);
+       path = moon_path_renew (path, MOON_PATH_ELLIPSE_LENGTH);
        moon_ellipse (path, pt->x - rx, pt->y - ry, rx * 2.0, ry * 2.0);
 }
 
@@ -492,9 +490,7 @@
        Point *p1 = line_geometry_get_start_point (this);
        Point *p2 = line_geometry_get_end_point (this);
 
-       if (path)
-               moon_path_destroy (path);
-       path = moon_path_new (MOON_PATH_MOVE_TO_LENGTH + 
MOON_PATH_LINE_TO_LENGTH);
+       path = moon_path_renew (path, MOON_PATH_MOVE_TO_LENGTH + 
MOON_PATH_LINE_TO_LENGTH);
        moon_move_to (path, p1->x, p1->y);
        moon_line_to (path, p2->x, p2->y);
 }
@@ -720,15 +716,12 @@
                }
        }
 
-       if (path)
-               moon_path_destroy (path);
-
        double radius_x, radius_y;
        if (GetRadius (&radius_x, &radius_y)) {
-               path = moon_path_new (MOON_PATH_ROUNDED_RECTANGLE_LENGTH);
+               path = moon_path_renew (path, 
MOON_PATH_ROUNDED_RECTANGLE_LENGTH);
                moon_rounded_rectangle (path, rect->x, rect->y, rect->w, 
rect->h, radius_x + half_thick, radius_y + half_thick);
        } else {
-               path = moon_path_new (MOON_PATH_RECTANGLE_LENGTH);
+               path = moon_path_renew (path, MOON_PATH_RECTANGLE_LENGTH);
                moon_rectangle (path, rect->x, rect->y, rect->w, rect->h);
        }
 }
@@ -832,10 +825,9 @@
        if (close)
                path_size += MOON_PATH_CLOSE_PATH_LENGTH;
 //g_warning ("PathFigure::Draw %d", path_size);
-       if (path)
-               moon_path_destroy (path);
-       path = moon_path_new (path_size);
 
+       path = moon_path_renew (path, path_size);
+
        Point *start = path_figure_get_start_point (this);
        moon_move_to (path, start->x, start->y);
        

Modified: trunk/moon/src/moon-path.c
===================================================================
--- trunk/moon/src/moon-path.c  2007-09-20 14:56:27 UTC (rev 86064)
+++ trunk/moon/src/moon-path.c  2007-09-20 15:25:36 UTC (rev 86065)
@@ -1,8 +1,27 @@
+/*
+ * moon-path.c: Path-based API, similar to cairo but without requiring a 
cairo_context_t
+ *
+ * Author:
+ *     Sebastien Pouliot  <[EMAIL PROTECTED]>
+ *
+ * Copyright 2007 Novell, Inc. (http://www.novell.com)
+ *
+ * See the LICENSE file included with the distribution for details.
+ * 
+ */
 
-
 #include "moon-path.h"
 
-
+/**
+ * moon_path_new:
+ * @size: the number of items to hold
+ *
+ * The number of items varies for each operation (MOVE_TO, LINE_TO,
+ * CURVE_TO and CLOSE_PATH). The caller has the responsability to
+ * calculate the required number of items.
+ *
+ * Return value: the allocated #moon_path
+ **/
 moon_path*
 moon_path_new (int size)
 {
@@ -14,9 +33,64 @@
        return path;
 }
 
+/**
+ * moon_path_renew:
+ * @path: an existing #moon_path or NULL
+ * @size: the number of items to hold
+ *
+ * The number of items varies for each operation (MOVE_TO, LINE_TO,
+ * CURVE_TO and CLOSE_PATH). The caller has the responsability to
+ * calculate the required number of items.
+ *
+ * Return value: the existing #moon_path (if large enough) or a new one
+ **/
+moon_path*
+moon_path_renew (moon_path* path, int size)
+{
+       if (!path)
+               return moon_path_new (size);
+
+       if (path->allocated < size) {
+               /* not enough space, destroy and recreate */
+               moon_path_destroy (path);
+               return moon_path_new (size);
+       }
+
+       /* we can reuse the already allocated structure */
+       moon_path_clear (path);
+       return path;
+}
+
+/**
+ * moon_path_clear:
+ * @path: an existing #moon_path
+ *
+ * Clear the #moon_path structure so it can be reused for a path
+ * of the same size.
+ **/
 void
+moon_path_clear (moon_path* path)
+{
+       if (!path)
+               g_warning ("mono_path_clear(NULL)");
+
+       path->cairo.status = CAIRO_STATUS_SUCCESS;
+       memset (path->cairo.data, 0, path->allocated * sizeof 
(cairo_path_data_t));
+       path->cairo.num_data = 0;
+}
+
+/**
+ * moon_path_destroy:
+ * @path: a #moon_path
+ *
+ * Free the specified #moon_path
+ **/
+void
 moon_path_destroy (moon_path* path)
 {
+       if (!path)
+               g_warning ("mono_path_destory(NULL)");
+
        if (path->allocated > 0)
                g_free (path->cairo.data);
        g_free (path);
@@ -24,6 +98,15 @@
 
 #define CHECK_SPACE(path,size) (path->cairo.num_data + size <= path->allocated)
 
+/**
+ * moon_get_current_point:
+ * @path: a #moon_path
+ * @x: pointer to a double (x coordinate)
+ * @y: pointer to a double (y coordinate)
+ *
+ * Get the current point (x,y) on the moon_path. By default (empty path)
+ * this is (0,0)
+ **/
 void
 moon_get_current_point (moon_path *path, double *x, double *y)
 {
@@ -43,7 +126,14 @@
        }
 }
 
-
+/**
+ * moon_move_to:
+ * @path: a #moon_path
+ * @x: a double with the x coordinate
+ * @y: a double with the y coordinate
+ *
+ * Record a move operation to x,y in the #moon_path.
+ **/
 void
 moon_move_to (moon_path *path, double x, double y)
 {
@@ -62,6 +152,14 @@
        path->cairo.num_data += MOON_PATH_MOVE_TO_LENGTH;
 }
 
+/**
+ * moon_line_to:
+ * @path: a #moon_path
+ * @x: a double with the x coordinate
+ * @y: a double with the y coordinate
+ *
+ * Record a line operation to x,y in the #moon_path.
+ **/
 void
 moon_line_to (moon_path *path, double x, double y)
 {
@@ -80,6 +178,15 @@
        path->cairo.num_data += MOON_PATH_MOVE_TO_LENGTH;
 }
 
+/**
+ * moon_curve_to:
+ * @path: a #moon_path
+ * @x: a double with the x coordinate
+ * @y: a double with the y coordinate
+ *
+ * Record a cubic bezier curve operation (x1,y1 x2,y2 x3,y3) 
+ * in the #moon_path.
+ **/
 void
 moon_curve_to (moon_path *path, double x1, double y1, double x2, double y2, 
double x3, double y3)
 {
@@ -104,6 +211,17 @@
        path->cairo.num_data += MOON_PATH_CURVE_TO_LENGTH;
 }
 
+/**
+ * moon_ellipse:
+ * @path: a #moon_path
+ * @x: a double with the left-most coordinate of the ellipse
+ * @y: a double with the top-most coordinate of the ellipse
+ * @w: a double with the width of the ellipse
+ * @h: a double with the height of the ellipse
+ *
+ * Record a series of basic operations that correspond to an ellipse in
+ * the #moon_path. Note that the x,y aren't the center of the ellipse.
+ **/
 void
 moon_ellipse (moon_path *path, double x, double y, double w, double h)
 {
@@ -180,6 +298,17 @@
        path->cairo.num_data += MOON_PATH_ELLIPSE_LENGTH;
 }
 
+/**
+ * moon_rectangle:
+ * @path: a #moon_path
+ * @x: a double with the left-most coordinate of the rectangle
+ * @y: a double with the top-most coordinate of the rectangle
+ * @w: a double with the width of the rectangle
+ * @h: a double with the height of the rectangle
+ *
+ * Record a series of basic operations that correspond to a rectangle 
+ * in the #moon_path.
+ **/
 void
 moon_rectangle (moon_path *path, double x, double y, double w, double h)
 {
@@ -219,6 +348,19 @@
        path->cairo.num_data += MOON_PATH_RECTANGLE_LENGTH;
 }
 
+/**
+ * moon_rounded_rectangle:
+ * @path: a #moon_path
+ * @x: a double with the left-most coordinate of the rectangle
+ * @y: a double with the top-most coordinate of the rectangle
+ * @w: a double with the width of the rectangle
+ * @h: a double with the height of the rectangle
+ * @radius_x: a double with the x radius of the rounded corner
+ * @radius_y: a double with the y radius of the rounded corner
+ *
+ * Record a series of basic operations that correspond to a rectangle 
+ * with rounded corners in the #moon_path.
+ **/
 void
 moon_rounded_rectangle (moon_path *path, double x, double y, double w, double 
h, double radius_x, double radius_y)
 {
@@ -328,6 +470,12 @@
        path->cairo.num_data += MOON_PATH_ROUNDED_RECTANGLE_LENGTH;
 }
 
+/**
+ * moon_close_path:
+ * @path: a #moon_path
+ *
+ * Record a close operation in the #moon_path.
+ **/
 void
 moon_close_path (moon_path *path)
 {
@@ -343,10 +491,17 @@
        path->cairo.num_data += MOON_PATH_CLOSE_PATH_LENGTH;
 }
 
+/**
+ * cairo_path_display:
+ * @path: a #cairo_path_t
+ *
+ * Display the content of the #cairo_path_t on the console.
+ * For debugging purpose only.
+ **/
 void
 cairo_path_display (cairo_path_t *path)
 {
-#if TRUE
+#if FALSE
        int i = 0;
        g_warning ("path %p status %d, num_data %d", path, path->status, 
path->num_data);
        for (; i < path->num_data; i+= path->data[i].header.length) {
@@ -370,6 +525,13 @@
 #endif
 }
 
+/**
+ * moon_path_display:
+ * @path: a #moon_path
+ *
+ * Display the content of the #moon_path on the console.
+ * For debugging purpose only.
+ **/
 void
 moon_path_display (moon_path *path)
 {

Modified: trunk/moon/src/moon-path.h
===================================================================
--- trunk/moon/src/moon-path.h  2007-09-20 14:56:27 UTC (rev 86064)
+++ trunk/moon/src/moon-path.h  2007-09-20 15:25:36 UTC (rev 86065)
@@ -14,6 +14,7 @@
 #define __MOON_PATH_H__
 
 #include <math.h>
+#include <string.h>
 #include <glib.h>
 #include <cairo.h>
 
@@ -42,6 +43,8 @@
  */
 
 moon_path*     moon_path_new (int size);
+moon_path*     moon_path_renew (moon_path* path, int size);
+void           moon_path_clear (moon_path* path);
 void           moon_path_destroy (moon_path* path);
 void           moon_get_current_point (moon_path *path, double *x, double *y);
 void           moon_move_to (moon_path *path, double x, double y);

Modified: trunk/moon/src/shape.cpp
===================================================================
--- trunk/moon/src/shape.cpp    2007-09-20 14:56:27 UTC (rev 86064)
+++ trunk/moon/src/shape.cpp    2007-09-20 15:25:36 UTC (rev 86065)
@@ -109,13 +109,13 @@
                fill->Detach (NULL, this);
                fill->unref ();
        }
-       InvalidatePathCache ();
+       InvalidatePathCache (true);
 }
 
 void
 Shape::Draw (cairo_t *cr)
 {
-       if (!path)
+       if (!path || (path->cairo.num_data == 0))
                BuildPath ();
 
        cairo_new_path (cr);
@@ -409,12 +409,16 @@
 
 
 void
-Shape::InvalidatePathCache ()
+Shape::InvalidatePathCache (bool free)
 {
        SetShapeFlags (UIElement::SHAPE_NORMAL);
        if (path) {
-               moon_path_destroy (path);
-               path = NULL;
+               if (free) {
+                       moon_path_destroy (path);
+                       path = NULL;
+               } else {
+                       moon_path_clear (path);
+               }
        }
 }
 
@@ -652,15 +656,12 @@
        }
 
 shape:
-       if (path)
-               moon_path_destroy (path);
-
        if (IsDegenerate ()) {
                double radius = t / 2;
-               path = moon_path_new (MOON_PATH_ROUNDED_RECTANGLE_LENGTH);
+               path = moon_path_renew (path, 
MOON_PATH_ROUNDED_RECTANGLE_LENGTH);
                moon_rounded_rectangle (path, x, y, w, h, radius, radius);
        } else {
-               path = moon_path_new (MOON_PATH_ELLIPSE_LENGTH);
+               path = moon_path_renew (path, MOON_PATH_ELLIPSE_LENGTH);
                moon_ellipse (path, x, y, w, h);
        }
        // note: both moon_rounded_rectangle and moon_ellipse close the path
@@ -840,14 +841,12 @@
        SetShapeFlags (UIElement::SHAPE_NORMAL);
 
 shape:
-       if (path)
-               moon_path_destroy (path);
        // rounded-corner rectangle ?
        if (round) {
-               path = moon_path_new (MOON_PATH_ROUNDED_RECTANGLE_LENGTH);
+               path = moon_path_renew (path, 
MOON_PATH_ROUNDED_RECTANGLE_LENGTH);
                moon_rounded_rectangle (path, x, y, w, h, radius_x, radius_y);
        } else {
-               path = moon_path_new (MOON_PATH_RECTANGLE_LENGTH);
+               path = moon_path_renew (path, MOON_PATH_RECTANGLE_LENGTH);
                moon_rectangle (path, x, y, w, h);
        }
 }
@@ -856,15 +855,20 @@
 Rectangle::OnPropertyChanged (DependencyProperty *prop)
 {
        if (prop->type != Type::RECTANGLE) {
+               if (prop == Shape::StretchProperty) {
+                       InvalidatePathCache ();
+                       UpdateBounds (true);
+               }
                Shape::OnPropertyChanged (prop);
                return;
        }
 
-       if ((prop == Rectangle::RadiusXProperty) || (prop == 
Rectangle::RadiusYProperty))
+       if ((prop == Rectangle::RadiusXProperty) || (prop == 
Rectangle::RadiusYProperty)) {
                InvalidatePathCache ();
-       
+               // note: changing the X and/or Y radius doesn't affect the 
bounds
+       }
+
        Invalidate ();
-
        NotifyAttacheesOfPropertyChange (prop);
 }
 
@@ -917,6 +921,14 @@
 //
 // Line
 //
+// rules
+// * the internal path must be rebuilt when
+//     - Line::X1Property, Line::Y1Property, Line::X2Property or 
Line::Y2Property is changed
+//
+// * bounds calculation is based on
+//     - Line::X1Property, Line::Y1Property, Line::X2Property and 
Line::Y2Property
+//     - Shape::StrokeThickness
+//
 
 DependencyProperty* Line::X1Property;
 DependencyProperty* Line::Y1Property;
@@ -1115,6 +1127,16 @@
 //
 // Polygon
 //
+// rules
+// * the internal path must be rebuilt when
+//     - Polygon::PointsProperty is changed
+//     - Shape::StretchProperty is changed
+//
+// * bounds calculation is based on
+//     - Polygon::PointsProperty
+//     - Shape::StretchProperty
+//     - Shape::StrokeThickness
+//
 
 DependencyProperty* Polygon::FillRuleProperty;
 DependencyProperty* Polygon::PointsProperty;
@@ -1326,10 +1348,8 @@
 
        SetShapeFlags (UIElement::SHAPE_NORMAL);
 
-       if (path)
-               moon_path_destroy (path);
        // 2 data per [move|line]_to + 1 for close path
-       path = moon_path_new (count * 2 + 1);
+       path = moon_path_renew (path, count * 2 + 1);
 
        // special case, both the starting and ending points are 5 * thickness 
than the actual points
        if (count == 2) {
@@ -1387,6 +1407,7 @@
 Polygon::OnCollectionChanged (Collection *col, CollectionChangeType type, 
DependencyObject *obj, DependencyProperty *prop)
 {
        UpdateBounds (true);
+       Invalidate ();
 }
 
 FillRule
@@ -1519,10 +1540,8 @@
 
        SetShapeFlags (UIElement::SHAPE_NORMAL);
 
-       if (path)
-               moon_path_destroy (path);
        // 2 data per [move|line]_to
-       path = moon_path_new (count * 2);
+       path = moon_path_renew (path, count * 2);
 
        Stretch stretch = shape_get_stretch (this);
        switch (stretch) {
@@ -1628,6 +1647,13 @@
 void
 Path::ComputeBounds ()
 {
+#if FALSE
+       Geometry* geometry = path_get_data (this);
+       if (geometry)
+               bounds = geometry->ComputeBounds (this);
+       else
+               bounds = Rect (0.0, 0.0, 0.0, 0.0);
+#else
        if (IsEmpty ()) {
                bounds = Rect (0.0, 0.0, 0.0, 0.0);
                return;
@@ -1654,6 +1680,7 @@
        bounds = Rect (x1, y1, x2-x1, y2-y1);
 
        measuring_context_destroy (cr);
+#endif
 }
 
 void

Modified: trunk/moon/src/shape.h
===================================================================
--- trunk/moon/src/shape.h      2007-09-20 14:56:27 UTC (rev 86064)
+++ trunk/moon/src/shape.h      2007-09-20 15:25:36 UTC (rev 86065)
@@ -37,7 +37,7 @@
        void DoDraw (cairo_t *cr, bool do_op, bool consider_fill);
 
        moon_path *path;
-       virtual void InvalidatePathCache ();
+       virtual void InvalidatePathCache (bool free = false);
  public: 
        static DependencyProperty* FillProperty;
        static DependencyProperty* StretchProperty;
@@ -167,7 +167,7 @@
 // 
 class Line : public Shape {
  protected:
-       virtual void InvalidatePathCache () {};
+       virtual void InvalidatePathCache (bool free) {};
  public:
        static DependencyProperty* X1Property;
        static DependencyProperty* Y1Property;

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to