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