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
21namespace 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        //--------------------------------------------------------------------
42        span_gradient_alpha() {}
43
44        //--------------------------------------------------------------------
45        span_gradient_alpha(interpolator_type& inter,
46                            const GradientF& gradient_function,
47                            const 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        //--------------------------------------------------------------------
57        interpolator_type& interpolator() { return *m_interpolator; }
58        const GradientF& gradient_function() const { return *m_gradient_function; }
59        const AlphaF& alpha_function() const { return *m_alpha_function; }
60        double d1() const { return double(m_d1) / gradient_subpixel_scale; }
61        double d2() const { return double(m_d2) / gradient_subpixel_scale; }
62
63        //--------------------------------------------------------------------
64        void interpolator(interpolator_type& i) { m_interpolator = &i; }
65        void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
66        void alpha_function(const AlphaF& af) { m_alpha_function = &af; }
67        void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); }
68        void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
69
70        //--------------------------------------------------------------------
71        void prepare() {}
72
73        //--------------------------------------------------------------------
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        const GradientF*   m_gradient_function;
97        const 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