Add my copyright to files I've modified.
[synfig.git] / synfig-core / trunk / src / synfig / layer_shape.cpp
index 0c980aa..d1e7aef 100644 (file)
@@ -6,6 +6,7 @@
 **
 **     \legal
 **     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007 Chris Moore
 **
 **     This package is free software; you can redistribute it and/or
 **     modify it under the terms of the GNU General Public License as
@@ -233,7 +234,7 @@ struct MonoSegment
 
        int intersect(Real x,Real y) const
        {
-               if((y < aabb.miny) || (y > aabb.maxy) || (x < aabb.minx)) return 0;
+               if((y < aabb.miny+EPSILON) || (y > aabb.maxy) || (x < aabb.minx)) return 0;
                if(x > aabb.maxx) return ydir;
 
                //int i = 0;
@@ -316,7 +317,7 @@ struct CurveArray
                degrees.push_back(2);
        }
 
-       static int intersect_conic(Real x, Real y, Point *p, int level = 0)
+       static int intersect_conic(Real x, Real y, Point *p, int /*level*/ = 0)
        {
                Real ymin,ymax,xmin,xmax;
                int intersects = 0;
@@ -440,7 +441,7 @@ struct CurveArray
                const Real cn[4] = {a,b,c,d};
                Real p,dp,newt,oldpmag=FLT_MAX;
 
-               //eval cubic eqn and it's derivative
+               //eval cubic eqn and its derivative
                for(;;)
                {
                        p = cn[0]*t + cn[1];
@@ -471,7 +472,7 @@ struct CurveArray
                }
        }
 
-       static int intersect_cubic(Real x, Real y, Point *p, int level = 0)
+       static int intersect_cubic(Real x, Real y, Point *p, int /*level*/ = 0)
        {
                const Real INVALIDROOT = -FLT_MAX;
                Real ymin,ymax,xmin,xmax;
@@ -1089,19 +1090,27 @@ public:
        void draw_scanline(int y, Real x1, Real y1, Real x2, Real y2);
        void draw_line(Real x1, Real y1, Real x2, Real y2);
 
-       Real ExtractAlpha(Real area)
+       Real ExtractAlpha(Real area, WindingStyle winding_style)
        {
-               //non-zero winding style
-               if(area < 0) area = -area;
-               if(area > 1) area = 1;
+               if (area < 0)
+                       area = -area;
 
-               //even-odd winding style
-               /*if(area < 0) area = -area;
+               if (winding_style == WINDING_NON_ZERO)
+               {
+                       // non-zero winding style
+                       if (area > 1)
+                               return 1;
+               }
+               else // if (winding_style == WINDING_EVEN_ODD)
+               {
+                       // even-odd winding style
+                       while (area > 1)
+                               area -= 2;
 
-               while(area > 2) area -= 2;
-               if(area > 1) area = 1-area; //want pyramid like thing
-               */
-               //broken? - yep broken
+                       // want pyramid like thing
+                       if (area < 0)
+                               area = -area;
+               }
 
                return area;
        }
@@ -1118,6 +1127,7 @@ Layer_Shape::Layer_Shape(const Real &a, const Color::BlendMethod m):
        antialias               (true),
        blurtype                (Blur::FASTGAUSSIAN),
        feather                 (0),
+       winding_style   (WINDING_NON_ZERO),
        bytestream              (0),
        lastbyteop              (Primitive::NONE),
        lastoppos               (-1)
@@ -1145,6 +1155,7 @@ Layer_Shape::set_param(const String & param, const ValueBase &value)
        IMPORT(antialias);
        IMPORT(feather);
        IMPORT(blurtype);
+       IMPORT(winding_style);
 
        return Layer_Composite::set_param(param,value);
 }
@@ -1158,6 +1169,7 @@ Layer_Shape::get_param(const String &param)const
        EXPORT(antialias);
        EXPORT(feather);
        EXPORT(blurtype);
+       EXPORT(winding_style);
 
        EXPORT_NAME();
        EXPORT_VERSION();
@@ -1197,6 +1209,13 @@ Layer_Shape::get_param_vocab()const
                .add_enum_value(Blur::GAUSSIAN,"gaussian",_("Gaussian Blur"))
                .add_enum_value(Blur::DISC,"disc",_("Disc Blur"))
        );
+       ret.push_back(ParamDesc("winding_style")
+               .set_local_name(_("Winding Style"))
+               .set_description(_("Winding style to use"))
+               .set_hint("enum")
+               .add_enum_value(WINDING_NON_ZERO,"nonzero",_("Non Zero"))
+               .add_enum_value(WINDING_EVEN_ODD,"evenodd",_("Even/Odd"))
+       );
 
        return ret;
 }
