Author: spouliot
Date: 2007-09-25 18:54:28 -0400 (Tue, 25 Sep 2007)
New Revision: 86370

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

        * geometry.h|cpp, shape.cpp: Implement GetBounds without a cairo 
        context.



Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog    2007-09-25 22:46:51 UTC (rev 86369)
+++ trunk/moon/src/ChangeLog    2007-09-25 22:54:28 UTC (rev 86370)
@@ -1,3 +1,8 @@
+2007-09-25  Sebastien Pouliot  <[EMAIL PROTECTED]>
+
+       * geometry.h|cpp, shape.cpp: Implement GetBounds without a cairo 
+       context.
+
 2007-09-26  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * text.cpp (TextBlock): Set an empty string as a default Text property.

Modified: trunk/moon/src/geometry.cpp
===================================================================
--- trunk/moon/src/geometry.cpp 2007-09-25 22:46:51 UTC (rev 86369)
+++ trunk/moon/src/geometry.cpp 2007-09-25 22:54:28 UTC (rev 86370)
@@ -58,6 +58,12 @@
        geometry->SetValue (Geometry::TransformProperty, Value (transform));
 }
 
+Geometry::~Geometry ()
+{
+       if (path)
+               moon_path_destroy (path);
+}
+
 void
 Geometry::Draw (Path *shape, cairo_t *cr)
 {
@@ -69,7 +75,7 @@
                cairo_transform (cr, &matrix);
        }
 
-       if (!path) {
+       if (!path || (path->cairo.num_data == 0)) {
                Build (shape);
                // note: shape can be NULL when Geometry is used for clipping
                if (shape)
@@ -82,31 +88,20 @@
 void
 Geometry::OnPropertyChanged (DependencyProperty *prop)
 {
+       // no need to clear the path for Geometry itself as FillRule and 
Transform properties are 
+       // only used when drawing, i.e. they do not affect the path itself
+       if ((prop->type != Type::GEOMETRY) && path)
+               moon_path_clear (path);
+
        NotifyAttacheesOfPropertyChange (prop);
 }
 
 static void
-path_stretch_adjust (Path *shape, cairo_path_t *path)
+path_get_extents (cairo_path_t *path, double *min_x, double *min_y, double 
*max_x, double *max_y)
 {
-       if (!path) {
-               shape->SetShapeFlags (UIElement::SHAPE_EMPTY);
+       if (!path)
                return;
-       }
 
-       double w = framework_element_get_width (shape);
-       double h = framework_element_get_height (shape);
-       if ((w < 0.0) || (h < 0.0)) {
-               shape->SetShapeFlags (UIElement::SHAPE_EMPTY);
-               return;
-       }
-
-       Stretch stretch = shape_get_stretch (shape);
-       if (stretch == StretchNone)
-               return;
-
-       /* NOTE: this looks complex but avoid a *lot* of changes in geometry 
-        * (resulting in something even more complex).
-        */
        double minx = G_MAXDOUBLE;
        double miny = G_MAXDOUBLE;
        double maxx = G_MINDOUBLE;
@@ -154,6 +149,37 @@
                }
        }
 
+       if (min_x) *min_x = minx;
+       if (min_y) *min_y = miny;
+       if (max_x) *max_x = maxx;
+       if (max_y) *max_y = maxy;
+}
+
+static void
+path_stretch_adjust (Path *shape, cairo_path_t *path)
+{
+       if (!path) {
+               shape->SetShapeFlags (UIElement::SHAPE_EMPTY);
+               return;
+       }
+
+       double w = framework_element_get_width (shape);
+       double h = framework_element_get_height (shape);
+       if ((w < 0.0) || (h < 0.0)) {
+               shape->SetShapeFlags (UIElement::SHAPE_EMPTY);
+               return;
+       }
+
+       Stretch stretch = shape_get_stretch (shape);
+       if (stretch == StretchNone)
+               return;
+
+       /* NOTE: this looks complex but avoid a *lot* of changes in geometry 
+        * (resulting in something even more complex).
+        */
+       double minx, maxx, miny, maxy;
+       path_get_extents (path, &minx, &miny, &maxx, &maxy);
+
        double actual_height = maxy - miny;
        double actual_width = maxx - minx;
 
@@ -270,8 +296,6 @@
                NotifyAttacheesOfPropertyChange 
(GeometryGroup::ChildrenProperty);
 }
 
