update dev300-m58
[ooovba.git] / agg / inc / agg_span_gouraud_rgba.h
blobf37f6a284e1d8f0cffd13550725beb38231ec6cc
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
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 //----------------------------------------------------------------------------
16 // Adaptation for high precision colors has been sponsored by
17 // Liberty Technology Systems, Inc., visit http://lib-sys.com
19 // Liberty Technology Systems, Inc. is the provider of
20 // PostScript and PDF technology for software developers.
21 //
22 //----------------------------------------------------------------------------
24 #ifndef AGG_SPAN_GOURAUD_RGBA_INCLUDED
25 #define AGG_SPAN_GOURAUD_RGBA_INCLUDED
27 #include "agg_basics.h"
28 #include "agg_color_rgba.h"
29 #include "agg_dda_line.h"
30 #include "agg_span_gouraud.h"
32 namespace agg
35 //=======================================================span_gouraud_rgba
36 template<class ColorT, class Allocator = span_allocator<ColorT> >
37 class span_gouraud_rgba : public span_gouraud<ColorT, Allocator>
39 public:
40 typedef Allocator alloc_type;
41 typedef ColorT color_type;
42 typedef typename ColorT::value_type value_type;
43 typedef span_gouraud<color_type, alloc_type> base_type;
44 typedef typename base_type::coord_type coord_type;
46 private:
47 //--------------------------------------------------------------------
48 struct rgba_calc
50 void init(const coord_type& c1, const coord_type& c2)
52 m_x1 = c1.x;
53 m_y1 = c1.y;
54 m_dx = c2.x - c1.x;
55 m_dy = 1.0 / (c2.y - c1.y);
56 m_r1 = c1.color.r;
57 m_g1 = c1.color.g;
58 m_b1 = c1.color.b;
59 m_a1 = c1.color.a;
60 m_dr = c2.color.r - m_r1;
61 m_dg = c2.color.g - m_g1;
62 m_db = c2.color.b - m_b1;
63 m_da = c2.color.a - m_a1;
66 void calc(int y)
68 double k = 0.0;
69 if(y > m_y1) k = (y - m_y1) * m_dy;
70 color_type rgba;
71 m_r = m_r1 + int(m_dr * k);
72 m_g = m_g1 + int(m_dg * k);
73 m_b = m_b1 + int(m_db * k);
74 m_a = m_a1 + int(m_da * k);
75 m_x = int(m_x1 + m_dx * k);
78 double m_x1;
79 double m_y1;
80 double m_dx;
81 double m_dy;
82 int m_r1;
83 int m_g1;
84 int m_b1;
85 int m_a1;
86 int m_dr;
87 int m_dg;
88 int m_db;
89 int m_da;
90 int m_r;
91 int m_g;
92 int m_b;
93 int m_a;
94 int m_x;
97 public:
99 //--------------------------------------------------------------------
100 span_gouraud_rgba(alloc_type& alloc) : base_type(alloc) {}
102 //--------------------------------------------------------------------
103 span_gouraud_rgba(alloc_type& alloc,
104 const color_type& c1,
105 const color_type& c2,
106 const color_type& c3,
107 double x1, double y1,
108 double x2, double y2,
109 double x3, double y3,
110 double d = 0) :
111 base_type(alloc, c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
114 //--------------------------------------------------------------------
115 void prepare(unsigned max_span_len)
117 base_type::prepare(max_span_len);
119 coord_type coord[3];
120 arrange_vertices(coord);
122 m_y2 = int(coord[1].y);
124 m_swap = calc_point_location(coord[0].x, coord[0].y,
125 coord[2].x, coord[2].y,
126 coord[1].x, coord[1].y) < 0.0;
128 m_rgba1.init(coord[0], coord[2]);
129 m_rgba2.init(coord[0], coord[1]);
130 m_rgba3.init(coord[1], coord[2]);
133 //--------------------------------------------------------------------
134 color_type* generate(int x, int y, unsigned len)
136 m_rgba1.calc(y);
137 const rgba_calc* pc1 = &m_rgba1;
138 const rgba_calc* pc2 = &m_rgba2;
140 if(y < m_y2)
142 m_rgba2.calc(y+1);
144 else
146 m_rgba3.calc(y);
147 pc2 = &m_rgba3;
150 if(m_swap)
152 const rgba_calc* t = pc2;
153 pc2 = pc1;
154 pc1 = t;
157 int nx = pc1->m_x;
158 unsigned nlen = pc2->m_x - pc1->m_x + 1;
160 if(nlen < len) nlen = len;
162 dda_line_interpolator<14> r(pc1->m_r, pc2->m_r, nlen);
163 dda_line_interpolator<14> g(pc1->m_g, pc2->m_g, nlen);
164 dda_line_interpolator<14> b(pc1->m_b, pc2->m_b, nlen);
165 dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen);
167 if(nx < x)
169 unsigned d = unsigned(x - nx);
170 r += d;
171 g += d;
172 b += d;
173 a += d;
176 color_type* span = base_type::allocator().span();
179 span->r = (value_type)r.y();
180 span->g = (value_type)g.y();
181 span->b = (value_type)b.y();
182 span->a = (value_type)a.y();
183 ++r;
184 ++g;
185 ++b;
186 ++a;
187 ++span;
189 while(--len);
190 return base_type::allocator().span();
194 private:
195 bool m_swap;
196 int m_y2;
197 rgba_calc m_rgba1;
198 rgba_calc m_rgba2;
199 rgba_calc m_rgba3;
206 #endif