Public feed #892506

Something

public text v1 · immutable
Raw Edit
·published 2008-02-05 14:20 UTC
rendered paste body
Index: moon-path.c
===================================================================
--- moon-path.c	(revision 94771)
+++ moon-path.c	(working copy)
@@ -547,6 +547,89 @@
 }
 
 /**
+ * moon_get_origin
+ * @path: a #moon_path
+ * @ox: a pointer to the double for the minimal X value of the path
+ * @oy: a pointer to the double for the minimal Y value of the path
+ *
+ * Get the origin point of the path.
+ **/
+void
+moon_get_origin (moon_path *path, double *ox, double *oy)
+{
+	int i = 0;
+	double x = 0.0, y = 0.0;
+	cairo_path_t *c_path;
+
+	g_return_if_fail (path != NULL);
+
+	c_path = &path->cairo;
+	for (; i < c_path->num_data; i+= c_path->data[i].header.length) {
+		cairo_path_data_t *data = &c_path->data[i];
+		switch (data->header.type) {
+		case CAIRO_PATH_CURVE_TO:
+			if (i == 0) {
+				x = data[1].point.x; 
+				y = data[1].point.y; 
+			} else {
+				x = MIN (x, data[1].point.x);
+				y = MIN (y, data[1].point.y);
+			}
+			x = MIN (x, data[2].point.x);
+			y = MIN (y, data[2].point.y);
+			x = MIN (x, data[3].point.x);
+			y = MIN (y, data[3].point.y);
+			break;
+		case CAIRO_PATH_LINE_TO:
+		case CAIRO_PATH_MOVE_TO:
+			if (i == 0) {
+				x = data[1].point.x; 
+				y = data[1].point.y; 
+			} else {
+				x = MIN (x, data[1].point.x);
+				y = MIN (y, data[1].point.y);
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (*ox) *ox = x;
+	if (*oy) *oy = y;
+}
+
+/**
+ * moon_merge:
+ * @path: a #moon_path
+ * @subpath: the #moon_path to merge into path
+ *
+ * Merge 'subpath' into 'path'.
+ **/
+void
+moon_merge (moon_path *path, moon_path *subpath)
+{
+	cairo_path_data_t *data = path->cairo.data;
+	int pos = path->cairo.num_data;
+	int n = 1;
+	
+	g_return_if_fail (path != NULL);
+	g_return_if_fail (subpath != NULL);
+	
+	if (!CHECK_SPACE (path, MOON_PATH_ROUNDED_RECTANGLE_LENGTH)) {
+		while (n < pos + subpath->cairo.num_data)
+			n <<= 1;
+		
+		data = g_realloc (data, sizeof (cairo_path_data_t) * n);
+		path->cairo.data = data;
+		path->allocated = n;
+	}
+
+	memcpy (&data [pos], subpath->cairo.data, subpath->cairo.num_data * sizeof (cairo_path_data_t));
+	path->cairo.num_data += subpath->cairo.num_data;
+}
+
+/**
  * cairo_path_display:
  * @path: a #cairo_path_t
  *
Index: moon-path.h
===================================================================
--- moon-path.h	(revision 94771)
+++ moon-path.h	(working copy)
@@ -54,6 +54,8 @@
 void		moon_rectangle (moon_path *path, double x, double y, double w, double h);
 void		moon_rounded_rectangle (moon_path *path, double x, double y, double w, double h, double radius_x, double radius_y);
 void		moon_close_path (moon_path *path);
+void		moon_get_origin (moon_path *path, double *ox, double *oy);
+void		moon_merge (moon_path *path, moon_path *subpath);
 
 // for debugging purpose
 void		cairo_path_display (cairo_path_t *path);
Index: geometry.h
===================================================================
--- geometry.h	(revision 94771)
+++ geometry.h	(working copy)
@@ -53,6 +53,8 @@
 	virtual void Draw (Path *path, cairo_t *cr);
 	virtual Rect ComputeBounds (Path *path) { return Rect (0.0, 0.0, 0.0, 0.0); };
 
+	virtual Point GetOriginPoint (Path *path);
+
 	virtual bool IsFilled () { return true; };
 
 	virtual void Build (Path *path) {}
@@ -157,6 +159,8 @@
 //
 /* @ContentProperty="Figures" */
 class PathGeometry : public Geometry {
+ protected:
+	virtual void Build (Path *path);
  public:
 	static DependencyProperty* FiguresProperty;
 
@@ -164,7 +168,6 @@
 	virtual Type::Kind GetObjectType () { return Type::PATHGEOMETRY; };
 
 	virtual void OnCollectionChanged (Collection *col, CollectionChangeType type, DependencyObject *obj, DependencyProperty *prop);
-	virtual void Draw (Path *path, cairo_t *cr);
 	virtual Rect ComputeBounds (Path *path);
 
 	// this is an element-by-element decision
@@ -216,14 +219,13 @@
 //
 /* @ContentProperty="Segments" */
 class PathFigure : public DependencyObject {
- protected:
-	int path_size;
-	moon_path *path;
  public:
 	static DependencyProperty* IsClosedProperty;
 	static DependencyProperty* SegmentsProperty;
 	static DependencyProperty* StartPointProperty;
 
+	moon_path *path;
+
 	PathFigure ();
 	virtual ~PathFigure ();
 	virtual Type::Kind GetObjectType () { return Type::PATHFIGURE; };
Index: geometry.cpp
===================================================================
--- geometry.cpp	(revision 94771)
+++ geometry.cpp	(working copy)
@@ -185,6 +185,19 @@
 	return bounds;
 }
 
+Point
+Geometry::GetOriginPoint (Path *shape)
+{
+	double x = 0.0;
+	double y = 0.0;
+
+	if (!path || (path->cairo.num_data == 0))
+		Build (shape);
+
+	moon_get_origin (path, &x, &y);
+	return Point (x, y);
+}
+
 GeometryCollection*
 geometry_group_get_children (GeometryGroup *geometry_group)
 {
@@ -408,27 +421,21 @@
 }
 
 void
-PathGeometry::Draw (Path *shape, cairo_t *cr)
+PathGeometry::Build (Path *shape)
 {
-	cairo_set_fill_rule (cr, convert_fill_rule (geometry_get_fill_rule (this)));
-	Transform* transform = geometry_get_transform (this);
-	if (transform) {
-		cairo_matrix_t matrix;
-		transform->GetTransform (&matrix);
-		cairo_transform (cr, &matrix);
-	}
-
 	Value *v = GetValue (PathGeometry::FiguresProperty);
 	if (!v)
 		return;
 
+	path = moon_path_renew (path, 0);
+
 	PathFigureCollection *children = v->AsPathFigureCollection();
 	Collection::Node *node = (Collection::Node *) children->list->First ();
 	for ( ; node != NULL; node = (Collection::Node *) node->next) {
 		PathFigure *pf = (PathFigure *) node->obj;
 		if (!pf->IsBuilt ())
 			pf->Build (shape);
-		cairo_append_path (cr, pf->GetCairoPath ());
+		moon_merge (path, pf->path);
 	}
 }
 
@@ -599,7 +606,6 @@
 PathFigure::PathFigure ()
 {
 	path = NULL;
-	path_size = 0;
 	this->SetValue (PathFigure::SegmentsProperty, Value::CreateUnref (new PathSegmentCollection ()));
 }
 
@@ -638,7 +644,7 @@
 	PathSegmentCollection *children = GetValue (PathFigure::SegmentsProperty)->AsPathSegmentCollection ();
 	Collection::Node *node;
 
-	path_size = MOON_PATH_MOVE_TO_LENGTH;
+	int path_size = MOON_PATH_MOVE_TO_LENGTH;
 	node = (Collection::Node *) children->list->First ();
 	for ( ; node != NULL; node = (Collection::Node *) node->next) {
 		PathSegment *ps = (PathSegment *) node->obj;
@@ -670,7 +676,6 @@
 		Build (shape);
 
 	return path_get_bounds (shape, &path->cairo);
-
 }
 
 bool