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