Merge branch 'fix-group-symbolizer-crash' of https://github.com/lightmare/mapnik into lightmare-fix-group-symbolizer-crash

This commit is contained in:
Artem Pavlenko 2018-01-05 12:16:41 +00:00
commit c29f944726
17 changed files with 73 additions and 89 deletions

View file

@ -26,19 +26,14 @@
#define MAPNIK_CAIRO_RENDER_VECTOR_HPP #define MAPNIK_CAIRO_RENDER_VECTOR_HPP
// mapnik // mapnik
#include <mapnik/svg/svg_path_adapter.hpp> #include <mapnik/marker.hpp>
namespace agg { struct trans_affine; }
namespace mapnik { namespace mapnik {
class cairo_context; class cairo_context;
struct pixel_position;
template <typename T> class box2d;
namespace svg { struct path_attributes; }
void render_vector_marker(cairo_context & context, svg::svg_path_adapter & svg_path, void render_vector_marker(cairo_context & context, svg_path_adapter & svg_path,
agg::pod_bvector<svg::path_attributes> const & attributes, svg_attribute_type const& attributes,
box2d<double> const& bbox, agg::trans_affine const& tr, box2d<double> const& bbox, agg::trans_affine const& tr,
double opacity); double opacity);

View file

@ -27,25 +27,20 @@
#include <mapnik/image.hpp> #include <mapnik/image.hpp>
#include <mapnik/svg/svg_storage.hpp> #include <mapnik/svg/svg_storage.hpp>
#include <mapnik/svg/svg_path_adapter.hpp> #include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/util/variant.hpp> #include <mapnik/util/variant.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore_agg.hpp>
#include "agg_array.h"
#pragma GCC diagnostic pop
// stl // stl
#include <deque>
#include <memory> #include <memory>
namespace mapnik namespace mapnik
{ {
struct image_any; struct image_any;
namespace svg { struct path_attributes; }
using svg::svg_path_adapter; using svg::svg_path_adapter;
using svg_attribute_type = std::deque<svg::path_attributes>;
using svg_attribute_type = agg::pod_bvector<svg::path_attributes>;
using svg_storage_type = svg::svg_storage<svg::svg_path_storage, svg_attribute_type>; using svg_storage_type = svg::svg_storage<svg::svg_path_storage, svg_attribute_type>;
using svg_path_ptr = std::shared_ptr<svg_storage_type>; using svg_path_ptr = std::shared_ptr<svg_storage_type>;
using image_ptr = std::shared_ptr<image_any>; using image_ptr = std::shared_ptr<image_any>;

View file

@ -29,7 +29,7 @@
#include <mapnik/geometry/centroid.hpp> #include <mapnik/geometry/centroid.hpp>
#include <mapnik/symbolizer.hpp> #include <mapnik/symbolizer.hpp>
#include <mapnik/svg/svg_path_attributes.hpp> #include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/marker.hpp> // for svg_storage_type #include <mapnik/marker.hpp> // svg_attribute_type, svg_storage_type
#include <mapnik/markers_placement.hpp> #include <mapnik/markers_placement.hpp>
#include <mapnik/attribute.hpp> #include <mapnik/attribute.hpp>
#include <mapnik/geometry/box2d.hpp> #include <mapnik/geometry/box2d.hpp>

View file

@ -41,6 +41,7 @@
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
// stl // stl
#include <deque>
#include <stdexcept> #include <stdexcept>
namespace mapnik { namespace mapnik {
@ -61,16 +62,16 @@ public:
void begin_path() void begin_path()
{ {
std::size_t idx = source_.start_new_path(); std::size_t idx = source_.start_new_path();
attributes_.add(path_attributes(cur_attr(), safe_cast<unsigned>(idx))); attributes_.emplace_back(cur_attr(), safe_cast<unsigned>(idx));
} }
void end_path() void end_path()
{ {
if(attributes_.size() == 0) if (attributes_.empty())
{ {
throw std::runtime_error("end_path : The path was not begun"); throw std::runtime_error("end_path : The path was not begun");
} }
path_attributes& attr = attributes_[attributes_.size() - 1]; path_attributes& attr = attributes_.back();
unsigned idx = attr.index; unsigned idx = attr.index;
attr = cur_attr(); attr = cur_attr();
attr.index = idx; attr.index = idx;
@ -183,17 +184,19 @@ public:
void push_attr() void push_attr()
{ {
attr_stack_.add(attr_stack_.size() ? if (attr_stack_.empty())
attr_stack_[attr_stack_.size() - 1] : attr_stack_.push_back(path_attributes());
path_attributes()); else
attr_stack_.push_back(attr_stack_.back());
} }
void pop_attr() void pop_attr()
{ {
if(attr_stack_.size() == 0) if (attr_stack_.empty())
{ {
throw std::runtime_error("pop_attr : Attribute stack is empty"); throw std::runtime_error("pop_attr : Attribute stack is empty");
} }
attr_stack_.remove_last(); attr_stack_.pop_back();
} }
// Attribute setting functions. // Attribute setting functions.
@ -226,15 +229,18 @@ public:
attr.stroke_color.opacity(a * s.opacity()); attr.stroke_color.opacity(a * s.opacity());
attr.stroke_flag = true; attr.stroke_flag = true;
} }
void dash_array(dash_array && dash) void dash_array(dash_array && dash)
{ {
path_attributes& attr = cur_attr(); path_attributes& attr = cur_attr();
attr.dash = std::move(dash); attr.dash = std::move(dash);
} }
void dash_offset(double offset) void dash_offset(double offset)
{ {
cur_attr().dash_offset = offset; cur_attr().dash_offset = offset;
} }
void even_odd(bool flag) void even_odd(bool flag)
{ {
cur_attr().even_odd_flag = flag; cur_attr().even_odd_flag = flag;
@ -264,6 +270,7 @@ public:
{ {
cur_attr().stroke_width = w; cur_attr().stroke_width = w;
} }
void fill_none() void fill_none()
{ {
cur_attr().fill_none = true; cur_attr().fill_none = true;
@ -352,11 +359,11 @@ public:
path_attributes& cur_attr() path_attributes& cur_attr()
{ {
if(attr_stack_.size() == 0) if (attr_stack_.empty())
{ {
throw std::runtime_error("cur_attr : Attribute stack is empty"); throw std::runtime_error("cur_attr : Attribute stack is empty");
} }
return attr_stack_[attr_stack_.size() - 1]; return attr_stack_.back();
} }
private: private:
@ -370,7 +377,7 @@ private:
}; };
using svg_converter_type = svg_converter<svg_path_adapter,agg::pod_bvector<mapnik::svg::path_attributes> >; using svg_converter_type = svg_converter<svg_path_adapter, std::deque<path_attributes> >;
}} }}

View file

@ -103,7 +103,7 @@ private:
}; };
template <typename VertexSource, typename AttributeSource, typename ScanlineRenderer, typename PixelFormat> template <typename VertexSource, typename AttributeSource, typename ScanlineRenderer, typename PixelFormat>
class svg_renderer_agg : util::noncopyable class renderer_agg : util::noncopyable
{ {
public: public:
using curved_type = agg::conv_curve<VertexSource>; using curved_type = agg::conv_curve<VertexSource>;
@ -122,7 +122,7 @@ public:
using vertex_source_type = VertexSource; using vertex_source_type = VertexSource;
using attribute_source_type = AttributeSource; using attribute_source_type = AttributeSource;
svg_renderer_agg(VertexSource & source, AttributeSource const& attributes) renderer_agg(VertexSource & source, AttributeSource const& attributes)
: source_(source), : source_(source),
curved_(source_), curved_(source_),
curved_dashed_(curved_), curved_dashed_(curved_),

View file

@ -416,14 +416,12 @@ struct agg_render_marker_visitor
mtx *= agg::trans_affine_scaling(common_.scale_factor_); mtx *= agg::trans_affine_scaling(common_.scale_factor_);
// render the marker at the center of the marker box // render the marker at the center of the marker box
mtx.translate(pos_.x, pos_.y); mtx.translate(pos_.x, pos_.y);
using namespace mapnik::svg; svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(marker.get_data()->source());
vertex_stl_adapter<svg_path_storage> stl_storage(marker.get_data()->source());
svg_path_adapter svg_path(stl_storage); svg_path_adapter svg_path(stl_storage);
svg_renderer_agg<svg_path_adapter, svg::renderer_agg<svg_path_adapter,
svg_attribute_type, svg_attribute_type,
renderer_type, renderer_type,
pixfmt_comp_type> svg_renderer(svg_path, pixfmt_comp_type> svg_renderer(svg_path, marker.get_data()->attributes());
marker.get_data()->attributes());
// https://github.com/mapnik/mapnik/issues/1316 // https://github.com/mapnik/mapnik/issues/1316
// https://github.com/mapnik/mapnik/issues/1866 // https://github.com/mapnik/mapnik/issues/1866

View file

@ -75,10 +75,10 @@ struct thunk_renderer<image_rgba8> : render_thunk_list_dispatch
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, buf_type>; using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, buf_type>;
using renderer_base = agg::renderer_base<pixfmt_comp_type>; using renderer_base = agg::renderer_base<pixfmt_comp_type>;
using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>; using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>;
using svg_renderer_type = svg::svg_renderer_agg<svg_path_adapter, using svg_renderer_type = svg::renderer_agg<svg_path_adapter,
svg_attribute_type, svg_attribute_type,
renderer_type, renderer_type,
pixfmt_comp_type>; pixfmt_comp_type>;
ras_ptr_->reset(); ras_ptr_->reset();
buf_type render_buffer(buf_.bytes(), buf_.width(), buf_.height(), buf_.row_size()); buf_type render_buffer(buf_.bytes(), buf_.width(), buf_.height(), buf_.row_size());
pixfmt_comp_type pixf(render_buffer); pixfmt_comp_type pixf(render_buffer);
@ -90,7 +90,8 @@ struct thunk_renderer<image_rgba8> : render_thunk_list_dispatch
agg::trans_affine offset_tr = thunk.tr_; agg::trans_affine offset_tr = thunk.tr_;
offset_tr.translate(offset_.x, offset_.y); offset_tr.translate(offset_.x, offset_.y);
render_vector_marker(svg_renderer, *ras_ptr_, renb, thunk.src_->bounding_box(), offset_tr, thunk.opacity_, thunk.snap_to_pixels_); render_vector_marker(svg_renderer, *ras_ptr_, renb, thunk.src_->bounding_box(),
offset_tr, thunk.opacity_, thunk.snap_to_pixels_);
} }
virtual void operator()(raster_marker_render_thunk const& thunk) virtual void operator()(raster_marker_render_thunk const& thunk)

View file

@ -108,7 +108,6 @@ void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
feature_impl & feature, feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
using namespace mapnik::svg;
using color_type = agg::rgba8; using color_type = agg::rgba8;
using order_type = agg::order_rgba; using order_type = agg::order_rgba;
using blender_type = agg::comp_op_adaptor_rgba_pre<color_type, order_type>; // comp blender using blender_type = agg::comp_op_adaptor_rgba_pre<color_type, order_type>; // comp blender
@ -116,11 +115,10 @@ void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, buf_type>; using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, buf_type>;
using renderer_base = agg::renderer_base<pixfmt_comp_type>; using renderer_base = agg::renderer_base<pixfmt_comp_type>;
using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>; using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>;
using svg_renderer_type = svg_renderer_agg<svg_path_adapter, using svg_renderer_type = svg::renderer_agg<svg_path_adapter,
svg_attribute_type, svg_attribute_type,
renderer_type, renderer_type,
pixfmt_comp_type>; pixfmt_comp_type>;
ras_ptr->reset(); ras_ptr->reset();
double gamma = get<value_double, keys::gamma>(sym, feature, common_.vars_); double gamma = get<value_double, keys::gamma>(sym, feature, common_.vars_);

View file

@ -31,18 +31,16 @@
namespace mapnik namespace mapnik
{ {
void render_vector_marker(cairo_context & context, svg_path_adapter & svg_path,
svg_attribute_type const& attributes,
void render_vector_marker(cairo_context & context, svg::svg_path_adapter & svg_path,
agg::pod_bvector<svg::path_attributes> const & attrs,
box2d<double> const& bbox, agg::trans_affine const& tr, box2d<double> const& bbox, agg::trans_affine const& tr,
double opacity) double opacity)
{ {
using namespace mapnik::svg;
agg::trans_affine transform; agg::trans_affine transform;
for(unsigned i = 0; i < attrs.size(); ++i) for (auto const& attr : attributes)
{ {
mapnik::svg::path_attributes const& attr = attrs[i];
if (!attr.visibility_flag) if (!attr.visibility_flag)
continue; continue;
cairo_save_restore guard(context); cairo_save_restore guard(context);

View file

@ -268,11 +268,11 @@ struct cairo_render_marker_visitor
marker_tr *= tr_; marker_tr *= tr_;
} }
marker_tr *= agg::trans_affine_scaling(common_.scale_factor_); marker_tr *= agg::trans_affine_scaling(common_.scale_factor_);
agg::pod_bvector<svg::path_attributes> const & attrs = vmarker->attributes(); auto const& attributes = vmarker->attributes();
svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(vmarker->source()); svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(vmarker->source());
svg::svg_path_adapter svg_path(stl_storage); svg::svg_path_adapter svg_path(stl_storage);
marker_tr.translate(pos_.x, pos_.y); marker_tr.translate(pos_.x, pos_.y);
render_vector_marker(context_, svg_path, attrs, bbox, marker_tr, opacity_); render_vector_marker(context_, svg_path, attributes, bbox, marker_tr, opacity_);
} }
} }

View file

@ -172,14 +172,12 @@ struct grid_render_marker_visitor
mtx *= agg::trans_affine_scaling(common_.scale_factor_); mtx *= agg::trans_affine_scaling(common_.scale_factor_);
// render the marker at the center of the marker box // render the marker at the center of the marker box
mtx.translate(pos_.x, pos_.y); mtx.translate(pos_.x, pos_.y);
using namespace mapnik::svg; svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(marker.get_data()->source());
vertex_stl_adapter<svg_path_storage> stl_storage(marker.get_data()->source());
svg_path_adapter svg_path(stl_storage); svg_path_adapter svg_path(stl_storage);
svg_renderer_agg<svg_path_adapter, svg::renderer_agg<svg_path_adapter,
agg::pod_bvector<path_attributes>, svg_attribute_type,
renderer_type, renderer_type,
pixfmt_type> svg_renderer(svg_path, pixfmt_type> svg_renderer(svg_path, marker.get_data()->attributes());
marker.get_data()->attributes());
svg_renderer.render_id(*ras_ptr_, sl, renb, feature_.id(), mtx, opacity_, bbox); svg_renderer.render_id(*ras_ptr_, sl, renb, feature_.id(), mtx, opacity_, bbox);
} }

