450 lines
14 KiB
C++
Executable file
450 lines
14 KiB
C++
Executable file
//----------------------------------------------------------------------------
|
|
// Anti-Grain Geometry - Version 2.3
|
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
|
//
|
|
// Permission to copy, use, modify, sell and distribute this software
|
|
// is granted provided this copyright notice appears in all copies.
|
|
// This software is provided "as is" without express or implied
|
|
// warranty, and with no claim as to its suitability for any purpose.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
// Contact: mcseem@antigrain.com
|
|
// mcseemagg@yahoo.com
|
|
// http://www.antigrain.com
|
|
//----------------------------------------------------------------------------
|
|
|
|
#ifndef AGG_RENDERER_SCANLINE_INCLUDED
|
|
#define AGG_RENDERER_SCANLINE_INCLUDED
|
|
|
|
#include "agg_basics.h"
|
|
#include "agg_renderer_base.h"
|
|
#include "agg_render_scanlines.h"
|
|
|
|
namespace agg
|
|
{
|
|
|
|
//====================================================renderer_scanline_aa
|
|
template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa
|
|
{
|
|
public:
|
|
typedef BaseRenderer base_ren_type;
|
|
|
|
//--------------------------------------------------------------------
|
|
renderer_scanline_aa(base_ren_type& ren, SpanGenerator& span_gen) :
|
|
m_ren(&ren),
|
|
m_span_gen(&span_gen)
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
void prepare(unsigned max_span_len)
|
|
{
|
|
m_span_gen->prepare(max_span_len);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
template<class Scanline> void render(const Scanline& sl)
|
|
{
|
|
int y = sl.y();
|
|
m_ren->first_clip_box();
|
|
do
|
|
{
|
|
int xmin = m_ren->xmin();
|
|
int xmax = m_ren->xmax();
|
|
|
|
if(y >= m_ren->ymin() && y <= m_ren->ymax())
|
|
{
|
|
unsigned num_spans = sl.num_spans();
|
|
typename Scanline::const_iterator span = sl.begin();
|
|
do
|
|
{
|
|
int x = span->x;
|
|
int len = span->len;
|
|
bool solid = false;
|
|
const typename Scanline::cover_type* covers = span->covers;
|
|
|
|
if(len < 0)
|
|
{
|
|
solid = true;
|
|
len = -len;
|
|
}
|
|
|
|
if(x < xmin)
|
|
{
|
|
len -= xmin - x;
|
|
if(!solid)
|
|
{
|
|
covers += xmin - x;
|
|
}
|
|
x = xmin;
|
|
}
|
|
|
|
if(len > 0)
|
|
{
|
|
if(x + len > xmax)
|
|
{
|
|
len = xmax - x + 1;
|
|
}
|
|
if(len > 0)
|
|
{
|
|
m_ren->blend_color_hspan_no_clip(
|
|
x, y, len,
|
|
m_span_gen->generate(x, y, len),
|
|
solid ? 0 : covers,
|
|
*covers);
|
|
}
|
|
}
|
|
++span;
|
|
}
|
|
while(--num_spans);
|
|
}
|
|
}
|
|
while(m_ren->next_clip_box());
|
|
}
|
|
|
|
private:
|
|
base_ren_type* m_ren;
|
|
SpanGenerator* m_span_gen;
|
|
};
|
|
|
|
|
|
|
|
|
|
//==============================================renderer_scanline_aa_opaque
|
|
template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa_opaque
|
|
{
|
|
public:
|
|
typedef BaseRenderer base_ren_type;
|
|
|
|
//--------------------------------------------------------------------
|
|
renderer_scanline_aa_opaque(base_ren_type& ren, SpanGenerator& span_gen) :
|
|
m_ren(&ren),
|
|
m_span_gen(&span_gen)
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
void prepare(unsigned max_span_len)
|
|
{
|
|
m_span_gen->prepare(max_span_len);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
template<class Scanline> void render(const Scanline& sl)
|
|
{
|
|
int y = sl.y();
|
|
m_ren->first_clip_box();
|
|
do
|
|
{
|
|
int xmin = m_ren->xmin();
|
|
int xmax = m_ren->xmax();
|
|
|
|
if(y >= m_ren->ymin() && y <= m_ren->ymax())
|
|
{
|
|
unsigned num_spans = sl.num_spans();
|
|
typename Scanline::const_iterator span = sl.begin();
|
|
do
|
|
{
|
|
int x = span->x;
|
|
int len = span->len;
|
|
bool solid = false;
|
|
const typename Scanline::cover_type* covers = span->covers;
|
|
|
|
if(len < 0)
|
|
{
|
|
solid = true;
|
|
len = -len;
|
|
}
|
|
|
|
if(x < xmin)
|
|
{
|
|
len -= xmin - x;
|
|
if(!solid)
|
|
{
|
|
covers += xmin - x;
|
|
}
|
|
x = xmin;
|
|
}
|
|
|
|
if(len > 0)
|
|
{
|
|
if(x + len > xmax)
|
|
{
|
|
len = xmax - x + 1;
|
|
}
|
|
if(len > 0)
|
|
{
|
|
m_ren->blend_opaque_color_hspan_no_clip(
|
|
x, y, len,
|
|
m_span_gen->generate(x, y, len),
|
|
solid ? 0 : covers,
|
|
*covers);
|
|
}
|
|
}
|
|
++span;
|
|
}
|
|
while(--num_spans);
|
|
}
|
|
}
|
|
while(m_ren->next_clip_box());
|
|
}
|
|
|
|
private:
|
|
base_ren_type* m_ren;
|
|
SpanGenerator* m_span_gen;
|
|
};
|
|
|
|
|
|
|
|
//==============================================renderer_scanline_aa_solid
|
|
template<class BaseRenderer> class renderer_scanline_aa_solid
|
|
{
|
|
public:
|
|
typedef BaseRenderer base_ren_type;
|
|
typedef typename base_ren_type::color_type color_type;
|
|
|
|
//--------------------------------------------------------------------
|
|
renderer_scanline_aa_solid(base_ren_type& ren) :
|
|
m_ren(&ren)
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
void color(const color_type& c) { m_color = c; }
|
|
const color_type& color() const { return m_color; }
|
|
|
|
//--------------------------------------------------------------------
|
|
void prepare(unsigned) {}
|
|
|
|
//--------------------------------------------------------------------
|
|
template<class Scanline> void render(const Scanline& sl)
|
|
{
|
|
int y = sl.y();
|
|
unsigned num_spans = sl.num_spans();
|
|
typename Scanline::const_iterator span = sl.begin();
|
|
|
|
do
|
|
{
|
|
int x = span->x;
|
|
if(span->len > 0)
|
|
{
|
|
m_ren->blend_solid_hspan(x, y, (unsigned)span->len,
|
|
m_color,
|
|
span->covers);
|
|
}
|
|
else
|
|
{
|
|
m_ren->blend_hline(x, y, (unsigned)(x - span->len - 1),
|
|
m_color,
|
|
*(span->covers));
|
|
}
|
|
++span;
|
|
}
|
|
while(--num_spans);
|
|
}
|
|
|
|
private:
|
|
base_ren_type* m_ren;
|
|
color_type m_color;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//===================================================renderer_scanline_bin
|
|
template<class BaseRenderer, class SpanGenerator> class renderer_scanline_bin
|
|
{
|
|
public:
|
|
typedef BaseRenderer base_ren_type;
|
|
|
|
//--------------------------------------------------------------------
|
|
renderer_scanline_bin(base_ren_type& ren, SpanGenerator& span_gen) :
|
|
m_ren(&ren),
|
|
m_span_gen(&span_gen)
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
void prepare(unsigned max_span_len)
|
|
{
|
|
m_span_gen->prepare(max_span_len);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
template<class Scanline> void render(const Scanline& sl)
|
|
{
|
|
int y = sl.y();
|
|
m_ren->first_clip_box();
|
|
do
|
|
{
|
|
int xmin = m_ren->xmin();
|
|
int xmax = m_ren->xmax();
|
|
|
|
if(y >= m_ren->ymin() && y <= m_ren->ymax())
|
|
{
|
|
unsigned num_spans = sl.num_spans();
|
|
typename Scanline::const_iterator span = sl.begin();
|
|
do
|
|
{
|
|
int x = span->x;
|
|
int len = span->len;
|
|
|
|
if(len < 0) len = -len;
|
|
if(x < xmin)
|
|
{
|
|
len -= xmin - x;
|
|
x = xmin;
|
|
}
|
|
if(len > 0)
|
|
{
|
|
if(x + len > xmax)
|
|
{
|
|
len = xmax - x + 1;
|
|
}
|
|
if(len > 0)
|
|
{
|
|
m_ren->blend_color_hspan_no_clip(
|
|
x, y, len,
|
|
m_span_gen->generate(x, y, len),
|
|
0);
|
|
}
|
|
}
|
|
++span;
|
|
}
|
|
while(--num_spans);
|
|
}
|
|
}
|
|
while(m_ren->next_clip_box());
|
|
}
|
|
|
|
private:
|
|
base_ren_type* m_ren;
|
|
SpanGenerator* m_span_gen;
|
|
};
|
|
|
|
|
|
|
|
//===============================================renderer_scanline_bin_opaque
|
|
template<class BaseRenderer, class SpanGenerator> class renderer_scanline_bin_opaque
|
|
{
|
|
public:
|
|
typedef BaseRenderer base_ren_type;
|
|
|
|
//--------------------------------------------------------------------
|
|
renderer_scanline_bin_opaque(base_ren_type& ren, SpanGenerator& span_gen) :
|
|
m_ren(&ren),
|
|
m_span_gen(&span_gen)
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
void prepare(unsigned max_span_len)
|
|
{
|
|
m_span_gen->prepare(max_span_len);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
template<class Scanline> void render(const Scanline& sl)
|
|
{
|
|
int y = sl.y();
|
|
m_ren->first_clip_box();
|
|
do
|
|
{
|
|
int xmin = m_ren->xmin();
|
|
int xmax = m_ren->xmax();
|
|
|
|
if(y >= m_ren->ymin() && y <= m_ren->ymax())
|
|
{
|
|
unsigned num_spans = sl.num_spans();
|
|
typename Scanline::const_iterator span = sl.begin();
|
|
do
|
|
{
|
|
int x = span->x;
|
|
int len = span->len;
|
|
|
|
if(len < 0) len = -len;
|
|
if(x < xmin)
|
|
{
|
|
len -= xmin - x;
|
|
x = xmin;
|
|
}
|
|
if(len > 0)
|
|
{
|
|
if(x + len > xmax)
|
|
{
|
|
len = xmax - x + 1;
|
|
}
|
|
if(len > 0)
|
|
{
|
|
m_ren->blend_opaque_color_hspan_no_clip(
|
|
x, y, len,
|
|
m_span_gen->generate(x, y, len),
|
|
0);
|
|
}
|
|
}
|
|
++span;
|
|
}
|
|
while(--num_spans);
|
|
}
|
|
}
|
|
while(m_ren->next_clip_box());
|
|
}
|
|
|
|
private:
|
|
base_ren_type* m_ren;
|
|
SpanGenerator* m_span_gen;
|
|
};
|
|
|
|
|
|
|
|
|
|
//=============================================renderer_scanline_bin_solid
|
|
template<class BaseRenderer> class renderer_scanline_bin_solid
|
|
{
|
|
public:
|
|
typedef BaseRenderer base_ren_type;
|
|
typedef typename base_ren_type::color_type color_type;
|
|
|
|
//--------------------------------------------------------------------
|
|
renderer_scanline_bin_solid(base_ren_type& ren) :
|
|
m_ren(&ren)
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
void color(const color_type& c) { m_color = c; }
|
|
const color_type& color() const { return m_color; }
|
|
|
|
//--------------------------------------------------------------------
|
|
void prepare(unsigned) {}
|
|
|
|
//--------------------------------------------------------------------
|
|
template<class Scanline> void render(const Scanline& sl)
|
|
{
|
|
unsigned num_spans = sl.num_spans();
|
|
typename Scanline::const_iterator span = sl.begin();
|
|
do
|
|
{
|
|
m_ren->blend_hline(span->x,
|
|
sl.y(),
|
|
span->x - 1 + ((span->len < 0) ?
|
|
-span->len :
|
|
span->len),
|
|
m_color,
|
|
cover_full);
|
|
++span;
|
|
}
|
|
while(--num_spans);
|
|
}
|
|
|
|
private:
|
|
base_ren_type* m_ren;
|
|
color_type m_color;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|