Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / stable / src / modules / mod_geometry / outline.cpp
index e855e91..1b97582 100644 (file)
@@ -1,20 +1,22 @@
-/* === S I N F G =========================================================== */
-/*!    \file bline.cpp
-**     \brief Template
+/* === S Y N F I G ========================================================= */
+/*!    \file outline.cpp
+**     \brief Implementation of the "Outline" layer
 **
-**     $Id: outline.cpp,v 1.1.1.1 2005/01/04 01:23:10 darco Exp $
+**     $Id$
 **
 **     \legal
-**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007, 2008 Chris Moore
 **
-**     This software and associated documentation
-**     are CONFIDENTIAL and PROPRIETARY property of
-**     the above-mentioned copyright holder.
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
 **
-**     You may not copy, print, publish, or in any
-**     other way distribute this software without
-**     a prior written agreement with
-**     the copyright holder.
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
 **     \endlegal
 */
 /* ========================================================================= */
 #endif
 
 #include "outline.h"
-#include <sinfg/string.h>
-#include <sinfg/time.h>
-#include <sinfg/context.h>
-#include <sinfg/paramdesc.h>
-#include <sinfg/renddesc.h>
-#include <sinfg/surface.h>
-#include <sinfg/value.h>
-#include <sinfg/valuenode.h>
+#include <synfig/string.h>
+#include <synfig/time.h>
+#include <synfig/context.h>
+#include <synfig/paramdesc.h>
+#include <synfig/renddesc.h>
+#include <synfig/surface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
 
 #include <ETL/calculus>
 #include <ETL/bezier>
 #include <ETL/hermite>
 #include <vector>
 
-#include <sinfg/valuenode_bline.h>
+#include <synfig/valuenode_bline.h>
 
 #endif
 
@@ -57,22 +59,22 @@ using namespace etl;
 #define ROUND_END_FACTOR       (4)
 #define CUSP_THRESHOLD         (0.40)
 #define SPIKE_AMOUNT           (4)
-#define NO_LOOP_COOKIE         sinfg::Vector(84951305,7836658)
+#define NO_LOOP_COOKIE         synfig::Vector(84951305,7836658)
 #define EPSILON                                (0.000000001)
 #define CUSP_TANGENT_ADJUST    (0.025)
 
 /* === G L O B A L S ======================================================= */
 
