removed unused files
This commit is contained in:
parent
e85db9ac69
commit
3848515e6e
7 changed files with 0 additions and 1145 deletions
|
@ -1,52 +0,0 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik 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 any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: render.hpp 39 2005-04-10 20:39:53Z pavlenko $
|
||||
|
||||
#ifndef RENDER_HPP
|
||||
#define RENDER_HPP
|
||||
|
||||
#include <stack>
|
||||
#include "envelope.hpp"
|
||||
#include "graphics.hpp"
|
||||
#include "datasource.hpp"
|
||||
#include "layer.hpp"
|
||||
#include "map.hpp"
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
template <typename Image> class Renderer
|
||||
{
|
||||
public:
|
||||
static void render(const Map& map,Image& image);
|
||||
private:
|
||||
Renderer();
|
||||
static void render_vector_layer(datasource_p const& ds,Map const& map,
|
||||
std::vector<std::string> const& ,
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
const Envelope<double>& bbox,Image& image);
|
||||
static void render_raster_layer(datasource_p const& ds,
|
||||
std::vector<std::string> const& namedStyles,
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
const Envelope<double>& bbox,Image& image);
|
||||
};
|
||||
}
|
||||
|
||||
#endif //RENDER_HPP
|
|
@ -1,44 +0,0 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik 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 any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: scanline.hpp 39 2005-04-10 20:39:53Z pavlenko $
|
||||
|
||||
#ifndef SCANLINE_HPP
|
||||
#define SCANLINE_HPP
|
||||
|
||||
#include "geometry.hpp"
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
template <typename PixBuffer> class ScanlineRasterizer
|
||||
{
|
||||
private:
|
||||
PixBuffer* pixbuf_;
|
||||
public:
|
||||
ScanlineRasterizer(PixBuffer& pixbuf)
|
||||
:pixbuf_(&pixbuf) {}
|
||||
|
||||
template <typename Transform>
|
||||
void render(const geometry_type& geom,const Color& c);
|
||||
private:
|
||||
ScanlineRasterizer(const ScanlineRasterizer&);
|
||||
ScanlineRasterizer& operator=(const ScanlineRasterizer&);
|
||||
void render_hline(int x0,int x1,int y,unsigned int rgba);
|
||||
};
|
||||
}
|
||||
#endif //SCANLINE_HPP
|
146
src/line_aa.cpp
146
src/line_aa.cpp
|
@ -1,146 +0,0 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik 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 any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: line_aa.cpp 29 2005-04-01 14:30:11Z pavlenko $
|
||||
|
||||
#include "line_aa.hpp"
|
||||
#include "geom_util.hpp"
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
template <typename PixBuffer>
|
||||
template <typename Transform>
|
||||
void LineRasterizerAA<PixBuffer>::render(const geometry_type& path,const Color& c)
|
||||
{
|
||||
unsigned rgba=c.rgba();
|
||||
typename geometry_type::path_iterator<Transform> itr=path.template begin<Transform>();
|
||||
|
||||
int x0 = 0 ,y0 = 0;
|
||||
while (itr!=path.template end<Transform>())
|
||||
{
|
||||
int x1=itr->x;
|
||||
int y1=itr->y;
|
||||
if (itr->cmd==SEG_LINETO || itr->cmd==SEG_CLOSE)
|
||||
{
|
||||
if (!(x0==x1 && y0==y1))
|
||||
{
|
||||
render_line(x0,y0,x1,y1,rgba);
|
||||
}
|
||||
}
|
||||
x0=x1;
|
||||
y0=y1;
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename PixBuffer>
|
||||
inline void LineRasterizerAA<PixBuffer>::render_line(int x0,int y0,int x1,int y1,unsigned rgba)
|
||||
{
|
||||
if (!clip_line(x0,y0,x1,y1,pixbuf_)) return;
|
||||
if(y0>y1)
|
||||
{
|
||||
swap(y0,y1);
|
||||
swap(x0,x1);
|
||||
}
|
||||
pixbuf_->setPixel(x0,y0,rgba);
|
||||
pixbuf_->setPixel(x1,y1,rgba);
|
||||
int dx=x1-x0;
|
||||
int dy=y1-y0;
|
||||
int xDir;
|
||||
if(dx>=0) xDir=1;
|
||||
else
|
||||
{
|
||||
xDir=-1;
|
||||
dx=-dx;
|
||||
}
|
||||
if(dx==0) // vertical line
|
||||
{
|
||||
for(int y=y0;y<y1;y++)
|
||||
{
|
||||
pixbuf_->setPixel(x0,y,rgba);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(dy==0) // horizontal line
|
||||
{
|
||||
if (x0>x1) swap(x0,x1);
|
||||
for(int x=x0;x<x1;++x)
|
||||
{
|
||||
pixbuf_->setPixel(x,y0,rgba);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(dx==dy) // diagonal line.
|
||||
{
|
||||
for(int x=x0,y=y0;y<y1;y++,x+=xDir)
|
||||
{
|
||||
pixbuf_->setPixel(x,y,rgba);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// line is not horizontal, diagonal, or vertical: use Wu Antialiasing:
|
||||
int error_acc=0;
|
||||
int t;
|
||||
if(dy>dx) // y-major line
|
||||
{
|
||||
int error_adj=(dx<<16)/dy;
|
||||
if(xDir<0)
|
||||
{
|
||||
while(--dy)
|
||||
{
|
||||
error_acc+=error_adj;
|
||||
++y0;
|
||||
x1=x0-(error_acc>>16);
|
||||
t=(error_acc>>8)&255;
|
||||
pixbuf_->blendPixel(x1 , y0, rgba,~t&255);
|
||||
pixbuf_->blendPixel(x1-1, y0, rgba,t);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while(--dy)
|
||||
{
|
||||
error_acc+=error_adj;
|
||||
++y0;
|
||||
x1=x0+(error_acc>>16);
|
||||
t=(error_acc>>8)&255;
|
||||
pixbuf_->blendPixel(x1 , y0, rgba,~t&255);
|
||||
pixbuf_->blendPixel(x1+xDir, y0, rgba,t);
|
||||
}
|
||||
}
|
||||
} // x-major line
|
||||
else
|
||||
{
|
||||
int error_adj=(dy<<16)/dx;
|
||||
while(--dx)
|
||||
{
|
||||
error_acc+=error_adj;
|
||||
x0+=xDir;
|
||||
y1=y0+(error_acc>>16);
|
||||
t=(error_acc>>8)&255;
|
||||
pixbuf_->blendPixel(x0, y1 , rgba,~t&255);
|
||||
pixbuf_->blendPixel(x0, y1+1, rgba,t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template class LineRasterizerAA<Image32>;
|
||||
template void LineRasterizerAA<Image32>::render<SHIFT0>(const geometry_type&,const Color&);
|
||||
}
|
|
@ -1,167 +0,0 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik 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 any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id$
|
||||
|
||||
#include "line_symbolizer.hpp"
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
#include "agg_rasterizer_scanline_aa.h"
|
||||
#include "agg_conv_stroke.h"
|
||||
#include "agg_conv_dash.h"
|
||||
#include "agg_conv_contour.h"
|
||||
#include "agg_vcgen_stroke.h"
|
||||
#include "agg_conv_adaptor_vcgen.h"
|
||||
#include "agg_conv_smooth_poly1.h"
|
||||
#include "agg_conv_marker.h"
|
||||
#include "agg_arrowhead.h"
|
||||
#include "agg_vcgen_markers_term.h"
|
||||
#include "agg_scanline_p.h"
|
||||
#include "agg_scanline_u.h"
|
||||
#include "agg_renderer_scanline.h"
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
#include "agg_path_storage.h"
|
||||
#include "agg_renderer_outline_aa.h"
|
||||
#include "agg_rasterizer_outline_aa.h"
|
||||
#include "agg_rasterizer_outline.h"
|
||||
#include "agg_renderer_outline_image.h"
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
line_symbolizer::line_symbolizer(stroke const& stroke)
|
||||
: symbolizer(),
|
||||
stroke_(stroke) {}
|
||||
|
||||
line_symbolizer::line_symbolizer(const Color& pen,float width)
|
||||
: symbolizer(),
|
||||
stroke_(pen,width) {}
|
||||
|
||||
void line_symbolizer::render(Feature const& feat, CoordTransform const& t,Image32& image) const
|
||||
{
|
||||
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
|
||||
typedef coord_transform<CoordTransform,geometry_type> path_type;
|
||||
typedef agg::renderer_outline_aa<ren_base> renderer_oaa;
|
||||
typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
|
||||
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
|
||||
|
||||
geometry_ptr const& geom=feat.get_geometry();
|
||||
if (geom && geom->num_points() > 1)
|
||||
{
|
||||
path_type path(t,*geom);
|
||||
agg::row_ptr_cache<agg::int8u> buf(image.raw_data(),image.width(),image.height(),
|
||||
image.width()*4);
|
||||
agg::pixfmt_rgba32 pixf(buf);
|
||||
ren_base renb(pixf);
|
||||
|
||||
Color const& col = stroke_.get_color();
|
||||
unsigned r=col.red();
|
||||
unsigned g=col.green();
|
||||
unsigned b=col.blue();
|
||||
|
||||
if (stroke_.has_dash())
|
||||
{
|
||||
renderer ren(renb);
|
||||
agg::rasterizer_scanline_aa<> ras;
|
||||
agg::scanline_u8 sl;
|
||||
agg::conv_dash<path_type> dash(path);
|
||||
dash_array const& d = stroke_.get_dash_array();
|
||||
dash_array::const_iterator itr = d.begin();
|
||||
dash_array::const_iterator end = d.end();
|
||||
while (itr != end)
|
||||
{
|
||||
dash.add_dash(itr->first, itr->second);
|
||||
++itr;
|
||||
}
|
||||
agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash);
|
||||
|
||||
line_join_e join=stroke_.get_line_join();
|
||||
if ( join == MITER_JOIN)
|
||||
stroke.generator().line_join(agg::miter_join);
|
||||
else if( join == MITER_REVERT_JOIN)
|
||||
stroke.generator().line_join(agg::miter_join);
|
||||
else if( join == ROUND_JOIN)
|
||||
stroke.generator().line_join(agg::round_join);
|
||||
else
|
||||
stroke.generator().line_join(agg::bevel_join);
|
||||
|
||||
line_cap_e cap=stroke_.get_line_cap();
|
||||
if (cap == BUTT_CAP)
|
||||
stroke.generator().line_cap(agg::butt_cap);
|
||||
else if (cap == SQUARE_CAP)
|
||||
stroke.generator().line_cap(agg::square_cap);
|
||||
else
|
||||
stroke.generator().line_cap(agg::round_cap);
|
||||
|
||||
stroke.generator().miter_limit(4.0);
|
||||
stroke.generator().width(stroke_.get_width());
|
||||
|
||||
ras.clip_box(0,0,image.width(),image.height());
|
||||
ras.add_path(stroke);
|
||||
ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity())));
|
||||
agg::render_scanlines(ras, sl, ren);
|
||||
}
|
||||
else if (0)//(stroke_.get_width() <= 1.0)
|
||||
{
|
||||
//faster but clipping doesn't work
|
||||
agg::line_profile_aa prof;
|
||||
prof.width(stroke_.get_width());
|
||||
renderer_oaa ren_oaa(renb, prof);
|
||||
rasterizer_outline_aa ras_oaa(ren_oaa);
|
||||
|
||||
ren_oaa.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity())));
|
||||
ren_oaa.clip_box(0,0,image.width(),image.height());
|
||||
ras_oaa.add_path(path);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer ren(renb);
|
||||
agg::rasterizer_scanline_aa<> ras;
|
||||
agg::scanline_p8 sl;
|
||||
agg::conv_stroke<path_type> stroke(path);
|
||||
|
||||
line_join_e join=stroke_.get_line_join();
|
||||
if ( join == MITER_JOIN)
|
||||
stroke.generator().line_join(agg::miter_join);
|
||||
else if( join == MITER_REVERT_JOIN)
|
||||
stroke.generator().line_join(agg::miter_join);
|
||||
else if( join == ROUND_JOIN)
|
||||
stroke.generator().line_join(agg::round_join);
|
||||
else
|
||||
stroke.generator().line_join(agg::bevel_join);
|
||||
|
||||
line_cap_e cap=stroke_.get_line_cap();
|
||||
if (cap == BUTT_CAP)
|
||||
stroke.generator().line_cap(agg::butt_cap);
|
||||
else if (cap == SQUARE_CAP)
|
||||
stroke.generator().line_cap(agg::square_cap);
|
||||
else
|
||||
stroke.generator().line_cap(agg::round_cap);
|
||||
|
||||
stroke.generator().miter_limit(4.0);
|
||||
stroke.generator().width(stroke_.get_width());
|
||||
|
||||
ras.clip_box(0,0,image.width(),image.height());
|
||||
ras.add_path(stroke);
|
||||
ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity())));
|
||||
agg::render_scanlines(ras, sl, ren);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik 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 any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id$
|
||||
|
||||
#include "polygon_symbolizer.hpp"
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_rendering_buffer.h"
|
||||
#include "agg_rasterizer_scanline_aa.h"
|
||||
#include "agg_scanline_p.h"
|
||||
#include "agg_scanline_u.h"
|
||||
#include "agg_renderer_scanline.h"
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
#include "agg_path_storage.h"
|
||||
#include "agg_span_allocator.h"
|
||||
#include "agg_span_pattern_rgba.h"
|
||||
#include "agg_image_accessors.h"
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
polygon_symbolizer::polygon_symbolizer(const Color& fill)
|
||||
: symbolizer(),
|
||||
fill_(fill) {}
|
||||
|
||||
|
||||
void polygon_symbolizer::render(Feature const& feat,CoordTransform const& t,Image32& image) const
|
||||
{
|
||||
typedef coord_transform<CoordTransform,geometry_type> path_type;
|
||||
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
|
||||
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
|
||||
|
||||
geometry_ptr const& geom=feat.get_geometry();
|
||||
if (geom && geom->num_points() > 2)
|
||||
{
|
||||
path_type path(t,*geom);
|
||||
agg::row_ptr_cache<agg::int8u> buf(image.raw_data(),image.width(),image.height(),
|
||||
image.width()*4);
|
||||
agg::pixfmt_rgba32 pixf(buf);
|
||||
ren_base renb(pixf);
|
||||
|
||||
unsigned r=fill_.red();
|
||||
unsigned g=fill_.green();
|
||||
unsigned b=fill_.blue();
|
||||
unsigned a=fill_.alpha();
|
||||
renderer ren(renb);
|
||||
|
||||
agg::rasterizer_scanline_aa<> ras;
|
||||
agg::scanline_u8 sl;
|
||||
ras.clip_box(0,0,image.width(),image.height());
|
||||
ras.add_path(path);
|
||||
ren.color(agg::rgba8(r, g, b, a));
|
||||
agg::render_scanlines(ras, sl, ren);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik 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 any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
//$Id: scanline.cpp 17 2005-03-08 23:58:43Z pavlenko $
|
||||
|
||||
#include <vector>
|
||||
#include "memory.hpp"
|
||||
#include "graphics.hpp"
|
||||
#include "scanline.hpp"
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
template <typename PixBuffer>
|
||||
template <typename Transform>
|
||||
void ScanlineRasterizer<PixBuffer>::render(const geometry_type& geom,const Color& c)
|
||||
{
|
||||
// ????
|
||||
}
|
||||
|
||||
template <typename PixBuffer>
|
||||
inline void ScanlineRasterizer<PixBuffer>::render_hline(int x0,int x1,int y,unsigned int rgba)
|
||||
{
|
||||
int x;
|
||||
if (x0<0) x0=0;
|
||||
if (x1> (int)pixbuf_->width()-1) x1=pixbuf_->width()-1;
|
||||
for(x=x0;x<=x1;x++) pixbuf_->setPixel(x,y,rgba);
|
||||
}
|
||||
|
||||
template class ScanlineRasterizer<Image32>;
|
||||
}
|
|
@ -1,619 +0,0 @@
|
|||
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||
* Copyright (C) 2005 Artem Pavlenko
|
||||
*
|
||||
* Mapnik 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 any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
// Credits:
|
||||
// I gratefully acknowledge the inspiring work of Maxim Shemanarev (McSeem),
|
||||
// author of Anti-Grain Geometry (http://www.antigrain.com), and also the developers
|
||||
// of the FreeType library (http://www.freetype.org). I have slightly modified the polygon
|
||||
// rasterizing algorithm to work with my library, but render_line and
|
||||
// render_hline remain intact.
|
||||
|
||||
//$Id: scanline_aa.cpp 29 2005-04-01 14:30:11Z pavlenko $
|
||||
|
||||
#include "scanline_aa.hpp"
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
inline void cell_aa::set_cover(int c, int a)
|
||||
{
|
||||
cover = c;
|
||||
area = a;
|
||||
}
|
||||
inline void cell_aa::add_cover(int c, int a)
|
||||
{
|
||||
cover += c;
|
||||
area += a;
|
||||
}
|
||||
inline void cell_aa::set_coord(int cx, int cy)
|
||||
{
|
||||
x = short(cx);
|
||||
y = short(cy);
|
||||
packed_coord = (cy << 16) + cx;
|
||||
}
|
||||
inline void cell_aa::set(int cx, int cy, int c, int a)
|
||||
{
|
||||
x = short(cx);
|
||||
y = short(cy);
|
||||
packed_coord = (cy << 16) + cx;
|
||||
cover = c;
|
||||
area = a;
|
||||
}
|
||||
|
||||
outline_aa::~outline_aa()
|
||||
{
|
||||
delete [] m_sorted_cells;
|
||||
if(m_num_blocks)
|
||||
{
|
||||
cell_aa** ptr = m_cells + m_num_blocks - 1;
|
||||
while(m_num_blocks--)
|
||||
{
|
||||
delete [] *ptr;
|
||||
ptr--;
|
||||
}
|
||||
delete [] m_cells;
|
||||
}
|
||||
}
|
||||
|
||||
outline_aa::outline_aa() :
|
||||
m_num_blocks(0),
|
||||
m_max_blocks(0),
|
||||
m_cur_block(0),
|
||||
m_num_cells(0),
|
||||
m_cells(0),
|
||||
m_cur_cell_ptr(0),
|
||||
m_sorted_cells(0),
|
||||
m_sorted_size(0),
|
||||
m_cur_x(0),
|
||||
m_cur_y(0),
|
||||
m_min_x(0x7FFFFFFF),
|
||||
m_min_y(0x7FFFFFFF),
|
||||
m_max_x(-0x7FFFFFFF),
|
||||
m_max_y(-0x7FFFFFFF),
|
||||
m_sorted(false)
|
||||
{
|
||||
m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0);
|
||||
}
|
||||
|
||||
void outline_aa::reset()
|
||||
{
|
||||
m_num_cells = 0;
|
||||
m_cur_block = 0;
|
||||
m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0);
|
||||
m_sorted = false;
|
||||
m_min_x = 0x7FFFFFFF;
|
||||
m_min_y = 0x7FFFFFFF;
|
||||
m_max_x = -0x7FFFFFFF;
|
||||
m_max_y = -0x7FFFFFFF;
|
||||
}
|
||||
|
||||
void outline_aa::allocate_block()
|
||||
{
|
||||
if(m_cur_block >= m_num_blocks)
|
||||
{
|
||||
if(m_num_blocks >= m_max_blocks)
|
||||
{
|
||||
cell_aa** new_cells = new cell_aa* [m_max_blocks + cell_block_pool];
|
||||
if(m_cells)
|
||||
{
|
||||
memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_aa*));
|
||||
delete [] m_cells;
|
||||
}
|
||||
m_cells = new_cells;
|
||||
m_max_blocks += cell_block_pool;
|
||||
}
|
||||
m_cells[m_num_blocks++] = new cell_aa [unsigned(cell_block_size)];
|
||||
}
|
||||
m_cur_cell_ptr = m_cells[m_cur_block++];
|
||||
}
|
||||
|
||||
inline void outline_aa::add_cur_cell()
|
||||
{
|
||||
if(m_cur_cell.area | m_cur_cell.cover)
|
||||
{
|
||||
if((m_num_cells & cell_block_mask) == 0)
|
||||
{
|
||||
if(m_num_blocks >= cell_block_limit) return;
|
||||
allocate_block();
|
||||
}
|
||||
*m_cur_cell_ptr++ = m_cur_cell;
|
||||
++m_num_cells;
|
||||
if(m_cur_cell.x < m_min_x) m_min_x = m_cur_cell.x;
|
||||
if(m_cur_cell.x > m_max_x) m_max_x = m_cur_cell.x;
|
||||
}
|
||||
}
|
||||
|
||||
inline void outline_aa::set_cur_cell(int x, int y)
|
||||
{
|
||||
if(m_cur_cell.packed_coord != (y << 16) + x)
|
||||
{
|
||||
add_cur_cell();
|
||||
m_cur_cell.set(x, y, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
inline void outline_aa::render_hline(int ey, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
int ex1 = x1 >> poly_base_shift;
|
||||
int ex2 = x2 >> poly_base_shift;
|
||||
int fx1 = x1 & poly_base_mask;
|
||||
int fx2 = x2 & poly_base_mask;
|
||||
|
||||
int delta, p, first, dx;
|
||||
int incr, lift, mod, rem;
|
||||
|
||||
|
||||
if(y1 == y2)
|
||||
{
|
||||
set_cur_cell(ex2, ey);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(ex1 == ex2)
|
||||
{
|
||||
delta = y2 - y1;
|
||||
m_cur_cell.add_cover(delta, (fx1 + fx2) * delta);
|
||||
return;
|
||||
}
|
||||
p = (poly_base_size - fx1) * (y2 - y1);
|
||||
first = poly_base_size;
|
||||
incr = 1;
|
||||
|
||||
dx = x2 - x1;
|
||||
|
||||
if(dx < 0)
|
||||
{
|
||||
p = fx1 * (y2 - y1);
|
||||
first = 0;
|
||||
incr = -1;
|
||||
dx = -dx;
|
||||
}
|
||||
|
||||
delta = p / dx;
|
||||
mod = p % dx;
|
||||
|
||||
if(mod < 0)
|
||||
{
|
||||
delta--;
|
||||
mod += dx;
|
||||
}
|
||||
|
||||
m_cur_cell.add_cover(delta, (fx1 + first) * delta);
|
||||
|
||||
ex1 += incr;
|
||||
set_cur_cell(ex1, ey);
|
||||
y1 += delta;
|
||||
|
||||
if(ex1 != ex2)
|
||||
{
|
||||
p = poly_base_size * (y2 - y1 + delta);
|
||||
lift = p / dx;
|
||||
rem = p % dx;
|
||||
|
||||
if (rem < 0)
|
||||
{
|
||||
lift--;
|
||||
rem += dx;
|
||||
}
|
||||
|
||||
mod -= dx;
|
||||
|
||||
while (ex1 != ex2)
|
||||
{
|
||||
delta = lift;
|
||||
mod += rem;
|
||||
if(mod >= 0)
|
||||
{
|
||||
mod -= dx;
|
||||
delta++;
|
||||
}
|
||||
|
||||
m_cur_cell.add_cover(delta, (poly_base_size) * delta);
|
||||
y1 += delta;
|
||||
ex1 += incr;
|
||||
set_cur_cell(ex1, ey);
|
||||
}
|
||||
}
|
||||
delta = y2 - y1;
|
||||
m_cur_cell.add_cover(delta, (fx2 + poly_base_size - first) * delta);
|
||||
}
|
||||
|
||||
void outline_aa::render_line(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
int ey1 = y1 >> poly_base_shift;
|
||||
int ey2 = y2 >> poly_base_shift;
|
||||
int fy1 = y1 & poly_base_mask;
|
||||
int fy2 = y2 & poly_base_mask;
|
||||
|
||||
int dx, dy, x_from, x_to;
|
||||
int p, rem, mod, lift, delta, first, incr;
|
||||
|
||||
dx = x2 - x1;
|
||||
dy = y2 - y1;
|
||||
|
||||
|
||||
if(ey1 == ey2)
|
||||
{
|
||||
render_hline(ey1, x1, fy1, x2, fy2);
|
||||
return;
|
||||
}
|
||||
incr = 1;
|
||||
if(dx == 0)
|
||||
{
|
||||
int ex = x1 >> poly_base_shift;
|
||||
int two_fx = (x1 - (ex << poly_base_shift)) << 1;
|
||||
int area;
|
||||
|
||||
first = poly_base_size;
|
||||
if(dy < 0)
|
||||
{
|
||||
first = 0;
|
||||
incr = -1;
|
||||
}
|
||||
|
||||
x_from = x1;
|
||||
|
||||
delta = first - fy1;
|
||||
m_cur_cell.add_cover(delta, two_fx * delta);
|
||||
|
||||
ey1 += incr;
|
||||
set_cur_cell(ex, ey1);
|
||||
|
||||
delta = first + first - poly_base_size;
|
||||
area = two_fx * delta;
|
||||
while(ey1 != ey2)
|
||||
{
|
||||
|
||||
m_cur_cell.set_cover(delta, area);
|
||||
ey1 += incr;
|
||||
set_cur_cell(ex, ey1);
|
||||
}
|
||||
|
||||
delta = fy2 - poly_base_size + first;
|
||||
m_cur_cell.add_cover(delta, two_fx * delta);
|
||||
return;
|
||||
}
|
||||
|
||||
p = (poly_base_size - fy1) * dx;
|
||||
|
||||
first = poly_base_size;
|
||||
|
||||
if(dy < 0)
|
||||
{
|
||||
p = fy1 * dx;
|
||||
first = 0;
|
||||
incr = -1;
|
||||
dy = -dy;
|
||||
}
|
||||
|
||||
delta = p / dy;
|
||||
mod = p % dy;
|
||||
|
||||
if(mod < 0)
|
||||
{
|
||||
delta--;
|
||||
mod += dy;
|
||||
}
|
||||
|
||||
x_from = x1 + delta;
|
||||
render_hline(ey1, x1, fy1, x_from, first);
|
||||
|
||||
ey1 += incr;
|
||||
set_cur_cell(x_from >> poly_base_shift, ey1);
|
||||
|
||||
if(ey1 != ey2)
|
||||
{
|
||||
p = poly_base_size * dx;
|
||||
lift = p / dy;
|
||||
rem = p % dy;
|
||||
|
||||
if(rem < 0)
|
||||
{
|
||||
lift--;
|
||||
rem += dy;
|
||||
}
|
||||
mod -= dy;
|
||||
|
||||
while(ey1 != ey2)
|
||||
{
|
||||
delta = lift;
|
||||
mod += rem;
|
||||
if (mod >= 0)
|
||||
{
|
||||
mod -= dy;
|
||||
delta++;
|
||||
}
|
||||
|
||||
x_to = x_from + delta;
|
||||
render_hline(ey1, x_from, poly_base_size - first, x_to, first);
|
||||
x_from = x_to;
|
||||
|
||||
ey1 += incr;
|
||||
set_cur_cell(x_from >> poly_base_shift, ey1);
|
||||
}
|
||||
}
|
||||
render_hline(ey1, x_from, poly_base_size - first, x2, fy2);
|
||||
}
|
||||
|
||||
void outline_aa::move_to(int x, int y)
|
||||
{
|
||||
if ( m_sorted ) reset();
|
||||
set_cur_cell(x >> poly_base_shift, y >> poly_base_shift);
|
||||
m_cur_x = x;
|
||||
m_cur_y = y;
|
||||
}
|
||||
|
||||
void outline_aa::line_to(int x, int y)
|
||||
{
|
||||
render_line(m_cur_x, m_cur_y, x, y);
|
||||
m_cur_x = x;
|
||||
m_cur_y = y;
|
||||
m_sorted = false;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
qsort_threshold = 9
|
||||
};
|
||||
|
||||
template <class T> static inline void swap_cells(T* a, T* b)
|
||||
{
|
||||
T temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
}
|
||||
|
||||
template <class T> static inline bool less_than(T* a, T* b)
|
||||
{
|
||||
return (*a)->packed_coord < (*b)->packed_coord;
|
||||
}
|
||||
|
||||
void outline_aa::qsort_cells(cell_aa** start, unsigned num)
|
||||
{
|
||||
cell_aa** stack[80];
|
||||
cell_aa*** top;
|
||||
cell_aa** limit;
|
||||
cell_aa** base;
|
||||
|
||||
limit = start + num;
|
||||
base = start;
|
||||
top = stack;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int len = int(limit - base);
|
||||
|
||||
cell_aa** i;
|
||||
cell_aa** j;
|
||||
cell_aa** pivot;
|
||||
|
||||
if(len > qsort_threshold)
|
||||
{
|
||||
pivot = base + len / 2;
|
||||
swap_cells(base, pivot);
|
||||
|
||||
i = base + 1;
|
||||
j = limit - 1;
|
||||
|
||||
if(less_than(j, i))
|
||||
{
|
||||
swap_cells(i, j);
|
||||
}
|
||||
|
||||
if(less_than(base, i))
|
||||
{
|
||||
swap_cells(base, i);
|
||||
}
|
||||
|
||||
if(less_than(j, base))
|
||||
{
|
||||
swap_cells(base, j);
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
do i++; while( less_than(i, base) );
|
||||
do j--; while( less_than(base, j) );
|
||||
|
||||
if ( i > j )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
swap_cells(i, j);
|
||||
}
|
||||
|
||||
swap_cells(base, j);
|
||||
|
||||
if(j - base > limit - i)
|
||||
{
|
||||
top[0] = base;
|
||||
top[1] = j;
|
||||
base = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
top[0] = i;
|
||||
top[1] = limit;
|
||||
limit = j;
|
||||
}
|
||||
top += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
j = base;
|
||||
i = j + 1;
|
||||
|
||||
for(; i < limit; j = i, i++)
|
||||
{
|
||||
for(; less_than(j + 1, j); j--)
|
||||
{
|
||||
swap_cells(j + 1, j);
|
||||
if (j == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(top > stack)
|
||||
{
|
||||
top -= 2;
|
||||
base = top[0];
|
||||
limit = top[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void outline_aa::sort_cells()
|
||||
{
|
||||
if(m_num_cells == 0) return;
|
||||
if(m_num_cells > m_sorted_size)
|
||||
{
|
||||
delete [] m_sorted_cells;
|
||||
m_sorted_size = m_num_cells;
|
||||
m_sorted_cells = new cell_aa* [m_num_cells + 1];
|
||||
}
|
||||
|
||||
cell_aa** sorted_ptr = m_sorted_cells;
|
||||
cell_aa** block_ptr = m_cells;
|
||||
cell_aa* cell_ptr;
|
||||
|
||||
unsigned nb = m_num_cells >> cell_block_shift;
|
||||
unsigned i;
|
||||
|
||||
while(nb--)
|
||||
{
|
||||
cell_ptr = *block_ptr++;
|
||||
i = cell_block_size;
|
||||
while(i--)
|
||||
{
|
||||
*sorted_ptr++ = cell_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
cell_ptr = *block_ptr++;
|
||||
i = m_num_cells & cell_block_mask;
|
||||
while(i--)
|
||||
{
|
||||
*sorted_ptr++ = cell_ptr++;
|
||||
}
|
||||
m_sorted_cells[m_num_cells] = 0;
|
||||
qsort_cells(m_sorted_cells, m_num_cells);
|
||||
m_min_y = m_sorted_cells[0]->y;
|
||||
m_max_y = m_sorted_cells[m_num_cells - 1]->y;
|
||||
}
|
||||
|
||||
const cell_aa* const* outline_aa::cells()
|
||||
{
|
||||
if(!m_sorted)
|
||||
{
|
||||
add_cur_cell();
|
||||
sort_cells();
|
||||
m_sorted = true;
|
||||
}
|
||||
return m_sorted_cells;
|
||||
}
|
||||
|
||||
template <typename PixBuffer>
|
||||
template <typename Transform>
|
||||
void ScanlineRasterizerAA<PixBuffer>::render(const geometry_type& geom,const Color& c)
|
||||
{
|
||||
reset();
|
||||
unsigned rgba=c.rgba();
|
||||
clip_box(0,0,pixbuf_->width(),pixbuf_->height());
|
||||
geometry_type::path_iterator<Transform> itr=geom.template begin<Transform>();
|
||||
while(itr!=geom.template end<Transform>())
|
||||
{
|
||||
if (itr->cmd == SEG_MOVETO)
|
||||
{
|
||||
move_to(itr->x,itr->y);
|
||||
}
|
||||
else if (itr->cmd == SEG_LINETO)
|
||||
{
|
||||
line_to(itr->x,itr->y);
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
|
||||
if(rewind_scanlines())
|
||||
{
|
||||
scanline_u8 sl;
|
||||
sl.reset(min_x(),max_x());
|
||||
while(sweep_scanline(sl))
|
||||
{
|
||||
int y = sl.y();
|
||||
unsigned num_spans = sl.num_spans();
|
||||
typename scanline_u8::const_iterator span = sl.begin();
|
||||
do
|
||||
{
|
||||
int x = span->x;
|
||||
if(span->len>0)
|
||||
{
|
||||
blend_hline(x,span->len,y,span->covers,rgba);
|
||||
}
|
||||
++span;
|
||||
} while(--num_spans);
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename PixBuffer>
|
||||
inline void ScanlineRasterizerAA<PixBuffer>::blend_hline(int x0,int len,int y,const unsigned char* covers,
|
||||
unsigned rgba)
|
||||
{
|
||||
if (y<0) return;
|
||||
if (y>(int)pixbuf_->height()-1) return;
|
||||
|
||||
if(x0<0)
|
||||
{
|
||||
len -= 0 - x0;
|
||||
if(len <= 0) return;
|
||||
covers += 0 - x0;
|
||||
x0 = 0;
|
||||
}
|
||||
if(x0 + len > (int)pixbuf_->width())
|
||||
{
|
||||
len = pixbuf_->width() - x0 + 1;
|
||||
if(len <= 0) return;
|
||||
}
|
||||
for(int x=x0;x<x0+len;x++)
|
||||
{
|
||||
int alpha = int(*covers++);
|
||||
pixbuf_->blendPixel(x,y,rgba,alpha);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename PixBuffer>
|
||||
inline void ScanlineRasterizerAA<PixBuffer>::render_hline(int x0,int x1,int y,unsigned rgba)
|
||||
{
|
||||
if (y < 0) return;
|
||||
if (y > (int)pixbuf_->height() - 1) return;
|
||||
if (x0 < 0) x0 = 0;
|
||||
if (x1 >(int)pixbuf_->width() - 1) x1 = pixbuf_->width()-1;
|
||||
for(int x=x0;x<=x1;x++) pixbuf_->setPixel(x,y,rgba);
|
||||
}
|
||||
|
||||
template class ScanlineRasterizerAA<Image32>;
|
||||
template void ScanlineRasterizerAA<Image32>::render<SHIFT8>(const geometry_type&,const Color&);
|
||||
}
|
Loading…
Reference in a new issue