-// FIXME: we should cache the path in the group (i.e. a Build method) to avoid
-// rebuilding and reapplying the strech every time
 void
 GeometryGroup::Draw (Path *shape, cairo_t *cr)
 {
@@ -310,7 +334,6 @@
        }
 }
 
-#if FALSE
 Rect
 GeometryGroup::ComputeBounds (Path *path)
 {
@@ -324,7 +347,6 @@
 //g_warning ("GeometryGroup::ComputeBounds - x %g y %g w %g h %g", bounds.x, 
bounds.y, bounds.w, bounds.h);
        return bounds;
 }
-#endif
 
 GeometryCollection*
 geometry_group_get_children (GeometryGroup *geometry_group)
@@ -431,7 +453,6 @@
        moon_ellipse (path, pt->x - rx, pt->y - ry, rx * 2.0, ry * 2.0);
 }
 
-#if FALSE
 Rect
 EllipseGeometry::ComputeBounds (Path *path)
 {
@@ -443,7 +464,6 @@
        Point *pt = ellipse_geometry_get_center (this);
        return Rect (pt->x - hw, pt->y - hh, hw * 2.0, hh * 2.0);
 }
-#endif
 
 //
 // LineGeometry
@@ -495,7 +515,6 @@
        moon_line_to (path, p2->x, p2->y);
 }
 
-#if FALSE
 Rect
 LineGeometry::ComputeBounds (Path *path)
 {
@@ -521,11 +540,11 @@
                return Rect (MIN (p1->x, p2->x), p1->y - thickness, fabs (dx), 
thickness * 2.0);
 
        // slopped line
-       double m = dy / dx;
-// FIXME
-       return Rect (MIN (p1->x, p2->x), MIN (p1->y, p2->y), fabs (dx), fabs 
(dy));
+       double m = fabs (dy / dx);
+       double tx = (m > 1.0) ? thickness : thickness * m;
+       double ty = (m < 1.0) ? thickness : thickness / m;
+       return Rect (MIN (p1->x, p2->x) - tx / 2.0, MIN (p1->y, p2->y) - ty / 
2.0, fabs (dx) + tx, fabs (dy) + ty);
 }
-#endif
 
 //
 // PathGeometry
@@ -609,7 +628,6 @@
        }
 }
 
-#if FALSE
 Rect
 PathGeometry::ComputeBounds (Path *shape)
 {
@@ -626,7 +644,6 @@
        // (e.g. arcs) adding 1.0 will cover the extra pixels used by Cairo's AA
        return bounds.GrowBy (1.0);
 }
-#endif
 
 PathFigureCollection *
 path_geometry_get_figures (PathGeometry *path_geometry)
@@ -726,7 +743,6 @@
        }
 }
 
-#if FALSE
 Rect
 RectangleGeometry::ComputeBounds (Path *path)
 {
@@ -741,7 +757,6 @@
 
        return rect->GrowBy (thickness / 2.0);
 }
-#endif
 
 bool
 RectangleGeometry::GetRadius (double *rx, double *ry)
@@ -780,6 +795,12 @@
        this->SetValue (PathFigure::SegmentsProperty, Value::CreateUnref (new 
PathSegmentCollection ()));
 }
 
+PathFigure::~PathFigure ()
+{
+       if (path)
+               moon_path_destroy (path);
+}
+
 void
 PathFigure::OnPropertyChanged (DependencyProperty *prop)
 {
@@ -798,12 +819,16 @@
                }
        }
 
+       if (path)
+               moon_path_clear (path);
        NotifyAttacheesOfPropertyChange (prop);
 }
 
 void
 PathFigure::OnCollectionChanged (Collection *col, CollectionChangeType type, 
DependencyObject *obj, DependencyProperty *prop)
 {
+       if (path)
+               moon_path_clear (path);
        // PathFigure only has one collection, so let's save the hash lookup
        //if (col == GetValue 
(PathFigure::SegmentsProperty)->AsPathSegmentCollection())
                NotifyAttacheesOfPropertyChange (PathFigure::SegmentsProperty);