-SINFG_LAYER_INIT(Outline);
-SINFG_LAYER_SET_NAME(Outline,"outline");
-SINFG_LAYER_SET_LOCAL_NAME(Outline,_("Outline"));
-SINFG_LAYER_SET_CATEGORY(Outline,_("Geometry"));
-SINFG_LAYER_SET_VERSION(Outline,"0.2");
-SINFG_LAYER_SET_CVS_ID(Outline,"$Id: outline.cpp,v 1.1.1.1 2005/01/04 01:23:10 darco Exp $");
+SYNFIG_LAYER_INIT(Outline);
+SYNFIG_LAYER_SET_NAME(Outline,"outline");
+SYNFIG_LAYER_SET_LOCAL_NAME(Outline,N_("Outline"));
+SYNFIG_LAYER_SET_CATEGORY(Outline,N_("Geometry"));
+SYNFIG_LAYER_SET_VERSION(Outline,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(Outline,"$Id$");
 
 /* === P R O C E D U R E S ================================================= */
 
-// This function was adapted from what was 
+// This function was adapted from what was
 // described on http://www.whisqu.se/per/docs/math28.htm
 Point line_intersection(
        const Point& p1,
@@ -92,24 +94,24 @@ Point line_intersection(
 
        const float x3(p2[0]+t2[0]);
        const float y3(p2[1]+t2[1]);
-       
+
        const float near_infinity((float)1e+10);
-       
+
        float m1,m2;    // the slopes of each line
-       
-       // compute slopes, note the cludge for infinity, however, this will
+
+       // compute slopes, note the kluge for infinity, however, this will
        // be close enough
-       
+
        if ((x1-x0)!=0)
           m1 = (y1-y0)/(x1-x0);
        else
           m1 = near_infinity;
-       
+
        if ((x3-x2)!=0)
           m2 = (y3-y2)/(x3-x2);
        else
           m2 = near_infinity;
-       
+
        // compute constants
        const float& a1(m1);
        const float& a2(m2);
@@ -117,11 +119,11 @@ Point line_intersection(
        const float b2(-1.0f);
        const float c1(y0-m1*x0);
        const float c2(y2-m2*x2);
-       
+
        // compute the inverse of the determinate
        const float det_inv(1.0f/(a1*b2 - a2*b1));
-       
-       // use Kramers rule to compute the intersection 
+
+       // use Kramers rule to compute the intersection
        return Point(
                ((b1*c2 - b2*c1)*det_inv),
                ((a2*c1 - a1*c2)*det_inv)
@@ -142,22 +144,22 @@ Outline::Outline()
        expand=0;
        homogeneous_width=true;
        clear();
-       
+
        vector<BLinePoint> bline_point_list;
        bline_point_list.push_back(BLinePoint());
        bline_point_list.push_back(BLinePoint());
        bline_point_list.push_back(BLinePoint());
-       bline_point_list[0].set_vertex(Point(0,1));     
-       bline_point_list[1].set_vertex(Point(0,-1));    
+       bline_point_list[0].set_vertex(Point(0,1));
+       bline_point_list[1].set_vertex(Point(0,-1));
        bline_point_list[2].set_vertex(Point(1,0));
-       bline_point_list[0].set_tangent(bline_point_list[1].get_vertex()-bline_point_list[2].get_vertex()*0.5f);        
-       bline_point_list[1].set_tangent(bline_point_list[2].get_vertex()-bline_point_list[0].get_vertex()*0.5f);        
-       bline_point_list[2].set_tangent(bline_point_list[0].get_vertex()-bline_point_list[1].get_vertex()*0.5f);        
-       bline_point_list[0].set_width(1.0f);    
-       bline_point_list[1].set_width(1.0f);    
-       bline_point_list[2].set_width(1.0f);    
+       bline_point_list[0].set_tangent(bline_point_list[1].get_vertex()-bline_point_list[2].get_vertex()*0.5f);
+       bline_point_list[1].set_tangent(bline_point_list[2].get_vertex()-bline_point_list[0].get_vertex()*0.5f);
+       bline_point_list[2].set_tangent(bline_point_list[0].get_vertex()-bline_point_list[1].get_vertex()*0.5f);
+       bline_point_list[0].set_width(1.0f);
+       bline_point_list[1].set_width(1.0f);
+       bline_point_list[2].set_width(1.0f);
        bline=bline_point_list;
-       
+
        needs_sync=true;
 }
 
@@ -170,13 +172,28 @@ void
 Outline::sync()
 {
        clear();
+
+       if (!bline.get_list().size())
+       {
+               synfig::warning(string("Outline::sync():")+N_("No vertices in outline " + string("\"") + get_description() + string("\"")));
+               return;
+       }
+               
        try {
 #if 1
-       
+
        const bool loop(bline.get_loop());
-       const vector<sinfg::BLinePoint> bline_(bline.get_list().begin(),bline.get_list().end());
+
+       ValueNode_BLine::Handle bline_valuenode;
+       if (bline.get_contained_type() == ValueBase::TYPE_SEGMENT)
+       {
+               bline_valuenode = ValueNode_BLine::create(bline);
+               bline = (*bline_valuenode)(0);
+       }
+
+       const vector<synfig::BLinePoint> bline_(bline.get_list().begin(),bline.get_list().end());
 #define bline bline_
-       
+
        vector<BLinePoint>::const_iterator
                iter,
                next(bline.begin());
@@ -187,28 +204,49 @@ Outline::sync()
        vector<Point>
                side_a,
                side_b;
-               
+
        if(loop)
                iter=--bline.end();
        else
                iter=next++;
 
+       //                              iter    next
+       //                              ----    ----
+       // looped               nth             1st
+       // !looped              1st             2nd
+
+       Vector first_tangent=bline.front().get_tangent2();
        Vector last_tangent=iter->get_tangent1();
-       
-       for(bool first=!loop;next!=end;iter=next++,first=false)
+
+       // if we are looped and drawing sharp cusps, we'll need a value for the incoming tangent
+       if (loop && sharp_cusps && last_tangent.is_equal_to(Vector::zero()))
+       {
+               hermite<Vector> curve((iter-1)->get_vertex(), iter->get_vertex(), (iter-1)->get_tangent2(), iter->get_tangent1());
+               const derivative< hermite<Vector> > deriv(curve);
+               last_tangent=deriv(1.0-CUSP_TANGENT_ADJUST);
+       }
+
+       // `first' is for making the cusps; don't do that for the first point if we're not looped
+       for(bool first=!loop; next!=end; iter=next++)
        {
                Vector prev_t(iter->get_tangent1());
                Vector iter_t(iter->get_tangent2());
                Vector next_t(next->get_tangent1());
-               
+
                bool split_flag(iter->get_split_tangent_flag());
-               
+
+               // if iter.t2 == 0 and next.t1 == 0, this is a straight line
                if(iter_t.is_equal_to(Vector::zero()) && next_t.is_equal_to(Vector::zero()))
                {
                        iter_t=next_t=next->get_vertex()-iter->get_vertex();
-                       split_flag=true;
+                       // split_flag=true;
+
+                       // if the two points are on top of each other, ignore this segment
+                       // leave `first' true if was before
+                       if (iter_t.is_equal_to(Vector::zero()))
+                               continue;
                }
-               
+
                // Setup the curve
                hermite<Vector> curve(
                        iter->get_vertex(),
@@ -216,35 +254,38 @@ Outline::sync()
                        iter_t,
                        next_t
                );
-               
+
                const float
                        iter_w((iter->get_width()*width)*0.5f+expand),
                        next_w((next->get_width()*width)*0.5f+expand);
 
                const derivative< hermite<Vector> > deriv(curve);
-               
+
+               if (first)
+                       first_tangent = deriv(CUSP_TANGENT_ADJUST);
+
                // Make cusps as necessary
                if(!first && sharp_cusps && split_flag && (!prev_t.is_equal_to(iter_t) || iter_t.is_equal_to(Vector::zero())) && !last_tangent.is_equal_to(Vector::zero()))
                {
                        Vector curr_tangent(deriv(CUSP_TANGENT_ADJUST));
-                       
+
                        const Vector t1(last_tangent.perp().norm());
                        const Vector t2(curr_tangent.perp().norm());
-                                               
+
                        Real cross(t1*t2.perp());
                        Real perp((t1-t2).mag());
-                       if(cross>CUSP_THRESHOLD)                                
+                       if(cross>CUSP_THRESHOLD)
                        {
                                const Point p1(iter->get_vertex()+t1*iter_w);
                                const Point p2(iter->get_vertex()+t2*iter_w);
-                               
+
                                side_a.push_back(line_intersection(p1,last_tangent,p2,curr_tangent));
                        }
                        else if(cross<-CUSP_THRESHOLD)
                        {
                                const Point p1(iter->get_vertex()-t1*iter_w);
                                const Point p2(iter->get_vertex()-t2*iter_w);
-                               
+
                                side_b.push_back(line_intersection(p1,last_tangent,p2,curr_tangent));
                        }
                        else if(cross>0 && perp>1)
@@ -258,16 +299,16 @@ Outline::sync()
                                float amount(max(0.0f,(float)(-cross/CUSP_THRESHOLD))*(SPIKE_AMOUNT-1)+1);
 
                                side_b.push_back(iter->get_vertex()-(t1+t2).norm()*iter_w*amount);
-                       }                       
+                       }
                }
-                               
+
                // Make the outline
                if(homogeneous_width)
                {
                        const float length(curve.length());
                        float dist(0);
                        Point lastpoint;
-                       for(float n=0.0f;n<1.0f;n+=1.0f/SAMPLES)
+                       for(float n=0.0f;n<0.999999f;n+=1.0f/SAMPLES)
                        {
                                const Vector d(deriv(n>CUSP_TANGENT_ADJUST?n:CUSP_TANGENT_ADJUST).perp().norm());
                                const Vector p(curve(n));
@@ -279,25 +320,27 @@ Outline::sync()
 
                                side_a.push_back(p+d*w);
                                side_b.push_back(p-d*w);
-                                                               
+
                                lastpoint=p;
                        }
                }
                else
-                       for(float n=0.0f;n<1.0f;n+=1.0f/SAMPLES)
+                       for(float n=0.0f;n<0.999999f;n+=1.0f/SAMPLES)
                        {
                                const Vector d(deriv(n>CUSP_TANGENT_ADJUST?n:CUSP_TANGENT_ADJUST).perp().norm());
                                const Vector p(curve(n));
                                const float w(((next_w-iter_w)*n+iter_w));
-                               
+
                                side_a.push_back(p+d*w);
                                side_b.push_back(p-d*w);
                        }
                last_tangent=deriv(1.0-CUSP_TANGENT_ADJUST);
                side_a.push_back(curve(1.0)+last_tangent.perp().norm()*next_w);
                side_b.push_back(curve(1.0)-last_tangent.perp().norm()*next_w);
+
+               first=false;
        }
-       
+
        if(loop)
        {
                reverse(side_b.begin(),side_b.end());
@@ -305,17 +348,17 @@ Outline::sync()
                add_polygon(side_b);
                return;
        }
-       
+
        // Insert code for adding end tip
-       if(round_tip[1] && !loop)
+       if(round_tip[1] && !loop && side_a.size())
        {
                // remove the last point
                side_a.pop_back();
-               
+
                const Point vertex(bline.back().get_vertex());
                const Vector tangent(last_tangent.norm());
                const float w((bline.back().get_width()*width)*0.5f+expand);
-               
+
                hermite<Vector> curve(
                        vertex+tangent.perp()*w,
                        vertex-tangent.perp()*w,
@@ -323,26 +366,23 @@ Outline::sync()
                        -tangent*w*ROUND_END_FACTOR
                );
 
-               for(float n=0.0f;n<1.0f;n+=1.0f/SAMPLES)
+               for(float n=0.0f;n<0.999999f;n+=1.0f/SAMPLES)
                        side_a.push_back(curve(n));
-
-               // remove the last point
-               side_a.pop_back();
        }
-       
+
        for(;!side_b.empty();side_b.pop_back())
                side_a.push_back(side_b.back());
 
        // Insert code for adding begin tip
-       if(round_tip[0] && !loop)
+       if(round_tip[0] && !loop && side_a.size())
        {
                // remove the last point
                side_a.pop_back();
-               
+
                const Point vertex(bline.front().get_vertex());
-               const Vector tangent(bline.front().get_tangent2().norm());
+               const Vector tangent(first_tangent.norm());
                const float w((bline.front().get_width()*width)*0.5f+expand);
-               
+
                hermite<Vector> curve(
                        vertex-tangent.perp()*w,
                        vertex+tangent.perp()*w,
@@ -350,18 +390,15 @@ Outline::sync()
                        tangent*w*ROUND_END_FACTOR
                );
 
-               for(float n=0.0f;n<1.0f;n+=1.0f/SAMPLES)
+               for(float n=0.0f;n<0.999999f;n+=1.0f/SAMPLES)
                        side_a.push_back(curve(n));
-
-               // remove the last point
-               side_a.pop_back();
        }
-       
+
        add_polygon(side_a);
-       
-       
-#else
-               
+
+
+#else /* 1 */
+
        bool loop_;
        if(bline.get_contained_type()==ValueBase::TYPE_BLINEPOINT)
        {
@@ -374,7 +411,7 @@ Outline::sync()
                }
                else
                        loop_=value.get_loop();
-               
+
                segment_list=convert_bline_to_segment_list(value);
                width_list=convert_bline_to_width_list(value);
        }
@@ -388,12 +425,12 @@ Outline::sync()
 
        if(segment_list.empty())
        {
-               sinfg::warning("Outline: segment_list is empty, layer disabled");
+               synfig::warning("Outline: segment_list is empty, layer disabled");
                clear();
                return;
        }
-       
-       
+
+
        // Repair the width list if we need to
        {
                Real default_width;
@@ -401,12 +438,12 @@ Outline::sync()
                        default_width=0.01;
                else
                        default_width=width_list.back();
-               
+
                while(width_list.size()<segment_list.size()+1)
                        width_list.push_back(default_width);
                while(width_list.size()>segment_list.size()+1)
                        width_list.pop_back();
-               
+
        }
 
        // Repair the zero tangents (if any)
@@ -418,7 +455,7 @@ Outline::sync()
                                iter->t1=iter->t2=iter->p2-iter->p1;
                }
        }
-       
+
        vector<Real>::iterator iter;
        vector<Real> scaled_width_list;
        for(iter=width_list.begin();iter!=width_list.end();++iter)
@@ -431,10 +468,10 @@ Outline::sync()
        vector<Point> vector_list;
        Vector last_tangent(segment_list.back().t2);
        clear();
-       
+
        if(!loop_)
                last_tangent=NO_LOOP_COOKIE;
-       
+
        {
                vector<Segment>::iterator iter;
                vector<Real>::iterator witer;
@@ -443,7 +480,7 @@ Outline::sync()
                        witer=scaled_width_list.begin();
                        iter!=segment_list.end();
                        ++iter,++witer)
-               {                       
+               {
                        if(iter->t1.mag_squared()<=EPSILON && iter->t2.mag_squared()<=EPSILON)
                        {
                                vector_list.push_back(iter->p1-(iter->p2-iter->p1).perp().norm()*witer[0]);
@@ -458,25 +495,25 @@ Outline::sync()
                                curve.p2()=iter->p2;
                                curve.t2()=iter->t2;
                                curve.sync();
-       
+
                                etl::derivative<etl::hermite<Vector> > deriv(curve);
-                               
+
                                // without this if statement, the broken tangents would
                                // have boxed edges
                                if(sharp_cusps && last_tangent!=NO_LOOP_COOKIE && !last_tangent.is_equal_to(iter->t1))
                                {
                                        //Vector curr_tangent(iter->t1);
                                        Vector curr_tangent(deriv(CUSP_TANGENT_ADJUST));
-                                       
+
                                        const Vector t1(last_tangent.perp().norm());
                                        const Vector t2(curr_tangent.perp().norm());
-                                       
+
                                        Point p1(iter->p1+t1*witer[0]);
                                        Point p2(iter->p1+t2*witer[0]);
-                                       
+
                                        Real cross(t1*t2.perp());
-                                       
-                                       if(cross>CUSP_THRESHOLD)                                
+
+                                       if(cross>CUSP_THRESHOLD)
                                                vector_list.push_back(line_intersection(p1,last_tangent,p2,curr_tangent));
                                        else if(cross>0)
                                        {
@@ -489,18 +526,18 @@ Outline::sync()
                                }
                                //last_tangent=iter->t2;
                                last_tangent=deriv(1.0f-CUSP_TANGENT_ADJUST);
-                               
+
                                for(n=0.0f;n<1.0f;n+=1.0f/SAMPLES)
                                        vector_list.push_back(curve(n)+deriv(n>CUSP_TANGENT_ADJUST?n:CUSP_TANGENT_ADJUST).perp().norm()*((witer[1]-witer[0])*n+witer[0]) );
                                vector_list.push_back(curve(1.0)+deriv(1.0-CUSP_TANGENT_ADJUST).perp().norm()*witer[1]);
-                               
+
                        }
                }
                if(round_tip[1] && !loop_/* && (!sharp_cusps || segment_list.front().p1!=segment_list.back().p2)*/)
                {
                        // remove the last point
                        vector_list.pop_back();
-                       
+
                        iter--;
 
                        curve.p1()=iter->p2+Vector(last_tangent[1],-last_tangent[0]).norm()*(*witer);
@@ -514,7 +551,7 @@ Outline::sync()
                        vector_list.pop_back();
                }
        }
-       
+
        if(!loop_)
                last_tangent=NO_LOOP_COOKIE;
        else
@@ -523,10 +560,10 @@ Outline::sync()
                vector_list.clear();
                last_tangent=segment_list.front().t1;
        }
-       
+
        //else
        //      last_tangent=segment_list.back().t2;
-       
+
        {
                vector<Segment>::reverse_iterator iter;
                vector<Real>::reverse_iterator witer;
@@ -536,7 +573,7 @@ Outline::sync()
                        !(iter==segment_list.rend());
                        ++iter,++witer)
                {
-                       
+
                        if(iter->t1.mag_squared()<=EPSILON && iter->t2.mag_squared()<=EPSILON)
                        {
                                vector_list.push_back(iter->p2+(iter->p2-iter->p1).perp().norm()*witer[0]);
@@ -551,7 +588,7 @@ Outline::sync()
                                curve.p2()=iter->p2;
                                curve.t2()=iter->t2;
                                curve.sync();
-       
+
                                etl::derivative<etl::hermite<Vector> > deriv(curve);
 
                                // without this if statement, the broken tangents would
@@ -560,17 +597,17 @@ Outline::sync()
                                {
                                        //Vector curr_tangent(iter->t2);
                                        Vector curr_tangent(deriv(1.0f-CUSP_TANGENT_ADJUST));
-                                       
+
                                        const Vector t1(last_tangent.perp().norm());
                                        const Vector t2(curr_tangent.perp().norm());
 
                                        Point p1(iter->p2-t1*witer[-1]);
                                        Point p2(iter->p2-t2*witer[-1]);
-                                       
+
                                        Real cross(t1*t2.perp());
-                                       
+
                                        //if(last_tangent.perp().norm()*curr_tangent.norm()<-CUSP_THRESHOLD)
-                                       if(cross>CUSP_THRESHOLD)                                
+                                       if(cross>CUSP_THRESHOLD)
                                                vector_list.push_back(line_intersection(p1,last_tangent,p2,curr_tangent));
                                        else if(cross>0)
                                        {
@@ -583,7 +620,7 @@ Outline::sync()
                                }
                                //last_tangent=iter->t1;
                                last_tangent=deriv(CUSP_TANGENT_ADJUST);
-                               
+
                                for(n=1.0f;n>CUSP_TANGENT_ADJUST;n-=1.0f/SAMPLES)
                                        vector_list.push_back(curve(n)-deriv(1-n>CUSP_TANGENT_ADJUST?n:1-CUSP_TANGENT_ADJUST).perp().norm()*((witer[-1]-witer[0])*n+witer[0]) );
                                vector_list.push_back(curve(0.0f)-deriv(CUSP_TANGENT_ADJUST).perp().norm()*witer[0]);
@@ -595,7 +632,7 @@ Outline::sync()
                        vector_list.pop_back();
                        iter--;
                        witer--;
-                       
+
                        curve.p1()=iter->p1+Vector(last_tangent[1],-last_tangent[0]).norm()*(*witer);
                        curve.p2()=iter->p1-(Vector(last_tangent[1],-last_tangent[0]).norm()*(*witer));
                        curve.t1()=-(curve.t2()=last_tangent/last_tangent.mag()*(*witer)*ROUND_END_FACTOR);
@@ -603,7 +640,7 @@ Outline::sync()
 
                        for(n=1.0;n>0.0;n-=1.0/SAMPLES)
                                vector_list.push_back(curve(n));
-                       
+
                        // remove the last point
                        vector_list.pop_back();
                }
@@ -618,17 +655,17 @@ Outline::sync()
                for(iter=vector_list.begin();iter!=vector_list.end();++iter)
                        if(!iter->is_valid())
                        {
-                               sinfg::error("Outline::sync(): Bad point in vector_list!");
+                               synfig::error("Outline::sync(): Bad point in vector_list!");
                        }
-               //sinfg::info("BLEHH__________--- x:%f, y:%f",vector_list.front()[0],vector_list.front()[1]);
+               //synfig::info("BLEHH__________--- x:%f, y:%f",vector_list.front()[0],vector_list.front()[1]);
        }
-#endif
-       
+#endif /* _DEBUG */
+
        add_polygon(vector_list);
 
 
-#endif
-       } catch (...) { sinfg::error("Outline::sync(): Exception thrown"); throw; }
+#endif /* 1 */
+       } catch (...) { synfig::error("Outline::sync(): Exception thrown"); throw; }
 }
 
 #undef bline
