diff --git a/src/display/curve.cpp b/src/display/curve.cpp
index 0b560883bd367b2df6de89107e12821469e87fcd..303d1bb4d26bacb5831896628858c8011c0e5d9b 100644 (file)
--- a/src/display/curve.cpp
+++ b/src/display/curve.cpp
}
SPCurve *
-SPCurve::new_from_rect(Geom::Rect const &rect)
+SPCurve::new_from_rect(Geom::Rect const &rect, bool all_four_sides)
{
SPCurve *c = new SPCurve();
Geom::Point p = rect.corner(0);
c->moveto(p);
- for (int i=3; i>=0; i--) {
+ for (int i=3; i>=1; i--) {
c->lineto(rect.corner(i));
}
- c->closepath_current();
+
+ if (all_four_sides) {
+ // When _constrained_ snapping to a path, the 2geom::SimpleCrosser will be invoked which doesn't consider the closing segment.
+ // of a path. Consequently, in case we want to snap to for example the page border, we must provide all four sides of the
+ // rectangle explicitly
+ c->lineto(rect.corner(0));
+ } else {
+ // ... instead of just three plus a closing segment
+ c->closepath();
+ }
return c;
}
}
/**
* Perform a moveto to a point, thus starting a new subpath.
+ * Point p must be finite.
*/
void
SPCurve::moveto(Geom::Point const &p)
}
/**
- * Calls SPCurve::lineto() with a point's coordinates.
+ * Adds a line to the current subpath.
+ * Point p must be finite.
*/
void
SPCurve::lineto(Geom::Point const &p)
{
- if (_pathv.empty()) g_message("SPCurve::lineto path is empty!");
+ if (_pathv.empty()) g_message("SPCurve::lineto - path is empty!");
else _pathv.back().appendNew<Geom::LineSegment>( p );
}
/**
- * Adds a line to the current subpath.
+ * Calls SPCurve::lineto( Geom::Point(x,y) )
*/
void
SPCurve::lineto(gdouble x, gdouble y)
}
/**
- * Calls SPCurve::curveto() with coordinates of three points.
+ * Adds a quadratic bezier segment to the current subpath.
+ * All points must be finite.
+ */
+void
+SPCurve::quadto(Geom::Point const &p1, Geom::Point const &p2)
+{
+ if (_pathv.empty()) g_message("SPCurve::quadto - path is empty!");
+ else _pathv.back().appendNew<Geom::QuadraticBezier>( p1, p2);
+}
+/**
+ * Calls SPCurve::quadto( Geom::Point(x1,y1), Geom::Point(x2,y2) )
+ * All coordinates must be finite.
+ */
+void
+SPCurve::quadto(gdouble x1, gdouble y1, gdouble x2, gdouble y2)
+{
+ quadto( Geom::Point(x1,y1), Geom::Point(x2,y2) );
+}
+
+/**
+ * Adds a bezier segment to the current subpath.
+ * All points must be finite.
*/
void
SPCurve::curveto(Geom::Point const &p0, Geom::Point const &p1, Geom::Point const &p2)
{
- if (_pathv.empty()) g_message("SPCurve::lineto path is empty!");
+ if (_pathv.empty()) g_message("SPCurve::curveto - path is empty!");
else _pathv.back().appendNew<Geom::CubicBezier>( p0, p1, p2 );
}
/**
- * Adds a bezier segment to the current subpath.
+ * Calls SPCurve::curveto( Geom::Point(x0,y0), Geom::Point(x1,y1), Geom::Point(x2,y2) )
+ * All coordinates must be finite.
*/
void
SPCurve::curveto(gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2)
void
SPCurve::closepath_current()
{
- _pathv.back().setFinal(_pathv.back().initialPoint());
+ if (_pathv.back().size() > 0 && dynamic_cast<Geom::LineSegment const *>(&_pathv.back().back_open())) {
+ _pathv.back().erase_last();
+ } else {
+ _pathv.back().setFinal(_pathv.back().initialPoint());
+ }
_pathv.back().close(true);
}
/**
* returns the number of nodes in a path, used for statusbar text when selecting an spcurve.
+ * Sum of nodes in all the paths. When a path is closed, and its closing line segment is of zero-length,
+ * this function will not count the closing knot double (so basically ignores the closing line segment when it has zero length)
*/
guint
SPCurve::nodes_in_path() const
nr += (*it).size();
nr++; // count last node (this works also for closed paths because although they don't have a 'last node', they do have an extra segment
+
+ // do not count closing knot double for zero-length closing line segments
+ // however, if the path is only a moveto, and is closed, do not subtract 1 (otherwise the result will be zero nodes)
+ if ( it->closed()
+ && ((*it).size() != 0) )
+ {
+ Geom::Curve const &c = it->back_closed();
+ if (are_near(c.initialPoint(), c.finalPoint())) {
+ nr--;
+ }
+ }
}
return nr;
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :