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