Remove .gitignore do nothing is ignored.
[synfig.git] / synfig-core / trunk / src / modules / mod_geometry / circle.cpp
index fca1ef7..f5ad99b 100644 (file)
@@ -1,11 +1,12 @@
 /* === S Y N F I G ========================================================= */
 /*!    \file circle.cpp
-**     \brief Template Header
+**     \brief Implementation of the "Circle" layer
 **
 **     $Id$
 **
 **     \legal
 **     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 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
@@ -61,7 +62,7 @@ SYNFIG_LAYER_SET_CVS_ID(Circle,"$Id$");
 Circle::Circle():
        Layer_Composite (1.0,Color::BLEND_STRAIGHT),
        color                   (Color::black()),
-       pos                             (0,0),
+       origin                  (0,0),
        radius                  (1),
        feather                 (0),
        invert                  (false),
@@ -73,13 +74,17 @@ Circle::Circle():
 bool
 Circle::ImportParameters(const String &param, const ValueBase &value)
 {
-       IMPORT(color);
+       IMPORT_PLUS(color, { if (color.get_a() == 0) { if (converted_blend_) {
+                                       set_blend_method(Color::BLEND_ALPHA_OVER);
+                                       color.set_a(1); } else transparent_color_ = true; } });
        IMPORT(radius);
-       IMPORT(feather);
+       IMPORT_PLUS(feather, if(feather<0)feather=0;);
        IMPORT(invert);
-       IMPORT(pos);
+       IMPORT(origin);
        IMPORT(falloff);
 
+       IMPORT_AS(origin,"pos");
+
        return Layer_Composite::set_param(param,value);
 }
 
@@ -102,7 +107,7 @@ Circle::get_param(const String &param)const
        EXPORT(radius);
        EXPORT(feather);
        EXPORT(invert);
-       EXPORT(pos);
+       EXPORT(origin);
        EXPORT(falloff);
 
        EXPORT_NAME();
@@ -121,15 +126,15 @@ Circle::get_param_vocab()const
        );
        ret.push_back(ParamDesc("radius")
                .set_local_name(_("Radius"))
-               .set_origin("pos")
+               .set_origin("origin")
                .set_is_distance()
        );
        ret.push_back(ParamDesc("feather")
                .set_local_name(_("Feather"))
                .set_is_distance()
        );
-       ret.push_back(ParamDesc("pos")
-               .set_local_name(_("Center"))
+       ret.push_back(ParamDesc("origin")
+               .set_local_name(_("Origin"))
        );
        ret.push_back(ParamDesc("invert")
                .set_local_name(_("Invert"))
@@ -153,7 +158,7 @@ Circle::get_param_vocab()const
 synfig::Layer::Handle
 Circle::hit_check(synfig::Context context, const synfig::Point &point)const
 {
-       Point temp=pos-point;
+       Point temp=origin-point;
 
        if(get_amount()==0)
                return context.hit_check(point);
@@ -301,11 +306,11 @@ Circle::FALLOFF_FUNC *Circle::GetFalloffFunc()const
 Color
 Circle::get_color(Context context, const Point &point)const
 {
-       if(radius==0 || is_disabled())
+       if(is_disabled() || (radius==0 && invert==false && !feather))
                return context.get_color(point);
 
 
-       Point temp=pos-point;
+       Point temp=origin-point;
 
        /*const Real inner_radius = radius-feather;
        const Real outer_radius = radius+feather;
@@ -339,7 +344,7 @@ Circle::get_color(Context context, const Point &point)const
                                return Color::blend(color,context.get_color(point),get_amount(),get_blend_method());
                }
                else
-                       return context.get_color(point);
+                       return Color::blend(Color::alpha(),context.get_color(point),get_amount(),get_blend_method());
        }
 
        //inside the circle's solid area (with feathering)
@@ -352,7 +357,7 @@ Circle::get_color(Context context, const Point &point)const
                        else
                                return Color::blend(color,context.get_color(point),get_amount(),get_blend_method());
                else
-                       return context.get_color(point);
+                       return Color::blend(Color::alpha(),context.get_color(point),get_amount(),get_blend_method());
        }
 
        //If we get here, the pixel is within the feathering area, and is thus subject to falloff
@@ -396,10 +401,7 @@ Circle::get_color(Context context, const Point &point)const
 
                alpha = falloff_func(cache,mag_squared);
 
-               //Compose falloff value with amount from the composite layer, and that is the blend value
-               alpha *= get_amount();
-
-               return Color::blend(color,context.get_color(point),alpha,get_blend_method());
+               return Color::blend(color*alpha,context.get_color(point),get_amount(),get_blend_method());
        }
 }
 
@@ -413,7 +415,7 @@ bool
 Circle::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
 {
        // trivial case
-       if(is_disabled() || (radius==0 && invert==false))
+       if(is_disabled() || (radius==0 && invert==false && !feather))
                return context.accelerated_render(surface,quality, renddesc, cb);
 
        // Another trivial case
@@ -441,13 +443,14 @@ Circle::accelerated_render(Context context,Surface *surface,int quality, const R
 
        // Increasing the feather amount by the size of
        // a pixel will create an anti-aliased appearance
-       const Real newfeather=feather + (abs(ph)+abs(pw))/4.0;
+       // don't render feathering at all when quality is 10
+       const Real newfeather = (quality == 10) ? 0 : feather + (abs(ph)+abs(pw))/4.0;
 
        //int u,v;
-       int left =      (int)   floor( (pos[0] - x_neg*(radius+newfeather) - tl[0]) / pw );
-       int right = (int)       ceil( (pos[0] + x_neg*(radius+newfeather) - tl[0]) / pw );
-       int top =       (int)   floor( (pos[1] - y_neg*(radius+newfeather) - tl[1]) / ph );
-       int bottom = (int)      ceil( (pos[1] + y_neg*(radius+newfeather) - tl[1]) / ph );
+       int left =      (int)   floor( (origin[0] - x_neg*(radius+newfeather) - tl[0]) / pw );
+       int right = (int)       ceil( (origin[0] + x_neg*(radius+newfeather) - tl[0]) / pw );
+       int top =       (int)   floor( (origin[1] - y_neg*(radius+newfeather) - tl[1]) / ph );
+       int bottom = (int)      ceil( (origin[1] + y_neg*(radius+newfeather) - tl[1]) / ph );
 
        //clip the rectangle bounds
        if(left < 0)
@@ -520,10 +523,10 @@ Circle::accelerated_render(Context context,Surface *surface,int quality, const R
                }
        }
 
-       if( (pos[0] - tl[0])*(pos[0] - tl[0]) + (pos[1] - tl[1])*(pos[1] - tl[1]) < inner_radius_sqd
-               && (pos[0] - br[0])*(pos[0] - br[0]) + (pos[1] - br[1])*(pos[1] - br[1]) < inner_radius_sqd
-               && (pos[0] - tl[0])*(pos[0] - tl[0]) + (pos[1] - br[1])*(pos[1] - br[1]) < inner_radius_sqd
-               && (pos[0] - br[0])*(pos[0] - br[0]) + (pos[1] - tl[1])*(pos[1] - tl[1]) < inner_radius_sqd     )
+       if( (origin[0] - tl[0])*(origin[0] - tl[0]) + (origin[1] - tl[1])*(origin[1] - tl[1]) < inner_radius_sqd
+               && (origin[0] - br[0])*(origin[0] - br[0]) + (origin[1] - br[1])*(origin[1] - br[1]) < inner_radius_sqd
+               && (origin[0] - tl[0])*(origin[0] - tl[0]) + (origin[1] - br[1])*(origin[1] - br[1]) < inner_radius_sqd
+               && (origin[0] - br[0])*(origin[0] - br[0]) + (origin[1] - tl[1])*(origin[1] - tl[1]) < inner_radius_sqd )
        {
                if(invert)
                {
@@ -565,8 +568,8 @@ Circle::accelerated_render(Context context,Surface *surface,int quality, const R
                }
 
                //make topf and leftf relative to the center of the circle
-               leftf   -=      pos[0];
-               topf    -=      pos[1];
+               leftf   -=      origin[0];
+               topf    -=      origin[1];
 
                j = top;
                y = topf;
@@ -677,8 +680,8 @@ Circle::accelerated_render(Context context,Surface *surface,int quality, const R
                        }
                }
 
-               topf -= pos[1];
-               leftf-= pos[0];
+               topf -= origin[1];
+               leftf-= origin[0];
 
                j = top;
                y = topf;
@@ -749,10 +752,10 @@ Circle::get_bounding_rect()const
                return Rect::full_plane();
 
        Rect bounds(
-               pos[0]+(radius+feather),
-               pos[1]+(radius+feather),
-               pos[0]-(radius+feather),
-               pos[1]-(radius+feather)
+               origin[0]+(radius+feather),
+               origin[1]+(radius+feather),
+               origin[0]-(radius+feather),
+               origin[1]-(radius+feather)
        );
 
        return bounds;
@@ -766,10 +769,10 @@ Circle::get_full_bounding_rect(Context context)const
                if(is_solid_color() && color.get_a()==0)
                {
                        Rect bounds(
-                               pos[0]+(radius+feather),
-                               pos[1]+(radius+feather),
-                               pos[0]-(radius+feather),
-                               pos[1]-(radius+feather)
+                               origin[0]+(radius+feather),
+                               origin[1]+(radius+feather),
+                               origin[0]-(radius+feather),
+                               origin[1]-(radius+feather)
                        );
                        return bounds & context.get_full_bounding_rect();
                }