xref: /haiku/headers/libs/agg/agg_renderer_mclip.h (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
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_mclip
17 //
18 //----------------------------------------------------------------------------
19 
20 #ifndef AGG_RENDERER_MCLIP_INCLUDED
21 #define AGG_RENDERER_MCLIP_INCLUDED
22 
23 #include "agg_basics.h"
24 #include "agg_array.h"
25 #include "agg_renderer_base.h"
26 
27 namespace agg
28 {
29 
30     //----------------------------------------------------------renderer_mclip
31     template<class PixelFormat> class renderer_mclip
32     {
33     public:
34         typedef PixelFormat pixfmt_type;
35         typedef typename pixfmt_type::color_type color_type;
36         typedef renderer_base<pixfmt_type> base_ren_type;
37 
38         //--------------------------------------------------------------------
39         renderer_mclip(pixfmt_type& ren) :
40             m_ren(ren),
41             m_curr_cb(0),
42             m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax())
43         {
44         }
45 
46         //--------------------------------------------------------------------
47         const pixfmt_type& ren() const { return m_ren.ren();  }
48         pixfmt_type& ren() { return m_ren.ren();  }
49 
50         //--------------------------------------------------------------------
51         unsigned width()  const { return m_ren.width();  }
52         unsigned height() const { return m_ren.height(); }
53 
54         //--------------------------------------------------------------------
55         const rect& clip_box() const { return m_ren.clip_box(); }
56         int         xmin()     const { return m_ren.xmin(); }
57         int         ymin()     const { return m_ren.ymin(); }
58         int         xmax()     const { return m_ren.xmax(); }
59         int         ymax()     const { return m_ren.ymax(); }
60 
61         //--------------------------------------------------------------------
62         const rect& bounding_clip_box() const { return m_bounds;    }
63         int         bounding_xmin()     const { return m_bounds.x1; }
64         int         bounding_ymin()     const { return m_bounds.y1; }
65         int         bounding_xmax()     const { return m_bounds.x2; }
66         int         bounding_ymax()     const { return m_bounds.y2; }
67 
68         //--------------------------------------------------------------------
69         void first_clip_box()
70         {
71             m_curr_cb = 0;
72             if(m_clip.size())
73             {
74                 const rect& cb = m_clip[0];
75                 m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
76             }
77         }
78 
79         //--------------------------------------------------------------------
80         bool next_clip_box()
81         {
82             if(++m_curr_cb < m_clip.size())
83             {
84                 const rect& cb = m_clip[m_curr_cb];
85                 m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
86                 return true;
87             }
88             return false;
89         }
90 
91         //--------------------------------------------------------------------
92         void reset_clipping(bool visibility)
93         {
94             m_ren.reset_clipping(visibility);
95             m_clip.remove_all();
96             m_curr_cb = 0;
97             m_bounds = m_ren.clip_box();
98         }
99 
100         //--------------------------------------------------------------------
101         void add_clip_box(int x1, int y1, int x2, int y2)
102         {
103             rect cb(x1, y1, x2, y2);
104             cb.normalize();
105             if(cb.clip(rect(0, 0, width() - 1, height() - 1)))
106             {
107                 m_clip.add(cb);
108                 if(cb.x1 < m_bounds.x1) m_bounds.x1 = cb.x1;
109                 if(cb.y1 < m_bounds.y1) m_bounds.y1 = cb.y1;
110                 if(cb.x2 > m_bounds.x2) m_bounds.x2 = cb.x2;
111                 if(cb.y2 > m_bounds.y2) m_bounds.y2 = cb.y2;
112             }
113         }
114 
115         //--------------------------------------------------------------------
116         void clear(const color_type& c)
117         {
118             m_ren.clear(c);
119         }
120 
121         //--------------------------------------------------------------------
122         void copy_pixel(int x, int y, const color_type& c)
123         {
124             first_clip_box();
125             do
126             {
127                 if(m_ren.inbox(x, y))
128                 {
129                     m_ren.ren().copy_pixel(x, y, c);
130                     break;
131                 }
132             }
133             while(next_clip_box());
134         }
135 
136         //--------------------------------------------------------------------
137         void blend_pixel(int x, int y, const color_type& c, cover_type cover)
138         {
139             first_clip_box();
140             do
141             {
142                 if(m_ren.inbox(x, y))
143                 {
144                     m_ren.ren().blend_pixel(x, y, c, cover);
145                     break;
146                 }
147             }
148             while(next_clip_box());
149         }
150 
151         //--------------------------------------------------------------------
152         color_type pixel(int x, int y) const
153         {
154             first_clip_box();
155             do
156             {
157                 if(m_ren.inbox(x, y))
158                 {
159                     return m_ren.ren().pixel(x, y);
160                 }
161             }
162             while(next_clip_box());
163             return color_type::no_color();
164         }
165 
166         //--------------------------------------------------------------------
167         void copy_hline(int x1, int y, int x2, const color_type& c)
168         {
169             first_clip_box();
170             do
171             {
172                 m_ren.copy_hline(x1, y, x2, c);
173             }
174             while(next_clip_box());
175         }
176 
177         //--------------------------------------------------------------------
178         void copy_vline(int x, int y1, int y2, const color_type& c)
179         {
180             first_clip_box();
181             do
182             {
183                 m_ren.copy_vline(x, y1, y2, c);
184             }
185             while(next_clip_box());
186         }
187 
188         //--------------------------------------------------------------------
189         void blend_hline(int x1, int y, int x2,
190                          const color_type& c, cover_type cover)
191         {
192             first_clip_box();
193             do
194             {
195                 m_ren.blend_hline(x1, y, x2, c, cover);
196             }
197             while(next_clip_box());
198         }
199 
200         //--------------------------------------------------------------------
201         void blend_vline(int x, int y1, int y2,
202                          const color_type& c, cover_type cover)
203         {
204             first_clip_box();
205             do
206             {
207                 m_ren.blend_vline(x, y1, y2, c, cover);
208             }
209             while(next_clip_box());
210         }
211 
212         //--------------------------------------------------------------------
213         void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
214         {
215             first_clip_box();
216             do
217             {
218                 m_ren.copy_bar(x1, y1, x2, y2, c);
219             }
220             while(next_clip_box());
221         }
222 
223         //--------------------------------------------------------------------
224         void blend_bar(int x1, int y1, int x2, int y2,
225                        const color_type& c, cover_type cover)
226         {
227             first_clip_box();
228             do
229             {
230                 m_ren.blend_bar(x1, y1, x2, y2, c, cover);
231             }
232             while(next_clip_box());
233         }
234 
235 
236         //--------------------------------------------------------------------
237         void blend_solid_hspan(int x, int y, int len,
238                                const color_type& c, const cover_type* covers)
239         {
240             first_clip_box();
241             do
242             {
243                 m_ren.blend_solid_hspan(x, y, len, c, covers);
244             }
245             while(next_clip_box());
246         }
247 
248         //--------------------------------------------------------------------
249         void blend_solid_vspan(int x, int y, int len,
250                                const color_type& c, const cover_type* covers)
251         {
252             first_clip_box();
253             do
254             {
255                 m_ren.blend_solid_vspan(x, y, len, c, covers);
256             }
257             while(next_clip_box());
258         }
259 
260         //--------------------------------------------------------------------
261         void blend_color_hspan(int x, int y, int len,
262                                const color_type* colors,
263                                const cover_type* covers,
264                                cover_type cover = cover_full)
265         {
266             first_clip_box();
267             do
268             {
269                 m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
270             }
271             while(next_clip_box());
272         }
273 
274         //--------------------------------------------------------------------
275         void blend_color_vspan(int x, int y, int len,
276                                const color_type* colors,
277                                const cover_type* covers,
278                                cover_type cover = cover_full)
279         {
280             first_clip_box();
281             do
282             {
283                 m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
284             }
285             while(next_clip_box());
286         }
287 
288         //--------------------------------------------------------------------
289         void blend_color_hspan_no_clip(int x, int y, int len,
290                                        const color_type* colors,
291                                        const cover_type* covers,
292                                        cover_type cover = cover_full)
293         {
294             m_ren.blend_color_hspan_no_clip(x, y, len, colors, covers, cover);
295         }
296 
297         //--------------------------------------------------------------------
298         void blend_color_vspan_no_clip(int x, int y, int len,
299                                        const color_type* colors,
300                                        const cover_type* covers,
301                                        cover_type cover = cover_full)
302         {
303             m_ren.blend_color_vspan_no_clip(x, y, len, colors, covers, cover);
304         }
305 
306         //--------------------------------------------------------------------
307         void copy_from(const rendering_buffer& from,
308                        const rect* rc=0,
309                        int x_to=0,
310                        int y_to=0)
311         {
312             first_clip_box();
313             do
314             {
315                 m_ren.copy_from(from, rc, x_to, y_to);
316             }
317             while(next_clip_box());
318         }
319 
320     private:
321         renderer_mclip(const renderer_mclip<PixelFormat>&);
322         const renderer_mclip<PixelFormat>&
323             operator = (const renderer_mclip<PixelFormat>&);
324 
325         base_ren_type      m_ren;
326         pod_deque<rect, 4> m_clip;
327         unsigned           m_curr_cb;
328         rect               m_bounds;
329     };
330 
331 
332 }
333 
334 #endif
335