@@ -1309,7 +1328,7 @@ void Layer_Shape::PolySpan::line_to(Real x, Real y)
                        //generate data for the ending clipped info
                        if(y > window.maxy)
                        {
-                               //intial line to intersection (and degenerate)
+                               //initial line to intersection (and degenerate)
                                n[2] = x + (window.maxy - y) * dx / dy;
 
                                //intersect coords
@@ -1333,7 +1352,7 @@ void Layer_Shape::PolySpan::line_to(Real x, Real y)
                        //generate data for the ending clipped info
                        if(y < window.miny)
                        {
-                               //intial line to intersection (and degenerate)
+                               //initial line to intersection (and degenerate)
                                n[2] = x + (window.miny - y) * dx / dy;
 
                                //intersect coords
@@ -1383,7 +1402,7 @@ void Layer_Shape::PolySpan::line_to(Real x, Real y)
                                //generate data for the ending clipped info
                                if(x > window.maxx)
                                {
-                                       //intial line to intersection (and degenerate)
+                                       //initial line to intersection (and degenerate)
                                        n[2] = y + (window.maxx - x) * dy / dx;
 
                                        n[0] = window.maxx;
@@ -1412,7 +1431,7 @@ void Layer_Shape::PolySpan::line_to(Real x, Real y)
                                //generate data for the ending clipped info
                                if(x < window.minx)
                                {
-                                       //intial line to intersection (and degenerate)
+                                       //initial line to intersection (and degenerate)
                                        n[2] = y + (window.minx - x) * dy / dx;
 
                                        n[0] = window.minx;
@@ -2195,7 +2214,7 @@ bool Layer_Shape::render_polyspan(Surface *surface, PolySpan &polyspan,
                //draw pixel - based on covered area
                if(area)        //if we're ok, draw the current pixel
                {
-                       alpha = polyspan.ExtractAlpha(cover - area);
+                       alpha = polyspan.ExtractAlpha(cover - area, winding_style);
                        if(invert) alpha = 1 - alpha;
 
                        if(!antialias)
@@ -2232,7 +2251,7 @@ bool Layer_Shape::render_polyspan(Surface *surface, PolySpan &polyspan,
                //draw span to next pixel - based on total amount of pixel cover
                if(x < cur_mark->x)
                {
-                       alpha = polyspan.ExtractAlpha(cover);
+                       alpha = polyspan.ExtractAlpha(cover, winding_style);
                        if(invert) alpha = 1 - alpha;
 
                        if(!antialias)
@@ -2321,7 +2340,7 @@ bool Layer_Shape::render_polyspan(etl::surface<float> *surface, PolySpan &polysp
                        //draw pixel - based on covered area
                        if(area)        //if we're ok, draw the current pixel
                        {
-                               alpha = 1 - polyspan.ExtractAlpha(cover - area);
+                               alpha = 1 - polyspan.ExtractAlpha(cover - area, winding_style);
                                if(!antialias)
                                {
                                        if(alpha >= .5) p.put_value();
@@ -2353,7 +2372,7 @@ bool Layer_Shape::render_polyspan(etl::surface<float> *surface, PolySpan &polysp
                        //draw span to next pixel - based on total amount of pixel cover
                        if(x < cur_mark->x)
                        {
-                               alpha = 1 - polyspan.ExtractAlpha(cover);
+                               alpha = 1 - polyspan.ExtractAlpha(cover, winding_style);
                                if(!antialias)
                                {
                                        if(alpha >= .5) p.put_hline(cur_mark->x - x);
@@ -2393,7 +2412,7 @@ bool Layer_Shape::render_polyspan(etl::surface<float> *surface, PolySpan &polysp
                        //draw pixel - based on covered area
                        if(area)        //if we're ok, draw the current pixel
                        {
-                               alpha = polyspan.ExtractAlpha(cover - area);
+                               alpha = polyspan.ExtractAlpha(cover - area, winding_style);
                                if(!antialias)
                                {
                                        if(alpha >= .5) p.put_value();
@@ -2418,7 +2437,7 @@ bool Layer_Shape::render_polyspan(etl::surface<float> *surface, PolySpan &polysp
                        //draw span to next pixel - based on total amount of pixel cover
                        if(x < cur_mark->x)
                        {
-                               alpha = polyspan.ExtractAlpha(cover);
+                               alpha = polyspan.ExtractAlpha(cover, winding_style);
                                if(!antialias)
                                {
                                        if(alpha >= .5) p.put_hline(cur_mark->x - x);
@@ -2596,7 +2615,7 @@ Layer_Shape::accelerated_render(Context context,Surface *surface,int quality, co
 }
 
 bool
-Layer_Shape::render_shape(Surface *surface,bool useblend,int quality,
+Layer_Shape::render_shape(Surface *surface,bool useblend,int /*quality*/,
                                                        const RendDesc &renddesc, ProgressCallback *cb)const
 {
        int tmp(0);
@@ -2836,8 +2855,8 @@ Layer_Shape::render_shape(Surface *surface,bool useblend,int quality,
 }
 
 bool
-Layer_Shape::render_shape(surface<float> *surface,int quality,
-                                                       const RendDesc &renddesc, ProgressCallback *cb)const
+Layer_Shape::render_shape(surface<float> *surface,int /*quality*/,
+                                                       const RendDesc &renddesc, ProgressCallback */*cb*/)const
 {
        // If our amount is set to zero, no need to render anything
        if(!get_amount())