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 #ifndef AGG_RENDERER_SCANLINE_INCLUDED 17 #define AGG_RENDERER_SCANLINE_INCLUDED 18 19 #include "agg_basics.h" 20 #include "agg_renderer_base.h" 21 #include "agg_render_scanlines.h" 22 23 namespace agg 24 { 25 26 //====================================================renderer_scanline_aa 27 template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa 28 { 29 public: 30 typedef BaseRenderer base_ren_type; 31 32 //-------------------------------------------------------------------- 33 renderer_scanline_aa(base_ren_type& ren, SpanGenerator& span_gen) : 34 m_ren(&ren), 35 m_span_gen(&span_gen) 36 { 37 } 38 39 //-------------------------------------------------------------------- 40 void prepare(unsigned max_span_len) 41 { 42 m_span_gen->prepare(max_span_len); 43 } 44 45 //-------------------------------------------------------------------- 46 template<class Scanline> void render(const Scanline& sl) 47 { 48 int y = sl.y(); 49 m_ren->first_clip_box(); 50 do 51 { 52 int xmin = m_ren->xmin(); 53 int xmax = m_ren->xmax(); 54 55 if(y >= m_ren->ymin() && y <= m_ren->ymax()) 56 { 57 unsigned num_spans = sl.num_spans(); 58 typename Scanline::const_iterator span = sl.begin(); 59 do 60 { 61 int x = span->x; 62 int len = span->len; 63 bool solid = false; 64 const typename Scanline::cover_type* covers = span->covers; 65 66 if(len < 0) 67 { 68 solid = true; 69 len = -len; 70 } 71 72 if(x < xmin) 73 { 74 len -= xmin - x; 75 if(!solid) 76 { 77 covers += xmin - x; 78 } 79 x = xmin; 80 } 81 82 if(len > 0) 83 { 84 if(x + len > xmax) 85 { 86 len = xmax - x + 1; 87 } 88 if(len > 0) 89 { 90 m_ren->blend_color_hspan_no_clip( 91 x, y, len, 92 m_span_gen->generate(x, y, len), 93 solid ? 0 : covers, 94 *covers); 95 } 96 } 97 ++span; 98 } 99 while(--num_spans); 100 } 101 } 102 while(m_ren->next_clip_box()); 103 } 104 105 private: 106 base_ren_type* m_ren; 107 SpanGenerator* m_span_gen; 108 }; 109 110 111 112 //==============================================renderer_scanline_aa_solid 113 template<class BaseRenderer> class renderer_scanline_aa_solid 114 { 115 public: 116 typedef BaseRenderer base_ren_type; 117 typedef typename base_ren_type::color_type color_type; 118 119 //-------------------------------------------------------------------- 120 renderer_scanline_aa_solid(base_ren_type& ren) : 121 m_ren(&ren) 122 { 123 } 124 125 //-------------------------------------------------------------------- 126 void color(const color_type& c) { m_color = c; } 127 const color_type& color() const { return m_color; } 128 129 //-------------------------------------------------------------------- 130 void prepare(unsigned) {} 131 132 //-------------------------------------------------------------------- 133 template<class Scanline> void render(const Scanline& sl) 134 { 135 int y = sl.y(); 136 unsigned num_spans = sl.num_spans(); 137 typename Scanline::const_iterator span = sl.begin(); 138 139 do 140 { 141 int x = span->x; 142 if(span->len > 0) 143 { 144 m_ren->blend_solid_hspan(x, y, (unsigned)span->len, 145 m_color, 146 span->covers); 147 } 148 else 149 { 150 m_ren->blend_hline(x, y, (unsigned)(x - span->len - 1), 151 m_color, 152 *(span->covers)); 153 } 154 ++span; 155 } 156 while(--num_spans); 157 } 158 159 private: 160 base_ren_type* m_ren; 161 color_type m_color; 162 }; 163 164 165 166 167 168 169 170 //===================================================renderer_scanline_bin 171 template<class BaseRenderer, class SpanGenerator> class renderer_scanline_bin 172 { 173 public: 174 typedef BaseRenderer base_ren_type; 175 176 //-------------------------------------------------------------------- 177 renderer_scanline_bin(base_ren_type& ren, SpanGenerator& span_gen) : 178 m_ren(&ren), 179 m_span_gen(&span_gen) 180 { 181 } 182 183 //-------------------------------------------------------------------- 184 void prepare(unsigned max_span_len) 185 { 186 m_span_gen->prepare(max_span_len); 187 } 188 189 //-------------------------------------------------------------------- 190 template<class Scanline> void render(const Scanline& sl) 191 { 192 int y = sl.y(); 193 m_ren->first_clip_box(); 194 do 195 { 196 int xmin = m_ren->xmin(); 197 int xmax = m_ren->xmax(); 198 199 if(y >= m_ren->ymin() && y <= m_ren->ymax()) 200 { 201 unsigned num_spans = sl.num_spans(); 202 typename Scanline::const_iterator span = sl.begin(); 203 do 204 { 205 int x = span->x; 206 int len = span->len; 207 208 if(len < 0) len = -len; 209 if(x < xmin) 210 { 211 len -= xmin - x; 212 x = xmin; 213 } 214 if(len > 0) 215 { 216 if(x + len > xmax) 217 { 218 len = xmax - x + 1; 219 } 220 if(len > 0) 221 { 222 m_ren->blend_color_hspan_no_clip( 223 x, y, len, 224 m_span_gen->generate(x, y, len), 225 0); 226 } 227 } 228 ++span; 229 } 230 while(--num_spans); 231 } 232 } 233 while(m_ren->next_clip_box()); 234 } 235 236 private: 237 base_ren_type* m_ren; 238 SpanGenerator* m_span_gen; 239 }; 240 241 242 243 //=============================================renderer_scanline_bin_solid 244 template<class BaseRenderer> class renderer_scanline_bin_solid 245 { 246 public: 247 typedef BaseRenderer base_ren_type; 248 typedef typename base_ren_type::color_type color_type; 249 250 //-------------------------------------------------------------------- 251 renderer_scanline_bin_solid(base_ren_type& ren) : 252 m_ren(&ren) 253 { 254 } 255 256 //-------------------------------------------------------------------- 257 void color(const color_type& c) { m_color = c; } 258 const color_type& color() const { return m_color; } 259 260 //-------------------------------------------------------------------- 261 void prepare(unsigned) {} 262 263 //-------------------------------------------------------------------- 264 template<class Scanline> void render(const Scanline& sl) 265 { 266 unsigned num_spans = sl.num_spans(); 267 typename Scanline::const_iterator span = sl.begin(); 268 do 269 { 270 m_ren->blend_hline(span->x, 271 sl.y(), 272 span->x - 1 + ((span->len < 0) ? 273 -span->len : 274 span->len), 275 m_color, 276 cover_full); 277 ++span; 278 } 279 while(--num_spans); 280 } 281 282 private: 283 base_ren_type* m_ren; 284 color_type m_color; 285 }; 286 287 } 288 289 #endif 290