xref: /haiku/headers/libs/agg/agg_renderer_primitives.h (revision 95bac3fda53a4cb21880712d7b43f8c21db32a2e)
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.2
3 // Copyright (C) 2002-2004 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 // class renderer_primitives
17 //
18 //----------------------------------------------------------------------------
19 
20 #ifndef AGG_RENDERER_PRIMITIVES_INCLUDED
21 #define AGG_RENDERER_PRIMITIVES_INCLUDED
22 
23 #include "agg_basics.h"
24 #include "agg_renderer_base.h"
25 #include "agg_dda_line.h"
26 #include "agg_ellipse_bresenham.h"
27 
28 namespace agg
29 {
30     //-----------------------------------------------------renderer_primitives
31     template<class BaseRenderer> class renderer_primitives
32     {
33     public:
34         typedef BaseRenderer base_ren_type;
35         typedef typename base_ren_type::color_type color_type;
36 
37         //--------------------------------------------------------------------
38         renderer_primitives(base_ren_type& ren) :
39             m_ren(&ren),
40             m_fill_color(),
41             m_line_color(),
42             m_curr_x(0),
43             m_curr_y(0)
44         {
45         }
46 
47         //--------------------------------------------------------------------
48         static int coord(double c)
49         {
50             return int(c * line_bresenham_interpolator::subpixel_size);
51         }
52 
53         //--------------------------------------------------------------------
54         void fill_color(const color_type& c) { m_fill_color = c; }
55         void line_color(const color_type& c) { m_line_color = c; }
56         const color_type& fill_color() const { return m_fill_color; }
57         const color_type& line_color() const { return m_line_color; }
58 
59         //--------------------------------------------------------------------
60         void rectangle(int x1, int y1, int x2, int y2)
61         {
62             m_ren->blend_hline(x1,   y1,   x2-1, m_line_color, cover_full);
63             m_ren->blend_vline(x2,   y1,   y2-1, m_line_color, cover_full);
64             m_ren->blend_hline(x1+1, y2,   x2,   m_line_color, cover_full);
65             m_ren->blend_vline(x1,   y1+1, y2,   m_line_color, cover_full);
66         }
67 
68         //--------------------------------------------------------------------
69         void solid_rectangle(int x1, int y1, int x2, int y2)
70         {
71             m_ren->blend_bar(x1, y1, x2, y2, m_fill_color, cover_full);
72         }
73 
74         //--------------------------------------------------------------------
75         void outlined_rectangle(int x1, int y1, int x2, int y2)
76         {
77             rectangle(x1, y1, x2, y2);
78             m_ren->blend_bar(x1+1, y1+1, x2-1, y2-1, m_fill_color, cover_full);
79         }
80 
81         //--------------------------------------------------------------------
82         void ellipse(int x, int y, int rx, int ry)
83         {
84             ellipse_bresenham_interpolator ei(rx, ry);
85             int dx = 0;
86             int dy = -ry;
87             do
88             {
89                 dx += ei.dx();
90                 dy += ei.dy();
91                 m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
92                 m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full);
93                 m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
94                 m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
95                 ++ei;
96             }
97             while(dy < 0);
98         }
99 
100         //--------------------------------------------------------------------
101         void solid_ellipse(int x, int y, int rx, int ry)
102         {
103             ellipse_bresenham_interpolator ei(rx, ry);
104             int dx = 0;
105             int dy = -ry;
106             int dy0 = dy;
107             int dx0 = dx;
108 
109             do
110             {
111                 dx += ei.dx();
112                 dy += ei.dy();
113 
114                 if(dy != dy0)
115                 {
116                     m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full);
117                     m_ren->blend_hline(x-dx0, y-dy0, x+dx0, m_fill_color, cover_full);
118                 }
119                 dx0 = dx;
120                 dy0 = dy;
121                 ++ei;
122             }
123             while(dy < 0);
124             m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full);
125         }
126 
127         //--------------------------------------------------------------------
128         void outlined_ellipse(int x, int y, int rx, int ry)
129         {
130             ellipse_bresenham_interpolator ei(rx, ry);
131             int dx = 0;
132             int dy = -ry;
133 
134             do
135             {
136                 dx += ei.dx();
137                 dy += ei.dy();
138 
139                 m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
140                 m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full);
141                 m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
142                 m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
143 
144                 if(ei.dy() && dx)
145                 {
146                    m_ren->blend_hline(x-dx+1, y+dy, x+dx-1, m_fill_color, cover_full);
147                    m_ren->blend_hline(x-dx+1, y-dy, x+dx-1, m_fill_color, cover_full);
148                 }
149                 ++ei;
150             }
151             while(dy < 0);
152         }
153 
154         //--------------------------------------------------------------------
155         void line(int x1, int y1, int x2, int y2, bool last=false)
156         {
157             line_bresenham_interpolator li(x1, y1, x2, y2);
158 
159             unsigned len = li.len();
160             if(len == 0)
161             {
162                 if(last)
163                 {
164                     m_ren->blend_pixel(li.line_lr(x1), li.line_lr(y1), m_line_color, cover_full);
165                 }
166                 return;
167             }
168 
169             if(last) ++len;
170 
171             if(li.is_ver())
172             {
173                 do
174                 {
175                     m_ren->blend_pixel(li.x2(), li.y1(), m_line_color, cover_full);
176                     li.vstep();
177                 }
178                 while(--len);
179             }
180             else
181             {
182                 do
183                 {
184                     m_ren->blend_pixel(li.x1(), li.y2(), m_line_color, cover_full);
185                     li.hstep();
186                 }
187                 while(--len);
188             }
189         }
190 
191         //--------------------------------------------------------------------
192         void move_to(int x, int y)
193         {
194             m_curr_x = x;
195             m_curr_y = y;
196         }
197 
198         //--------------------------------------------------------------------
199         void line_to(int x, int y, bool last=false)
200         {
201             line(m_curr_x, m_curr_y, x, y, last);
202             m_curr_x = x;
203             m_curr_y = y;
204         }
205 
206         //--------------------------------------------------------------------
207         const base_ren_type& ren() const { return *m_ren; }
208         base_ren_type& ren() { return *m_ren; }
209 
210         //--------------------------------------------------------------------
211         const rendering_buffer& rbuf() const { return m_ren->rbuf(); }
212         rendering_buffer& rbuf() { return m_ren->rbuf(); }
213 
214     private:
215         base_ren_type* m_ren;
216         color_type m_fill_color;
217         color_type m_line_color;
218         int m_curr_x;
219         int m_curr_y;
220     };
221 
222 }
223 
224 #endif
225