Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / extension / internal / pov-out.cpp
index f30cbc317a4413cd6b07270bd2542a15c3bfc86e..a130b692354142786208ac3b1bd8fcfe97aa75bd 100644 (file)
@@ -10,6 +10,7 @@
  *
  * Authors:
  *   Bob Jamison <ishmal@inkscape.org>
+ *   Abhishek Sharma
  *
  * Copyright (C) 2004-2008 Authors
  *
@@ -300,17 +301,31 @@ bool PovOutput::doCurve(SPItem *item, const String &id)
     povShapes.push_back(shapeInfo); //passed all tests.  save the info
 
     // convert the path to only lineto's and cubic curveto's:
-    Geom::Matrix tf = sp_item_i2d_affine(item);
+    Geom::Matrix tf = item->i2d_affine();
     Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers( curve->get_pathvector() * tf );
 
-    //Count the NR_CURVETOs/LINETOs (including closing line segment)
+    /*
+     * We need to know the number of segments (NR_CURVETOs/LINETOs, including
+     * closing line segment) before we write out segment data. Since we are
+     * going to skip degenerate (zero length) paths, we need to loop over all
+     * subpaths and segments first.
+     */
     int segmentCount = 0;
-    for(Geom::PathVector::const_iterator it = pathv.begin(); it != pathv.end(); ++it)
-           {
-        segmentCount += (*it).size();
-        if (it->closed())
-            segmentCount += 1;
+    /**
+     * For all Subpaths in the <path>
+     */
+    for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit)
+    {
+        /**
+         * For all segments in the subpath, including extra closing segment defined by 2geom
+         */
+        for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_closed(); ++cit)
+        {
+
+            // Skip zero length segments.
+            if( !cit->isDegenerate() ) ++segmentCount;
         }
+    }
 
     out("/*###################################################\n");
     out("### PRISM:  %s\n", id.c_str());
@@ -326,24 +341,28 @@ bool PovOutput::doCurve(SPItem *item, const String &id)
     nrSegments += segmentCount;
 
     /**
-     *  at moment of writing, 2geom lacks proper initialization of empty intervals in rect...
-     */     
-    Geom::Rect cminmax( pathv.front().initialPoint(), pathv.front().initialPoint() ); 
-   
-   
+     *   at moment of writing, 2geom lacks proper initialization of empty intervals in rect...
+     */
+    Geom::Rect cminmax( pathv.front().initialPoint(), pathv.front().initialPoint() );
+
+
     /**
      * For all Subpaths in the <path>
-     */             
+     */
     for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit)
         {
 
         cminmax.expandTo(pit->initialPoint());
 
         /**
-         * For all segments in the subpath
-         */                     
+         * For all segments in the subpath, including extra closing segment defined by 2geom
+         */
         for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_closed(); ++cit)
-                   {
+            {
+
+            // Skip zero length segments
+            if( cit->isDegenerate() )
+                continue;
 
             if( is_straight_curve(*cit) )
                 {
@@ -354,7 +373,7 @@ bool PovOutput::doCurve(SPItem *item, const String &id)
                 nrNodes += 8;
                 }
             else if(Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const*>(&*cit))
-                           {
+            {
                 std::vector<Geom::Point> points = cubic->points();
                 Geom::Point p0 = points[0];
                 Geom::Point p1 = points[1];
@@ -365,7 +384,7 @@ bool PovOutput::doCurve(SPItem *item, const String &id)
                 nrNodes += 8;
                 }
             else
-                           {
+            {
                 err("logical error, because pathv_to_linear_and_cubic_beziers was used");
                 return false;
                 }
@@ -374,6 +393,11 @@ bool PovOutput::doCurve(SPItem *item, const String &id)
                 out(",\n");
             else
                 out("\n");
+            if (segmentNr > segmentCount)
+                {
+                err("Too many segments");
+                return false;
+                }
 
             cminmax.expandTo(cit->finalPoint());
 
@@ -421,7 +445,7 @@ bool PovOutput::doTreeRecursive(SPDocument *doc, SPObject *obj)
 {
 
     String id;
-    if (!obj->id)
+    if (!obj->getId())
         {
         char buf[16];
         sprintf(buf, "id%d", idIndex++);
@@ -429,7 +453,7 @@ bool PovOutput::doTreeRecursive(SPDocument *doc, SPObject *obj)
         }
     else
         {
-        id = obj->id;
+            id = obj->getId();
         }
 
     if (SP_IS_ITEM(obj))
@@ -444,9 +468,9 @@ bool PovOutput::doTreeRecursive(SPDocument *doc, SPObject *obj)
      */
     for (SPObject *child = obj->firstChild() ; child ; child = child->next)
         {
-               if (!doTreeRecursive(doc, child))
-                   return false;
-               }
+            if (!doTreeRecursive(doc, child))
+                return false;
+        }
 
     return true;
 }
@@ -587,7 +611,7 @@ void PovOutput::saveDocument(SPDocument *doc, gchar const *filename_utf8)
         err("Could not output curves for %s", filename_utf8);
         return;
         }
-        
+
     String curveBuf = outbuf;
     outbuf.clear();
 
@@ -704,4 +728,4 @@ PovOutput::init()
   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 :