1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 //          mcseemagg@yahoo.com
13 //          http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 
16 #ifndef AGG_SPAN_GRADIENT_ALPHA_INCLUDED
17 #define AGG_SPAN_GRADIENT_ALPHA_INCLUDED
18 
19 #include "agg_span_gradient.h"
20 
21 namespace agg
22 {
23     //======================================================span_gradient_alpha
24     template<class ColorT,
25              class Interpolator,
26              class GradientF,
27              class AlphaF>
28     class span_gradient_alpha
29     {
30     public:
31         typedef Interpolator interpolator_type;
32         typedef ColorT color_type;
33         typedef typename color_type::value_type alpha_type;
34 
35         enum downscale_shift_e
36         {
37             downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift
38         };
39 
40 
41         //--------------------------------------------------------------------
span_gradient_alpha()42         span_gradient_alpha() {}
43 
44         //--------------------------------------------------------------------
span_gradient_alpha(interpolator_type & inter,GradientF & gradient_function,AlphaF & alpha_function,double d1,double d2)45         span_gradient_alpha(interpolator_type& inter,
46                             GradientF& gradient_function,
47                             AlphaF& alpha_function,
48                             double d1, double d2) :
49             m_interpolator(&inter),
50             m_gradient_function(&gradient_function),
51             m_alpha_function(&alpha_function),
52             m_d1(iround(d1 * gradient_subpixel_scale)),
53             m_d2(iround(d2 * gradient_subpixel_scale))
54         {}
55 
56         //--------------------------------------------------------------------
interpolator()57         interpolator_type& interpolator() { return *m_interpolator; }
gradient_function()58         const GradientF& gradient_function() const { return *m_gradient_function; }
alpha_function()59         const AlphaF& alpha_function() const { return *m_alpha_function; }
d1()60         double d1() const { return double(m_d1) / gradient_subpixel_scale; }
d2()61         double d2() const { return double(m_d2) / gradient_subpixel_scale; }
62 
63         //--------------------------------------------------------------------
interpolator(interpolator_type & i)64         void interpolator(interpolator_type& i) { m_interpolator = &i; }
gradient_function(const GradientF & gf)65         void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
alpha_function(const AlphaF & af)66         void alpha_function(const AlphaF& af) { m_alpha_function = &af; }
d1(double v)67         void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); }
d2(double v)68         void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
69 
70         //--------------------------------------------------------------------
prepare()71         void prepare() {}
72 
73         //--------------------------------------------------------------------
generate(color_type * span,int x,int y,unsigned len)74         void generate(color_type* span, int x, int y, unsigned len)
75         {
76             int dd = m_d2 - m_d1;
77             if(dd < 1) dd = 1;
78             m_interpolator->begin(x+0.5, y+0.5, len);
79             do
80             {
81                 m_interpolator->coordinates(&x, &y);
82                 int d = m_gradient_function->calculate(x >> downscale_shift,
83                                                        y >> downscale_shift, m_d2);
84                 d = ((d - m_d1) * (int)m_alpha_function->size()) / dd;
85                 if(d < 0) d = 0;
86                 if(d >= (int)m_alpha_function->size()) d = m_alpha_function->size() - 1;
87                 span->a = (*m_alpha_function)[d];
88                 ++span;
89                 ++(*m_interpolator);
90             }
91             while(--len);
92         }
93 
94     private:
95         interpolator_type* m_interpolator;
96         GradientF*         m_gradient_function;
97         AlphaF*            m_alpha_function;
98         int                m_d1;
99         int                m_d2;
100     };
101 
102 
103     //=======================================================gradient_alpha_x
104     template<class ColorT> struct gradient_alpha_x
105     {
106         typedef typename ColorT::value_type alpha_type;
107         alpha_type operator [] (alpha_type x) const { return x; }
108     };
109 
110     //====================================================gradient_alpha_x_u8
111     struct gradient_alpha_x_u8
112     {
113         typedef int8u alpha_type;
114         alpha_type operator [] (alpha_type x) const { return x; }
115     };
116 
117     //==========================================gradient_alpha_one_munus_x_u8
118     struct gradient_alpha_one_munus_x_u8
119     {
120         typedef int8u alpha_type;
121         alpha_type operator [] (alpha_type x) const { return 255-x; }
122     };
123 
124 }
125 
126 #endif
127