Code

Make curvature work again by fixing a minor omission
[inkscape.git] / src / display / curve.cpp
index 0b560883bd367b2df6de89107e12821469e87fcd..7d7dbc987664c417bb894503eccc40695d6c45a6 100644 (file)
@@ -200,6 +200,7 @@ SPCurve::moveto(gdouble x, gdouble y)
 }
 /**
  * Perform a moveto to a point, thus starting a new subpath.
+ * Point p must be finite.
  */
 void
 SPCurve::moveto(Geom::Point const &p)
@@ -209,16 +210,17 @@ 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)
@@ -227,16 +229,38 @@ 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)
@@ -593,6 +617,8 @@ SPCurve::move_endpoints(Geom::Point const &new_p0, Geom::Point const &new_p1)
 
 /**
  * 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
@@ -602,6 +628,17 @@ 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;