update dev300-m58
[ooovba.git] / agg / inc / agg_span_gouraud.h
blob091ca5d8af538a9d9eba92a1eff09bd31dc58889
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 #ifndef AGG_SPAN_GOURAUD_INCLUDED
17 #define AGG_SPAN_GOURAUD_INCLUDED
19 #include "agg_basics.h"
20 #include "agg_math.h"
21 #include "agg_span_generator.h"
23 namespace agg
26 //============================================================span_gouraud
27 template<class ColorT, class Allocator>
28 class span_gouraud : public span_generator<ColorT, Allocator>
30 public:
31 typedef ColorT color_type;
32 typedef Allocator alloc_type;
34 struct coord_type
36 double x;
37 double y;
38 color_type color;
41 //--------------------------------------------------------------------
42 span_gouraud(alloc_type& alloc) :
43 span_generator<color_type, alloc_type>(alloc),
44 m_vertex(0)
46 m_cmd[0] = path_cmd_stop;
49 //--------------------------------------------------------------------
50 span_gouraud(alloc_type& alloc,
51 const color_type& c1,
52 const color_type& c2,
53 const color_type& c3,
54 double x1, double y1,
55 double x2, double y2,
56 double x3, double y3,
57 double d) :
58 span_generator<color_type, alloc_type>(alloc)
60 colors(c1, c2, c3);
61 triangle(x1, y1, x2, y2, x3, y3, d);
64 //--------------------------------------------------------------------
65 void colors(ColorT c1, ColorT c2, ColorT c3)
67 m_coord[0].color = c1;
68 m_coord[1].color = c2;
69 m_coord[2].color = c3;
72 //--------------------------------------------------------------------
73 // Sets the triangle and dilates it if needed.
74 // The trick here is to calculate beveled joins in the vertices of the
75 // triangle and render it as a 6-vertex polygon.
76 // It's necessary to achieve numerical stability.
77 // However, the coordinates to interpolate colors are calculated
78 // as miter joins (calc_intersection).
79 void triangle(double x1, double y1,
80 double x2, double y2,
81 double x3, double y3,
82 double d)
84 m_coord[0].x = m_x[0] = x1;
85 m_coord[0].y = m_y[0] = y1;
86 m_coord[1].x = m_x[1] = x2;
87 m_coord[1].y = m_y[1] = y2;
88 m_coord[2].x = m_x[2] = x3;
89 m_coord[2].y = m_y[2] = y3;
90 m_cmd[0] = path_cmd_move_to;
91 m_cmd[1] = path_cmd_line_to;
92 m_cmd[2] = path_cmd_line_to;
93 m_cmd[3] = path_cmd_stop;
95 if(d != 0.0)
97 dilate_triangle(m_coord[0].x, m_coord[0].y,
98 m_coord[1].x, m_coord[1].y,
99 m_coord[2].x, m_coord[2].y,
100 m_x, m_y, d);
102 calc_intersection(m_x[4], m_y[4], m_x[5], m_y[5],
103 m_x[0], m_y[0], m_x[1], m_y[1],
104 &m_coord[0].x, &m_coord[0].y);
106 calc_intersection(m_x[0], m_y[0], m_x[1], m_y[1],
107 m_x[2], m_y[2], m_x[3], m_y[3],
108 &m_coord[1].x, &m_coord[1].y);
110 calc_intersection(m_x[2], m_y[2], m_x[3], m_y[3],
111 m_x[4], m_y[4], m_x[5], m_y[5],
112 &m_coord[2].x, &m_coord[2].y);
113 m_cmd[3] = path_cmd_line_to;
114 m_cmd[4] = path_cmd_line_to;
115 m_cmd[5] = path_cmd_line_to;
116 m_cmd[6] = path_cmd_stop;
120 //--------------------------------------------------------------------
121 // Vertex Source Interface to feed the coordinates to the rasterizer
122 void rewind(unsigned)
124 m_vertex = 0;
127 //--------------------------------------------------------------------
128 unsigned vertex(double* x, double* y)
130 *x = m_x[m_vertex];
131 *y = m_y[m_vertex];
132 return m_cmd[m_vertex++];
137 protected:
138 //--------------------------------------------------------------------
139 void arrange_vertices(coord_type* coord) const
141 coord[0] = m_coord[0];
142 coord[1] = m_coord[1];
143 coord[2] = m_coord[2];
145 if(m_coord[0].y > m_coord[2].y)
147 coord[0] = m_coord[2];
148 coord[2] = m_coord[0];
151 coord_type tmp;
152 if(coord[0].y > coord[1].y)
154 tmp = coord[1];
155 coord[1] = coord[0];
156 coord[0] = tmp;
159 if(coord[1].y > coord[2].y)
161 tmp = coord[2];
162 coord[2] = coord[1];
163 coord[1] = tmp;
168 private:
169 //--------------------------------------------------------------------
170 coord_type m_coord[3];
171 double m_x[8];
172 double m_y[8];
173 unsigned m_cmd[8];
174 unsigned m_vertex;
179 #endif