View file

@ -72,24 +72,20 @@ struct thunk_renderer : render_thunk_list_dispatch
using buf_type = grid_rendering_buffer; using buf_type = grid_rendering_buffer;
using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using pixfmt_type = typename grid_renderer_base_type::pixfmt_type;
using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>;
using svg_renderer_type = svg::renderer_agg<svg_path_adapter,
using namespace mapnik::svg; svg_attribute_type,
using svg_renderer_type = svg_renderer_agg<svg_path_adapter, renderer_type,
svg_attribute_type, pixfmt_type>;
renderer_type,
pixfmt_type>;
buf_type render_buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); buf_type render_buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_);
ras_.reset(); ras_.reset();
pixfmt_type pixf(render_buf); pixfmt_type pixf(render_buf);
grid_renderer_base_type renb(pixf); grid_renderer_base_type renb(pixf);
renderer_type ren(renb); renderer_type ren(renb);
vertex_stl_adapter<svg_path_storage> stl_storage(thunk.src_->source()); svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(thunk.src_->source());
svg_path_adapter svg_path(stl_storage); svg_path_adapter svg_path(stl_storage);
svg_renderer_type svg_renderer(svg_path, thunk.attrs_); svg_renderer_type svg_renderer(svg_path, thunk.attrs_);
agg::trans_affine offset_tr = thunk.tr_; agg::trans_affine offset_tr = thunk.tr_;
offset_tr.translate(offset_.x, offset_.y); offset_tr.translate(offset_.x, offset_.y);
//render_vector_marker(svg_renderer, *ras_ptr_, renb, thunk.src_->bounding_box(), offset_tr, thunk.opacity_, thunk.snap_to_pixels_);
agg::scanline_bin sl; agg::scanline_bin sl;
svg_renderer.render_id(ras_, sl, renb, feature_.id(), offset_tr, thunk.opacity_, thunk.src_->bounding_box()); svg_renderer.render_id(ras_, sl, renb, feature_.id(), offset_tr, thunk.opacity_, thunk.src_->bounding_box());
pixmap_.add_feature(feature_); pixmap_.add_feature(feature_);