@@ -824,7 +849,6 @@
        bool close = path_figure_get_is_closed (this);
        if (close)
                path_size += MOON_PATH_CLOSE_PATH_LENGTH;
-//g_warning ("PathFigure::Draw %d", path_size);
 
        path = moon_path_renew (path, path_size);
 
@@ -841,21 +865,19 @@
                moon_close_path (path);
 }
 
-#if FALSE
 Rect
 PathFigure::ComputeBounds (Path *shape)
 {
-       Rect bounds = Rect (0.0, 0.0, 0.0, 0.0);
-       PathSegmentCollection *children = GetValue 
(PathFigure::SegmentsProperty)->AsPathSegmentCollection ();
-       Collection::Node *node = (Collection::Node *) children->list->First ();
-       for ( ; node != NULL; node = (Collection::Node *) node->next) {
-               PathSegment *ps = (PathSegment *) node->obj;
-               bounds = bounds.Union (ps->ComputeBounds (path));
-       }
-//g_warning ("PathFigure::ComputeBounds - x %g y %g w %g h %g", bounds.x, 
bounds.y, bounds.w, bounds.h);
-       return bounds;
+       if (!path || (path->cairo.num_data == 0))
+               Build (shape);
+
+       double minx, miny, maxx, maxy;
+       path_get_extents (&path->cairo, &minx, &miny, &maxx, &maxy);
+
+       Rect bounds = Rect (minx, miny, maxx - minx, maxy - miny);
+       double thickness = shape_get_stroke_thickness (shape);
+       return bounds.GrowBy (thickness / 2.0);
 }
-#endif
 
 bool
 path_figure_get_is_closed (PathFigure *path_figure)
@@ -1001,7 +1023,6 @@
        rsvg_arc_to (path, size->x, size->y, angle, large, direction, p->x, 
p->y); 
 }
 
-
 //
 // BezierSegment
 //

Modified: trunk/moon/src/geometry.h
===================================================================
--- trunk/moon/src/geometry.h   2007-09-25 22:46:51 UTC (rev 86369)
+++ trunk/moon/src/geometry.h   2007-09-25 22:54:28 UTC (rev 86370)
@@ -44,12 +44,13 @@
        static DependencyProperty* TransformProperty;
 
        Geometry () : path (NULL) {};
+       ~Geometry ();
        virtual Type::Kind GetObjectType () { return Type::GEOMETRY; };
 
        virtual void OnPropertyChanged (DependencyProperty *prop);
 
        virtual void Draw (Path *path, cairo_t *cr);
-//     virtual Rect ComputeBounds (Path *path) { return Rect (0.0, 0.0, 0.0, 
0.0); };
+       virtual Rect ComputeBounds (Path *path) { return Rect (0.0, 0.0, 0.0, 
0.0); };
 
        virtual bool IsFilled () { return true; };
 
@@ -88,7 +89,7 @@
        virtual void OnCollectionChanged (Collection *col, CollectionChangeType 
type, DependencyObject *obj, DependencyProperty *prop);
 
        virtual void Draw (Path *path, cairo_t *cr);
-//     virtual Rect ComputeBounds (Path *path);
+       virtual Rect ComputeBounds (Path *path);
 };
 GeometryGroup          *geometry_group_new             ();
 GeometryCollection     *geometry_group_get_children    (GeometryGroup 
*geometry_group);
@@ -108,7 +109,7 @@
        EllipseGeometry () { };
        virtual Type::Kind GetObjectType () { return Type::ELLIPSEGEOMETRY; };
 
-//     virtual Rect ComputeBounds (Path *path);
+       virtual Rect ComputeBounds (Path *path);
 };
 EllipseGeometry* ellipse_geometry_new ();
 Point* ellipse_geometry_get_center (EllipseGeometry *ellipse_geometry);
@@ -131,7 +132,7 @@
        LineGeometry () { };
        virtual Type::Kind GetObjectType () { return Type::LINEGEOMETRY; };
 
-//     virtual Rect ComputeBounds (Path *path);
+       virtual Rect ComputeBounds (Path *path);
 };
 LineGeometry* line_geometry_new ();
 Point* line_geometry_get_end_point (LineGeometry* line_geometry);