@@ -642,17 +679,17 @@ Outline::set_param(const String & param, const ValueBase &value)
                {
                        connect_dynamic_param("bline",dynamic_param_list().find("segment_list")->second);
                        disconnect_dynamic_param("segment_list");
-                       sinfg::warning("Outline::set_param(): Updated valuenode connection to use the new \"bline\" parameter.");
+                       synfig::warning("Outline::set_param(): Updated valuenode connection to use the new \"bline\" parameter.");
                }
                else
-                       sinfg::warning("Outline::set_param(): The parameter \"segment_list\" is deprecated. Use \"bline\" instead.");
+                       synfig::warning("Outline::set_param(): The parameter \"segment_list\" is deprecated. Use \"bline\" instead.");
        }
 
        if(     (param=="segment_list" || param=="bline") && value.get_type()==ValueBase::TYPE_LIST)
        {
                //if(value.get_contained_type()!=ValueBase::TYPE_BLINEPOINT)
                //      return false;
-                       
+
                bline=value;
 
                return true;
@@ -699,8 +736,8 @@ Outline::set_param(const String & param, const ValueBase &value)
                //sync();
                return true;
        }
-       
-       if(     param=="width_list" && value.same_as(width_list))
+
+       if(     param=="width_list" && value.same_type_as(width_list))
        {
                width_list=value;
                //sync();
@@ -715,7 +752,7 @@ Outline::set_param(const String & param, const ValueBase &value)
        IMPORT(loopyness);
        IMPORT(expand);
        IMPORT(homogeneous_width);
-       
+
        if(param!="vector_list")
                return Layer_Polygon::set_param(param,value);
 
@@ -749,7 +786,7 @@ Outline::get_param(const String& param)const
        EXPORT(sharp_cusps);
        EXPORT(width);
        EXPORT(loopyness);
-       
+
        EXPORT_NAME();
        EXPORT_VERSION();
 
@@ -768,8 +805,8 @@ Outline::get_param_vocab()const
 
        ret.push_back(ParamDesc("bline")
                .set_local_name(_("Vertices"))
-               .set_origin("offset")
-               .set_scalar("width")
+               .set_origin("origin")
+               .set_hint("width")
                .set_description(_("A list of BLine Points"))
        );