📄 agg_renderer_scanline.h
字号:
//----------------------------------------------------------------------------
// Anti-Grain Geometry (AGG) - Version 2.5
// A high quality rendering engine for C++
// Copyright (C) 2002-2006 Maxim Shemanarev
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://antigrain.com
//
// AGG is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// AGG is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGG; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
//----------------------------------------------------------------------------
#ifndef AGG_RENDERER_SCANLINE_INCLUDED
#define AGG_RENDERER_SCANLINE_INCLUDED
#include "agg_basics.h"
#include "agg_renderer_base.h"
namespace agg
{
//================================================render_scanline_aa_solid
template<class Scanline, class BaseRenderer, class ColorT>
void render_scanline_aa_solid(const Scanline& sl,
BaseRenderer& ren,
const ColorT& color)
{
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
int x = span->x;
if(span->len > 0)
{
ren.blend_solid_hspan(x, y, (unsigned)span->len,
color,
span->covers);
}
else
{
ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
color,
*(span->covers));
}
if(--num_spans == 0) break;
++span;
}
}
//===============================================render_scanlines_aa_solid
template<class Rasterizer, class Scanline,
class BaseRenderer, class ColorT>
void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl,
BaseRenderer& ren, const ColorT& color)
{
if(ras.rewind_scanlines())
{
// Explicitly convert "color" to the BaseRenderer color type.
// For example, it can be called with color type "rgba", while
// "rgba8" is needed. Otherwise it will be implicitly
// converted in the loop many times.
//----------------------
typename BaseRenderer::color_type ren_color(color);
sl.reset(ras.min_x(), ras.max_x());
while(ras.sweep_scanline(sl))
{
//render_scanline_aa_solid(sl, ren, ren_color);
// This code is equivalent to the above call (copy/paste).
// It's just a "manual" optimization for old compilers,
// like Microsoft Visual C++ v6.0
//-------------------------------
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
int x = span->x;
if(span->len > 0)
{
ren.blend_solid_hspan(x, y, (unsigned)span->len,
ren_color,
span->covers);
}
else
{
ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
ren_color,
*(span->covers));
}
if(--num_spans == 0) break;
++span;
}
}
}
}
//==============================================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() : m_ren(0) {}
explicit renderer_scanline_aa_solid(base_ren_type& ren) : m_ren(&ren) {}
void attach(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() {}
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
render_scanline_aa_solid(sl, *m_ren, m_color);
}
private:
base_ren_type* m_ren;
color_type m_color;
};
//======================================================render_scanline_aa
template<class Scanline, class BaseRenderer,
class SpanAllocator, class SpanGenerator>
void render_scanline_aa(const Scanline& sl, BaseRenderer& ren,
SpanAllocator& alloc, SpanGenerator& span_gen)
{
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
int x = span->x;
int len = span->len;
const typename Scanline::cover_type* covers = span->covers;
if(len < 0) len = -len;
typename BaseRenderer::color_type* colors = alloc.allocate(len);
span_gen.generate(colors, x, y, len);
ren.blend_color_hspan(x, y, len, colors,
(span->len < 0) ? 0 : covers, *covers);
if(--num_spans == 0) break;
++span;
}
}
//=====================================================render_scanlines_aa
template<class Rasterizer, class Scanline, class BaseRenderer,
class SpanAllocator, class SpanGenerator>
void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
SpanAllocator& alloc, SpanGenerator& span_gen)
{
if(ras.rewind_scanlines())
{
sl.reset(ras.min_x(), ras.max_x());
span_gen.prepare();
while(ras.sweep_scanline(sl))
{
render_scanline_aa(sl, ren, alloc, span_gen);
}
}
}
//====================================================renderer_scanline_aa
template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
class renderer_scanline_aa
{
public:
typedef BaseRenderer base_ren_type;
typedef SpanAllocator alloc_type;
typedef SpanGenerator span_gen_type;
//--------------------------------------------------------------------
renderer_scanline_aa() : m_ren(0), m_alloc(0), m_span_gen(0) {}
renderer_scanline_aa(base_ren_type& ren,
alloc_type& alloc,
span_gen_type& span_gen) :
m_ren(&ren),
m_alloc(&alloc),
m_span_gen(&span_gen)
{}
void attach(base_ren_type& ren,
alloc_type& alloc,
span_gen_type& span_gen)
{
m_ren = &ren;
m_alloc = &alloc;
m_span_gen = &span_gen;
}
//--------------------------------------------------------------------
void prepare() { m_span_gen->prepare(); }
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
render_scanline_aa(sl, *m_ren, *m_alloc, *m_span_gen);
}
private:
base_ren_type* m_ren;
alloc_type* m_alloc;
span_gen_type* m_span_gen;
};
//===============================================render_scanline_bin_solid
template<class Scanline, class BaseRenderer, class ColorT>
void render_scanline_bin_solid(const Scanline& sl,
BaseRenderer& ren,
const ColorT& color)
{
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
for(;;)
{
ren.blend_hline(span->x,
sl.y(),
span->x - 1 + ((span->len < 0) ?
-span->len :
span->len),
color,
cover_full);
if(--num_spans == 0) break;
++span;
}
}
//==============================================render_scanlines_bin_solid
template<class Rasterizer, class Scanline,
class BaseRenderer, class ColorT>
void render_scanlines_bin_solid(Rasterizer& ras, Scanline& sl,
BaseRenderer& ren, const ColorT& color)
{
if(ras.rewind_scanlines())
{
// Explicitly convert "color" to the BaseRenderer color type.
// For example, it can be called with color type "rgba", while
// "rgba8" is needed. Otherwise it will be implicitly
// converted in the loop many times.
//----------------------
typename BaseRenderer::color_type ren_color(color);
sl.reset(ras.min_x(), ras.max_x());
while(ras.sweep_scanline(sl))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -