00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef AGG_RENDERER_SCANLINE_INCLUDED
00017 #define AGG_RENDERER_SCANLINE_INCLUDED
00018
00019 #include "agg_basics.h"
00020 #include "agg_renderer_base.h"
00021 #include "agg_render_scanlines.h"
00022
00023 namespace agg
00024 {
00025
00026
00027 template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa
00028 {
00029 public:
00030 typedef BaseRenderer base_ren_type;
00031
00032
00033 renderer_scanline_aa(base_ren_type& ren, SpanGenerator& span_gen) :
00034 m_ren(&ren),
00035 m_span_gen(&span_gen)
00036 {
00037 }
00038
00039
00040 void prepare(unsigned max_span_len)
00041 {
00042 m_span_gen->prepare(max_span_len);
00043 }
00044
00045
00046 template<class Scanline> void render(const Scanline& sl)
00047 {
00048 int y = sl.y();
00049 m_ren->first_clip_box();
00050 do
00051 {
00052 int xmin = m_ren->xmin();
00053 int xmax = m_ren->xmax();
00054
00055 if(y >= m_ren->ymin() && y <= m_ren->ymax())
00056 {
00057 unsigned num_spans = sl.num_spans();
00058 typename Scanline::const_iterator span = sl.begin();
00059 do
00060 {
00061 int x = span->x;
00062 int len = span->len;
00063 bool solid = false;
00064 const typename Scanline::cover_type* covers = span->covers;
00065
00066 if(len < 0)
00067 {
00068 solid = true;
00069 len = -len;
00070 }
00071
00072 if(x < xmin)
00073 {
00074 len -= xmin - x;
00075 if(!solid)
00076 {
00077 covers += xmin - x;
00078 }
00079 x = xmin;
00080 }
00081
00082 if(len > 0)
00083 {
00084 if(x + len > xmax)
00085 {
00086 len = xmax - x + 1;
00087 }
00088 if(len > 0)
00089 {
00090 m_ren->blend_color_hspan_no_clip(
00091 x, y, len,
00092 m_span_gen->generate(x, y, len),
00093 solid ? 0 : covers,
00094 *covers);
00095 }
00096 }
00097 ++span;
00098 }
00099 while(--num_spans);
00100 }
00101 }
00102 while(m_ren->next_clip_box());
00103 }
00104
00105 private:
00106 base_ren_type* m_ren;
00107 SpanGenerator* m_span_gen;
00108 };
00109
00110
00111
00112
00113 template<class BaseRenderer> class renderer_scanline_aa_solid
00114 {
00115 public:
00116 typedef BaseRenderer base_ren_type;
00117 typedef typename base_ren_type::color_type color_type;
00118
00119
00120 renderer_scanline_aa_solid(base_ren_type& ren) :
00121 m_ren(&ren)
00122 {
00123 }
00124
00125
00126 void color(const color_type& c) { m_color = c; }
00127 const color_type& color() const { return m_color; }
00128
00129
00130 void prepare(unsigned) {}
00131
00132
00133 template<class Scanline> void render(const Scanline& sl)
00134 {
00135 int y = sl.y();
00136 unsigned num_spans = sl.num_spans();
00137 typename Scanline::const_iterator span = sl.begin();
00138
00139 do
00140 {
00141 int x = span->x;
00142 if(span->len > 0)
00143 {
00144 m_ren->blend_solid_hspan(x, y, (unsigned)span->len,
00145 m_color,
00146 span->covers);
00147 }
00148 else
00149 {
00150 m_ren->blend_hline(x, y, (unsigned)(x - span->len - 1),
00151 m_color,
00152 *(span->covers));
00153 }
00154 ++span;
00155 }
00156 while(--num_spans);
00157 }
00158
00159 private:
00160 base_ren_type* m_ren;
00161 color_type m_color;
00162 };
00163
00164
00165
00166
00167
00168
00169
00170
00171 template<class BaseRenderer, class SpanGenerator> class renderer_scanline_bin
00172 {
00173 public:
00174 typedef BaseRenderer base_ren_type;
00175
00176
00177 renderer_scanline_bin(base_ren_type& ren, SpanGenerator& span_gen) :
00178 m_ren(&ren),
00179 m_span_gen(&span_gen)
00180 {
00181 }
00182
00183
00184 void prepare(unsigned max_span_len)
00185 {
00186 m_span_gen->prepare(max_span_len);
00187 }
00188
00189
00190 template<class Scanline> void render(const Scanline& sl)
00191 {
00192 int y = sl.y();
00193 m_ren->first_clip_box();
00194 do
00195 {
00196 int xmin = m_ren->xmin();
00197 int xmax = m_ren->xmax();
00198
00199 if(y >= m_ren->ymin() && y <= m_ren->ymax())
00200 {
00201 unsigned num_spans = sl.num_spans();
00202 typename Scanline::const_iterator span = sl.begin();
00203 do
00204 {
00205 int x = span->x;
00206 int len = span->len;
00207
00208 if(len < 0) len = -len;
00209 if(x < xmin)
00210 {
00211 len -= xmin - x;
00212 x = xmin;
00213 }
00214 if(len > 0)
00215 {
00216 if(x + len > xmax)
00217 {
00218 len = xmax - x + 1;
00219 }
00220 if(len > 0)
00221 {
00222 m_ren->blend_color_hspan_no_clip(
00223 x, y, len,
00224 m_span_gen->generate(x, y, len),
00225 0);
00226 }
00227 }
00228 ++span;
00229 }
00230 while(--num_spans);
00231 }
00232 }
00233 while(m_ren->next_clip_box());
00234 }
00235
00236 private:
00237 base_ren_type* m_ren;
00238 SpanGenerator* m_span_gen;
00239 };
00240
00241
00242
00243
00244 template<class BaseRenderer> class renderer_scanline_bin_solid
00245 {
00246 public:
00247 typedef BaseRenderer base_ren_type;
00248 typedef typename base_ren_type::color_type color_type;
00249
00250
00251 renderer_scanline_bin_solid(base_ren_type& ren) :
00252 m_ren(&ren)
00253 {
00254 }
00255
00256
00257 void color(const color_type& c) { m_color = c; }
00258 const color_type& color() const { return m_color; }
00259
00260
00261 void prepare(unsigned) {}
00262
00263
00264 template<class Scanline> void render(const Scanline& sl)
00265 {
00266 unsigned num_spans = sl.num_spans();
00267 typename Scanline::const_iterator span = sl.begin();
00268 do
00269 {
00270 m_ren->blend_hline(span->x,
00271 sl.y(),
00272 span->x - 1 + ((span->len < 0) ?
00273 -span->len :
00274 span->len),
00275 m_color,
00276 cover_full);
00277 ++span;
00278 }
00279 while(--num_spans);
00280 }
00281
00282 private:
00283 base_ren_type* m_ren;
00284 color_type m_color;
00285 };
00286
00287 }
00288
00289 #endif