TuttleOFX  1
ramp.hpp
Go to the documentation of this file.
00001 #ifndef _TERRY_GENERATOR_RAMP_HPP_
00002 #define _TERRY_GENERATOR_RAMP_HPP_
00003 
00004 #include <boost/gil/utilities.hpp>
00005 #include <terry/numeric/operations.hpp>
00006 #include <terry/numeric/operations_assign.hpp>
00007 #include <terry/numeric/assign.hpp>
00008 #include <terry/numeric/init.hpp>
00009 
00010 #include <cmath>
00011 
00012 namespace terry {
00013 namespace generator {
00014 
00015 template<class Pixel>
00016 Pixel clearChannel( const Pixel& in, bool red, bool green, bool blue, bool alpha, const boost::mpl::true_, const boost::mpl::true_ )
00017 {
00018         Pixel out = in;
00019         if( red )
00020                 get_color( out, red_t() ) = 0.0;
00021         if( green )
00022                 get_color( out, green_t() ) = 0.0;
00023         if( blue )
00024                 get_color( out, blue_t() ) = 0.0;
00025         if( alpha )
00026                 get_color( out, gray_color_t() ) = 0.0;
00027         
00028         return out;
00029 }
00030 
00031 template<class Pixel>
00032 Pixel clearChannel( const Pixel& in, bool red, bool green, bool blue, bool alpha, const boost::mpl::true_, const boost::mpl::false_ )
00033 {
00034         Pixel out = in;
00035         if( red )
00036                 get_color( out, red_t() ) = 0.0;
00037         if( green )
00038                 get_color( out, green_t() ) = 0.0;
00039         if( blue )
00040                 get_color( out, blue_t() ) = 0.0;
00041         
00042         return out;
00043 }
00044 
00045 template<class Pixel>
00046 Pixel clearChannel( const Pixel& in, bool red, bool green, bool blue, bool alpha, const boost::mpl::false_, const boost::mpl::true_ )
00047 {
00048         return in;
00049 }
00050 
00051 template<class Pixel>
00052 Pixel clearChannel( const Pixel& in, bool red, bool green, bool blue, bool alpha, const boost::mpl::false_, const boost::mpl::false_ )
00053 {
00054         return in;
00055 }
00056 
00057 // Models a Unary Function
00058 template <typename Pixel>
00059 // Models PixelValueConcept
00060 struct RampFunctor
00061 {
00062         //typedef point2<ptrdiff_t>    point_t;
00063         typedef boost::gil::point2<double>    point_t;
00064         
00065         typedef RampFunctor const_t;
00066         typedef Pixel value_type;
00067         typedef value_type reference;
00068         typedef value_type const_reference;
00069         typedef point_t argument_type;
00070         typedef reference result_type;
00071         typedef typename contains_color<Pixel, red_t>::type hasRGBChannel;
00072         typedef typename contains_color<Pixel, gray_color_t>::type hasAlphaChannel;
00073         BOOST_STATIC_CONSTANT( bool, is_mutable = false );
00074         
00075         point_t _tile_size;
00076         
00077         value_type _start_color;
00078         value_type _end_color;
00079         
00080         bool _horizontal;
00081         bool _multiColor;
00082         
00083         RampFunctor() {}
00084         RampFunctor( const point_t& tileSize, const value_type& start_color, const value_type& end_color, bool horizontal = true, bool _multiColor = false ) :
00085                 _tile_size   ( tileSize ),
00086                 _start_color ( start_color ),
00087                 _end_color   ( end_color ),
00088                 _horizontal  ( horizontal ),
00089                 _multiColor  ( _multiColor )
00090         {}
00091         
00092         Pixel operator()( const point_t& p ) const
00093         {
00094                 Pixel pixel;
00095                 
00096                 float level = p.x / ( _tile_size.x - 1 );
00097                 if( ! _horizontal )
00098                 {
00099                         level = p.y / ( _tile_size.y - 1 );
00100                 }
00101                 
00102                 Pixel pixelStart = numeric::pixel_multiplies_scalar_t<Pixel, float>()( _start_color, 1.0 - level );
00103                 Pixel pixelEnd   = numeric::pixel_multiplies_scalar_t<Pixel, float>()( _end_color, level );
00104                 
00105                 pixel = numeric::pixel_plus_t<Pixel, Pixel, Pixel>()( pixelStart, pixelEnd );
00106                 
00107                 if( !_multiColor )
00108                 {
00109                         return pixel;
00110                 }
00111                 
00112                 if( _horizontal )
00113                 {
00114                         if( p.y < 0.25 * _tile_size.y )
00115                         {
00116                                 pixel = clearChannel( pixel, false, true, true, false, hasRGBChannel(), hasAlphaChannel() );
00117                         }
00118                         else
00119                         {
00120                                 if( p.y < 0.5 * _tile_size.y )
00121                                 {
00122                                         pixel = clearChannel( pixel, true, false, true, false, hasRGBChannel(), hasAlphaChannel() );
00123                                 }
00124                                 else
00125                                 {
00126                                         if( p.y < 0.75 * _tile_size.y )
00127                                         {
00128                                                 pixel = clearChannel( pixel, true, true, false, false, hasRGBChannel(), hasAlphaChannel() );
00129                                         }
00130                                 }
00131                         }
00132                 }
00133                 else
00134                 {
00135                         if( p.x < 0.25 * _tile_size.x )
00136                         {
00137                                 pixel = clearChannel( pixel, false, true, true, false, hasRGBChannel(), hasAlphaChannel() );
00138                         }
00139                         else
00140                         {
00141                                 if( p.x < 0.5 * _tile_size.x )
00142                                 {
00143                                         pixel = clearChannel( pixel, true, false, true, false, hasRGBChannel(), hasAlphaChannel() );
00144                                 }
00145                                 else
00146                                 {
00147                                         if( p.x < 0.75 * _tile_size.x )
00148                                         {
00149                                                 pixel = clearChannel( pixel, true, true, false, false, hasRGBChannel(), hasAlphaChannel() );
00150                                         }
00151                                 }
00152                         }
00153                 }
00154                 return pixel;
00155         }
00156         
00157 };
00158 
00159 }
00160 }
00161 
00162 #endif