16 #ifndef AGG_SPAN_GRADIENT_INCLUDED 17 #define AGG_SPAN_GRADIENT_INCLUDED 21 #include "agg_basics.h" 23 #include "agg_array.h" 29 enum gradient_subpixel_scale_e
31 gradient_subpixel_shift = 4,
32 gradient_subpixel_scale = 1 << gradient_subpixel_shift,
33 gradient_subpixel_mask = gradient_subpixel_scale - 1
39 template<
class ColorT,
46 typedef Interpolator interpolator_type;
47 typedef ColorT color_type;
49 enum downscale_shift_e
51 downscale_shift = interpolator_type::subpixel_shift -
52 gradient_subpixel_shift
60 GradientF& gradient_function,
61 ColorF& color_function,
62 double d1,
double d2) :
63 m_interpolator(&inter),
64 m_gradient_function(&gradient_function),
65 m_color_function(&color_function),
66 m_d1(iround(d1 * gradient_subpixel_scale)),
67 m_d2(iround(d2 * gradient_subpixel_scale))
71 interpolator_type& interpolator() {
return *m_interpolator; }
72 const GradientF& gradient_function()
const {
return *m_gradient_function; }
73 const ColorF& color_function()
const {
return *m_color_function; }
74 double d1()
const {
return double(m_d1) / gradient_subpixel_scale; }
75 double d2()
const {
return double(m_d2) / gradient_subpixel_scale; }
78 void interpolator(interpolator_type& i) { m_interpolator = &i; }
79 void gradient_function(GradientF& gf) { m_gradient_function = &gf; }
80 void color_function(ColorF& cf) { m_color_function = &cf; }
81 void d1(
double v) { m_d1 = iround(v * gradient_subpixel_scale); }
82 void d2(
double v) { m_d2 = iround(v * gradient_subpixel_scale); }
88 void generate(color_type* span,
int x,
int y,
unsigned len)
92 m_interpolator->begin(x+0.5, y+0.5, len);
95 m_interpolator->coordinates(&x, &y);
96 int d = m_gradient_function->calculate(x >> downscale_shift,
97 y >> downscale_shift, m_d2);
98 d = ((d - m_d1) * (
int)m_color_function->size()) / dd;
100 if(d >= (
int)m_color_function->size()) d = m_color_function->size() - 1;
101 *span++ = (*m_color_function)[d];
108 interpolator_type* m_interpolator;
109 GradientF* m_gradient_function;
110 ColorF* m_color_function;
119 template<
class ColorT>
122 typedef ColorT color_type;
126 unsigned size = 256) :
127 m_c1(c1), m_c2(c2), m_size(size)
129 ,m_mult(1/(
double(size)-1))
133 unsigned size()
const {
return m_size; }
134 color_type operator [] (
unsigned v)
const 138 return m_c1.gradient(m_c2,
double(v) * m_mult );
142 void colors(
const color_type& c1,
const color_type& c2,
unsigned size = 256)
148 m_mult=1/(double(size)-1);
170 static AGG_INLINE
int calculate(
int x,
int y,
int)
172 return int(fast_sqrt(x*x + y*y));
181 static AGG_INLINE
int calculate(
int x,
int y,
int)
183 return int(fast_sqrt(x*x + y*y));
191 static AGG_INLINE
int calculate(
int x,
int y,
int)
193 return uround(std::sqrt(
double(x)*
double(x) +
double(y)*
double(y)));
203 m_r(100 * gradient_subpixel_scale),
212 m_r (iround(r * gradient_subpixel_scale)),
213 m_fx(iround(fx * gradient_subpixel_scale)),
214 m_fy(iround(fy * gradient_subpixel_scale))
220 void init(
double r,
double fx,
double fy)
222 m_r = iround(r * gradient_subpixel_scale);
223 m_fx = iround(fx * gradient_subpixel_scale);
224 m_fy = iround(fy * gradient_subpixel_scale);
229 double radius()
const {
return double(m_r) / gradient_subpixel_scale; }
230 double focus_x()
const {
return double(m_fx) / gradient_subpixel_scale; }
231 double focus_y()
const {
return double(m_fy) / gradient_subpixel_scale; }
234 int calculate(
int x,
int y,
int)
const 236 double dx = x - m_fx;
237 double dy = y - m_fy;
238 double d2 = dx * m_fy - dy * m_fx;
239 double d3 = m_r2 * (dx * dx + dy * dy) - d2 * d2;
240 return iround((dx * m_fx + dy * m_fy + std::sqrt(std::fabs(d3))) * m_mul);
253 m_r2 = double(m_r) * double(m_r);
254 m_fx2 = double(m_fx) * double(m_fx);
255 m_fy2 = double(m_fy) * double(m_fy);
256 double d = (m_r2 - (m_fx2 + m_fy2));
259 if(m_fx) {
if(m_fx < 0) ++m_fx;
else --m_fx; }
260 if(m_fy) {
if(m_fy < 0) ++m_fy;
else --m_fy; }
261 m_fx2 = double(m_fx) * double(m_fx);
262 m_fy2 = double(m_fy) * double(m_fy);
263 d = (m_r2 - (m_fx2 + m_fy2));
282 static int calculate(
int x,
int,
int) {
return x; }
290 static int calculate(
int,
int y,
int) {
return y; }
297 static AGG_INLINE
int calculate(
int x,
int y,
int)
299 int ax = std::abs(x);
300 int ay = std::abs(y);
301 return ax > ay ? ax : ay;
309 static AGG_INLINE
int calculate(
int x,
int y,
int d)
311 return std::abs(x) * std::abs(y) / d;
319 static AGG_INLINE
int calculate(
int x,
int y,
int)
321 return fast_sqrt(std::abs(x) * std::abs(y));
329 static AGG_INLINE
int calculate(
int x,
int y,
int d)
331 return uround(std::fabs(std::atan2(
double(y),
double(x))) *
double(d) / pi);
340 m_gradient(&gradient) {}
342 AGG_INLINE
int calculate(
int x,
int y,
int d)
const 344 int ret = m_gradient->calculate(x, y, d) % d;
345 if(ret < 0) ret += d;
350 const GradientF* m_gradient;
358 m_gradient(&gradient) {}
360 AGG_INLINE
int calculate(
int x,
int y,
int d)
const 363 int ret = m_gradient->calculate(x, y, d) % d2;
364 if(ret < 0) ret += d2;
365 if(ret >= d) ret = d2 - ret;
370 const GradientF* m_gradient;