AGG line/polygon_pattern_symbolizer add support for SVG patterns

This commit is contained in:
artemp 2014-07-31 15:25:22 +01:00
parent d4224ae852
commit 18a7731d42
6 changed files with 64 additions and 32 deletions

View file

@ -36,6 +36,7 @@
#include <mapnik/request.hpp>
#include <mapnik/gamma_method.hpp>
#include <mapnik/renderer_common.hpp>
#include <mapnik/image_data.hpp>
// boost
#include <memory>
@ -180,6 +181,9 @@ private:
renderer_common common_;
void setup(Map const& m);
};
}
std::shared_ptr<image_data_32> render_pattern(rasterizer & ras, marker const& marker);
} // namespace mapnik
#endif // MAPNIK_AGG_RENDERER_HPP

View file

@ -64,21 +64,14 @@ public:
}
marker(boost::optional<mapnik::image_ptr> const& data)
: bitmap_data_(data)
{
}
: bitmap_data_(data) {}
marker(boost::optional<mapnik::svg_path_ptr> const& data)
: vector_data_(data)
{
}
: vector_data_(data) {}
marker(marker const& rhs)
: bitmap_data_(rhs.bitmap_data_),
vector_data_(rhs.vector_data_)
{}
vector_data_(rhs.vector_data_) {}
box2d<double> bounding_box() const
{

View file

@ -350,10 +350,10 @@ void agg_renderer<T0,T1>::render_marker(pixel_position const& pos,
vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source());
svg_path_adapter svg_path(stl_storage);
svg_renderer_agg<svg_path_adapter,
svg_attribute_type,
renderer_type,
pixfmt_comp_type> svg_renderer(svg_path,
(*marker.get_vector_data())->attributes());
svg_attribute_type,
renderer_type,
pixfmt_comp_type> svg_renderer(svg_path,
(*marker.get_vector_data())->attributes());
svg_renderer.render(*ras_ptr, sl, renb, mtx, opacity, bbox);
}
@ -502,6 +502,34 @@ void agg_renderer<T0,T1>::draw_geo_extent(box2d<double> const& extent, mapnik::c
}
}
std::shared_ptr<image_data_32> render_pattern(rasterizer & ras, marker const& marker)
{
using pixfmt = agg::pixfmt_rgba32_pre;
using renderer_base = agg::renderer_base<pixfmt>;
using renderer_solid = agg::renderer_scanline_aa_solid<renderer_base>;
agg::scanline_u8 sl;
double width = marker.width();
double height = marker.height();
std::shared_ptr<mapnik::image_data_32> image = std::make_shared<mapnik::image_data_32>(width, height);
agg::rendering_buffer buf(image->getBytes(), image->width(), image->height(), image->width() * 4);
pixfmt pixf(buf);
renderer_base renb(pixf);
mapnik::box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box();
mapnik::coord<double,2> c = bbox.center();
agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
mtx.translate(0.5 * image->width(), 0.5 * image->height());
mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage((*marker.get_vector_data())->source());
mapnik::svg::svg_path_adapter svg_path(stl_storage);
mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter,
agg::pod_bvector<mapnik::svg::path_attributes>,
renderer_solid,
agg::pixfmt_rgba32_pre > svg_renderer(svg_path,
(*marker.get_vector_data())->attributes());
svg_renderer.render(ras, sl, renb, mtx, 1.0, bbox);
return image;
}
template class agg_renderer<image_32>;
template void agg_renderer<image_32>::debug_draw_box<agg::rendering_buffer>(
agg::rendering_buffer& buf,

View file

@ -102,16 +102,18 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
if (filename.empty()) return;
boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true);
if (!mark) return;
if (!(*mark)->is_bitmap())
boost::optional<mapnik::marker_ptr> marker_ptr = marker_cache::instance().find(filename, true);
if (!marker_ptr || !(*marker_ptr)) return;
boost::optional<image_ptr> pat;
if ((*marker_ptr)->is_bitmap())
{
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer";
return;
boost::optional<image_ptr> pat = (*marker_ptr)->get_bitmap_data();
}
else
{
pat = render_pattern(*ras_ptr, **marker_ptr);
}
boost::optional<image_ptr> pat = (*mark)->get_bitmap_data();
if (!pat) return;
bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, false);
@ -139,7 +141,7 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
if (clip)
{
double padding = (double)(common_.query_extent_.width()/pixmap_.width());
double half_stroke = (*mark)->width()/2.0;
double half_stroke = (*marker_ptr)->width()/2.0;
if (half_stroke > 1)
padding *= half_stroke;
if (std::fabs(offset) > 0)

View file

@ -32,6 +32,9 @@
#include <mapnik/vertex_converters.hpp>
#include <mapnik/parse_path.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/svg/svg_converter.hpp>
#include <mapnik/svg/svg_renderer_agg.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
// agg
#include "agg_basics.h"
@ -56,25 +59,27 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
{
std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
if (filename.empty()) return;
boost::optional<mapnik::marker_ptr> marker = marker_cache::instance().find(filename, true);
if (!marker) return;
boost::optional<mapnik::marker_ptr> marker_ptr = marker_cache::instance().find(filename, true);
if (!marker_ptr || !(*marker_ptr)) return;
boost::optional<image_ptr> pat;
if (!(*marker)->is_bitmap())
if ((*marker_ptr)->is_bitmap())
{
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer";
return;
pat = (*marker_ptr)->get_bitmap_data();
}
else
{
pat = render_pattern(*ras_ptr, **marker_ptr);
}
pat = (*marker)->get_bitmap_data();
if (!pat) return;
using clipped_geometry_type = agg::conv_clip_polygon<geometry_type>;
using path_type = coord_transform<CoordTransform,clipped_geometry_type>;
agg::rendering_buffer buf(current_buffer_->raw_data(), current_buffer_->width(), current_buffer_->height(), current_buffer_->width() * 4);
agg::rendering_buffer buf(current_buffer_->raw_data(), current_buffer_->width(),
current_buffer_->height(), current_buffer_->width() * 4);
ras_ptr->reset();
double gamma = get<value_double>(sym, keys::gamma, feature, common_.vars_, 1.0);
gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, common_.vars_, GAMMA_POWER);

View file

@ -155,7 +155,7 @@ int main (int argc,char** argv)
std::clog << "found width of '" << w << "' and height of '" << h << "'\n";
}
// 10 pixel buffer to avoid edge clipping of 100% svg's
mapnik::image_32 im(w+10,h+10);
mapnik::image_32 im(w+0,h+0);
agg::rendering_buffer buf(im.raw_data(), im.width(), im.height(), im.width() * 4);
pixfmt pixf(buf);
renderer_base renb(pixf);