View file

@ -141,12 +141,10 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
using buf_type = grid_rendering_buffer; using buf_type = grid_rendering_buffer;
using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using pixfmt_type = typename grid_renderer_base_type::pixfmt_type;
using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>; using renderer_type = agg::renderer_scanline_bin_solid<grid_renderer_base_type>;
using svg_renderer_type = svg::renderer_agg<svg_path_adapter,
using namespace mapnik::svg; svg_attribute_type,
using svg_renderer_type = svg_renderer_agg<svg_path_adapter, renderer_type,
svg_attribute_type, pixfmt_type>;
renderer_type,
pixfmt_type>;
buf_type render_buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_); buf_type render_buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_);
ras_ptr->reset(); ras_ptr->reset();

View file

@ -94,7 +94,7 @@ bool push_explicit_style(svg_attribute_type const& src,
for(unsigned i = 0; i < src.size(); ++i) for(unsigned i = 0; i < src.size(); ++i)
{ {
dst.push_back(src[i]); dst.push_back(src[i]);
mapnik::svg::path_attributes & attr = dst.last(); mapnik::svg::path_attributes & attr = dst.back();
if (!attr.visibility_flag) if (!attr.visibility_flag)
continue; continue;
success = true; success = true;

View file

@ -62,13 +62,12 @@ void render_pattern<image_rgba8>(rasterizer & ras,
pixfmt pixf(buf); pixfmt pixf(buf);
renderer_base renb(pixf); renderer_base renb(pixf);
mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(marker.get_data()->source()); svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(marker.get_data()->source());
mapnik::svg::svg_path_adapter svg_path(stl_storage); svg_path_adapter svg_path(stl_storage);
mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter, svg::renderer_agg<svg_path_adapter,
agg::pod_bvector<mapnik::svg::path_attributes>, svg_attribute_type,
renderer_solid, renderer_solid,
pixfmt > svg_renderer(svg_path, pixfmt> svg_renderer(svg_path, marker.get_data()->attributes());
marker.get_data()->attributes());
svg_renderer.render(ras, sl, renb, mtx, opacity, bbox); svg_renderer.render(ras, sl, renb, mtx, opacity, bbox);
} }

View file

@ -1410,8 +1410,8 @@ void parse_linear_gradient(svg_parser & parser, rapidxml::xml_node<char> const*
parser.gradient_map_[id] = gr; parser.gradient_map_[id] = gr;
} }
svg_parser::svg_parser(svg_converter<svg_path_adapter,
agg::pod_bvector<mapnik::svg::path_attributes> > & path, bool strict) svg_parser::svg_parser(svg_converter_type & path, bool strict)
: path_(path), : path_(path),
is_defs_(false), is_defs_(false),
err_handler_(strict) {} err_handler_(strict) {}

View file

@ -84,8 +84,9 @@ struct main_marker_visitor
agg::trans_affine mtx = {}; agg::trans_affine mtx = {};
mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(marker.get_data()->source()); mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(marker.get_data()->source());
mapnik::svg::svg_path_adapter svg_path(stl_storage); mapnik::svg::svg_path_adapter svg_path(stl_storage);
mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter, mapnik::svg::renderer_agg<
agg::pod_bvector<mapnik::svg::path_attributes>, mapnik::svg_path_adapter,
mapnik::svg_attribute_type,
renderer_solid, renderer_solid,
agg::pixfmt_rgba32_pre > svg_renderer_this(svg_path, agg::pixfmt_rgba32_pre > svg_renderer_this(svg_path,
marker.get_data()->attributes()); marker.get_data()->attributes());