@@ -163,7 +164,7 @@
        virtual void OnPropertyChanged (DependencyProperty *prop);
        virtual void OnCollectionChanged (Collection *col, CollectionChangeType 
type, DependencyObject *obj, DependencyProperty *prop);
        virtual void Draw (Path *path, cairo_t *cr);
-//     virtual Rect ComputeBounds (Path *path);
+       virtual Rect ComputeBounds (Path *path);
 
        // this is an element-by-element decision
        virtual bool IsFilled () { return true; }
@@ -186,7 +187,7 @@
        RectangleGeometry () { };
        virtual Type::Kind GetObjectType () { return Type::RECTANGLEGEOMETRY; };
 
-//     virtual Rect ComputeBounds (Path *path);
+       virtual Rect ComputeBounds (Path *path);
 
        bool GetRadius (double *rx, double *ry);
 };
@@ -223,6 +224,7 @@
        static DependencyProperty* StartPointProperty;
 
        PathFigure ();
+       ~PathFigure ();
        virtual Type::Kind GetObjectType () { return Type::PATHFIGURE; };
 
        virtual void OnPropertyChanged (DependencyProperty *prop);
@@ -232,7 +234,7 @@
        virtual bool IsBuilt () {return ( path != NULL); }
        virtual cairo_path_t* GetCairoPath () { return (path) ? &path->cairo : 
NULL; }
 
-//     Rect ComputeBounds (Path *shape);
+       Rect ComputeBounds (Path *shape);
 };
 PathFigure* path_figure_new ();
 bool   path_figure_get_is_closed       (PathFigure *path_figure);
@@ -252,7 +254,6 @@
 
        virtual void Append (moon_path *path) {}
        virtual int GetSize () { return 0; }
-       virtual Rect ComputeBounds (Path *shape) { return Rect (0.0, 0.0, 0.0, 
0.0); }
 
        virtual void OnPropertyChanged (DependencyProperty *prop);
 };

Modified: trunk/moon/src/shape.cpp
===================================================================
--- trunk/moon/src/shape.cpp    2007-09-25 22:46:51 UTC (rev 86369)
+++ trunk/moon/src/shape.cpp    2007-09-25 22:54:28 UTC (rev 86370)
@@ -1647,40 +1647,34 @@
 void
 Path::ComputeBounds ()
 {
-#if FALSE
        Geometry* geometry = path_get_data (this);
-       if (geometry)
-               bounds = geometry->ComputeBounds (this);
-       else
+       if (!geometry) {
                bounds = Rect (0.0, 0.0, 0.0, 0.0);
-#else
-       if (IsEmpty ()) {
-               bounds = Rect (0.0, 0.0, 0.0, 0.0);
                return;
        }
 
-       double x1, y1, x2, y2;
-       cairo_t* cr = measuring_context_create ();
+       bounds = geometry->ComputeBounds (this);
 
-       cairo_save (cr);
-       // dont do the operation
-       DoDraw (cr, false, true);
+       Stretch stretch = shape_get_stretch (this);
+       if (stretch != StretchNone) {
+               double t = shape_get_stroke_thickness (this);
+               double ht = t / -2.0;
+               bounds.x = ht;
+               bounds.y = ht;
 
-       // XXX this next call will hopefully become unnecessary in a
-       // later version of cairo.
-       cairo_identity_matrix (cr);
-       // note: a stroke brush may be present, but it doesn't means it will 
get used
-       if (stroke && (shape_get_stroke_thickness (this) > 0.0))
-               cairo_stroke_extents (cr, &x1, &y1, &x2, &y2);
-       else
-               cairo_fill_extents (cr, &x1, &y1, &x2, &y2);
+               Value *vh = GetValueNoDefault 
(FrameworkElement::HeightProperty);
+               if (vh)
+                       bounds.h = MIN (vh->AsDouble (), bounds.h);
+               
+               Value *vw = GetValueNoDefault (FrameworkElement::WidthProperty);
+               if (vw)
+                       bounds.w = MIN (vw->AsDouble (), bounds.w);
 
-       cairo_restore (cr);
+               bounds.w += t;
+               bounds.h += t;
+       }
 
-       bounds = Rect (x1, y1, x2-x1, y2-y1);
-
-       measuring_context_destroy (cr);
-#endif
+       bounds = bounding_rect_for_transformed_rect (&absolute_xform, bounds);
 }
 
 void

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

Reply via email to