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