1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry (AGG) - Version 2.5
3 // A high quality rendering engine for C++
4 // Copyright (C) 2002-2006 Maxim Shemanarev
5 // Contact: mcseem@antigrain.com
6 //          mcseemagg@yahoo.com
7 //          http://antigrain.com
8 //
9 // AGG is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // AGG is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with AGG; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 // MA 02110-1301, USA.
23 //----------------------------------------------------------------------------
24 
25 #ifndef AGG_SPAN_GRADIENT_ALPHA_INCLUDED
26 #define AGG_SPAN_GRADIENT_ALPHA_INCLUDED
27 
28 #include "agg_span_gradient.h"
29 
30 namespace agg
31 {
32     //======================================================span_gradient_alpha
33     template<class ColorT,
34              class Interpolator,
35              class GradientF,
36              class AlphaF>
37     class span_gradient_alpha
38     {
39     public:
40         typedef Interpolator interpolator_type;
41         typedef ColorT color_type;
42         typedef typename color_type::value_type alpha_type;
43 
44         enum downscale_shift_e
45         {
46             downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift
47         };
48 
49 
50         //--------------------------------------------------------------------
span_gradient_alpha()51         span_gradient_alpha() {}
52 
53         //--------------------------------------------------------------------
span_gradient_alpha(interpolator_type & inter,const GradientF & gradient_function,const AlphaF & alpha_function,double d1,double d2)54         span_gradient_alpha(interpolator_type& inter,
55                             const GradientF& gradient_function,
56                             const AlphaF& alpha_function,
57                             double d1, double d2) :
58             m_interpolator(&inter),
59             m_gradient_function(&gradient_function),
60             m_alpha_function(&alpha_function),
61             m_d1(iround(d1 * gradient_subpixel_scale)),
62             m_d2(iround(d2 * gradient_subpixel_scale))
63         {}
64 
65         //--------------------------------------------------------------------
interpolator()66         interpolator_type& interpolator() { return *m_interpolator; }
gradient_function()67         const GradientF& gradient_function() const { return *m_gradient_function; }
alpha_function()68         const AlphaF& alpha_function() const { return *m_alpha_function; }
d1()69         double d1() const { return double(m_d1) / gradient_subpixel_scale; }
d2()70         double d2() const { return double(m_d2) / gradient_subpixel_scale; }
71 
72         //--------------------------------------------------------------------
interpolator(interpolator_type & i)73         void interpolator(interpolator_type& i) { m_interpolator = &i; }
gradient_function(const GradientF & gf)74         void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
alpha_function(const AlphaF & af)75         void alpha_function(const AlphaF& af) { m_alpha_function = &af; }
d1(double v)76         void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); }
d2(double v)77         void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
78 
79         //--------------------------------------------------------------------
prepare()80         void prepare() {}
81 
82         //--------------------------------------------------------------------
generate(color_type * span,int x,int y,unsigned len)83         void generate(color_type* span, int x, int y, unsigned len)
84         {
85             int dd = m_d2 - m_d1;
86             if(dd < 1) dd = 1;
87             m_interpolator->begin(x+0.5, y+0.5, len);
88             do
89             {
90                 m_interpolator->coordinates(&x, &y);
91                 int d = m_gradient_function->calculate(x >> downscale_shift,
92                                                        y >> downscale_shift, m_d2);
93                 d = ((d - m_d1) * (int)m_alpha_function->size()) / dd;
94                 if(d < 0) d = 0;
95                 if(d >= (int)m_alpha_function->size()) d = m_alpha_function->size() - 1;
96                 span->a = (*m_alpha_function)[d];
97                 ++span;
98                 ++(*m_interpolator);
99             }
100             while(--len);
101         }
102 
103     private:
104         interpolator_type* m_interpolator;
105         const GradientF*   m_gradient_function;
106         const AlphaF*      m_alpha_function;
107         int                m_d1;
108         int                m_d2;
109     };
110 
111 
112     //=======================================================gradient_alpha_x
113     template<class ColorT> struct gradient_alpha_x
114     {
115         typedef typename ColorT::value_type alpha_type;
116         alpha_type operator [] (alpha_type x) const { return x; }
117     };
118 
119     //====================================================gradient_alpha_x_u8
120     struct gradient_alpha_x_u8
121     {
122         typedef int8u alpha_type;
123         alpha_type operator [] (alpha_type x) const { return x; }
124     };
125 
126     //==========================================gradient_alpha_one_munus_x_u8
127     struct gradient_alpha_one_munus_x_u8
128     {
129         typedef int8u alpha_type;
130         alpha_type operator [] (alpha_type x) const { return 255-x; }
131     };
132 
133 }
134 
135 #endif
136