From f99c0e5a6f21e5330cb0d86e4fc3f826fa1a9244 Mon Sep 17 00:00:00 2001 From: Mickey Rose Date: Wed, 27 Jan 2016 01:55:50 +0100 Subject: [PATCH] refactor render_markers_symbolizer --- include/mapnik/marker_helpers.hpp | 152 ++++++++++-------- include/mapnik/markers_placements/point.hpp | 21 +-- .../process_markers_symbolizer.hpp | 10 +- src/agg/process_markers_symbolizer.cpp | 122 +++++--------- src/cairo/process_markers_symbolizer.cpp | 82 +++------- src/grid/process_markers_symbolizer.cpp | 136 ++++++---------- .../render_thunk_extractor.cpp | 76 +++------ 7 files changed, 226 insertions(+), 373 deletions(-) diff --git a/include/mapnik/marker_helpers.hpp b/include/mapnik/marker_helpers.hpp index 375d16fac..8615bb28e 100644 --- a/include/mapnik/marker_helpers.hpp +++ b/include/mapnik/marker_helpers.hpp @@ -48,64 +48,106 @@ struct clip_poly_tag; using svg_attribute_type = agg::pod_bvector; +struct markers_dispatch_params +{ + // placement + markers_placement_params placement_params; + marker_placement_enum placement_method; + value_bool ignore_placement; + // rendering + bool snap_to_pixels; + double scale_factor; + value_double opacity; + + markers_dispatch_params(box2d const& size, + agg::trans_affine const& tr, + symbolizer_base const& sym, + feature_impl const& feature, + attributes const& vars, + double scale = 1.0, + bool snap = false) + : placement_params{ + .size = size, + .tr = tr, + .spacing = get(sym, feature, vars), + .max_error = get(sym, feature, vars), + .allow_overlap = get(sym, feature, vars), + .avoid_edges = get(sym, feature, vars), + .direction = get(sym, feature, vars)} + , placement_method(get(sym, feature, vars)) + , ignore_placement(get(sym, feature, vars)) + , snap_to_pixels(snap) + , scale_factor(scale) + , opacity(get(sym, feature, vars)) + { + placement_params.spacing *= scale; + } +}; + +struct markers_renderer_context : util::noncopyable +{ + virtual void render_marker(image_rgba8 const& src, + markers_dispatch_params const& params, + agg::trans_affine const& marker_tr) = 0; + + virtual void render_marker(svg_path_ptr const& src, + svg_path_adapter & path, + svg_attribute_type const& attrs, + markers_dispatch_params const& params, + agg::trans_affine const& marker_tr) = 0; +}; + template struct vector_markers_dispatch : util::noncopyable { vector_markers_dispatch(svg_path_ptr const& src, + svg_path_adapter & path, + svg_attribute_type const& attrs, agg::trans_affine const& marker_trans, symbolizer_base const& sym, Detector & detector, double scale_factor, feature_impl const& feature, - attributes const& vars) - : src_(src), - marker_trans_(marker_trans), - sym_(sym), - detector_(detector), - feature_(feature), - vars_(vars), - scale_factor_(scale_factor) + attributes const& vars, + bool snap_to_pixels, + markers_renderer_context & renderer_context) + : params_(src->bounding_box(), recenter(src) * marker_trans, + sym, feature, vars, scale_factor, snap_to_pixels) + , renderer_context_(renderer_context) + , src_(src) + , path_(path) + , attrs_(attrs) + , detector_(detector) {} - virtual ~vector_markers_dispatch() {} - template void add_path(T & path) { - marker_placement_enum placement_method = get(sym_, feature_, vars_); - value_bool ignore_placement = get(sym_, feature_, vars_); - value_bool allow_overlap = get(sym_, feature_, vars_); - value_bool avoid_edges = get(sym_, feature_, vars_); - value_double opacity = get(sym_, feature_, vars_); - value_double spacing = get(sym_, feature_, vars_); - value_double max_error = get(sym_, feature_, vars_); - coord2d center = src_->bounding_box().center(); - agg::trans_affine_translation recenter(-center.x, -center.y); - agg::trans_affine tr = recenter * marker_trans_; - direction_enum direction = get(sym_, feature_, vars_); - markers_placement_params params { src_->bounding_box(), tr, spacing * scale_factor_, max_error, allow_overlap, avoid_edges, direction }; markers_placement_finder placement_finder( - placement_method, path, detector_, params); + params_.placement_method, path, detector_, params_.placement_params); double x, y, angle = .0; - while (placement_finder.get_point(x, y, angle, ignore_placement)) + while (placement_finder.get_point(x, y, angle, params_.ignore_placement)) { - agg::trans_affine matrix = tr; + agg::trans_affine matrix = params_.placement_params.tr; matrix.rotate(angle); matrix.translate(x, y); - render_marker(matrix, opacity); + renderer_context_.render_marker(src_, path_, attrs_, params_, matrix); } } - virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0; - protected: + static agg::trans_affine recenter(svg_path_ptr const& src) + { + coord2d center = src->bounding_box().center(); + return agg::trans_affine_translation(-center.x, -center.y); + } + + markers_dispatch_params params_; + markers_renderer_context & renderer_context_; svg_path_ptr const& src_; - agg::trans_affine const& marker_trans_; - symbolizer_base const& sym_; + svg_path_adapter & path_; + svg_attribute_type const& attrs_; Detector & detector_; - feature_impl const& feature_; - attributes const& vars_; - double scale_factor_; }; template @@ -117,53 +159,35 @@ struct raster_markers_dispatch : util::noncopyable Detector & detector, double scale_factor, feature_impl const& feature, - attributes const& vars) - : src_(src), - marker_trans_(marker_trans), - sym_(sym), - detector_(detector), - feature_(feature), - vars_(vars), - scale_factor_(scale_factor) + attributes const& vars, + markers_renderer_context & renderer_context) + : params_(box2d(0, 0, src.width(), src.height()), + marker_trans, sym, feature, vars, scale_factor) + , renderer_context_(renderer_context) + , src_(src) + , detector_(detector) {} - virtual ~raster_markers_dispatch() {} - template void add_path(T & path) { - marker_placement_enum placement_method = get(sym_, feature_, vars_); - value_bool allow_overlap = get(sym_, feature_, vars_); - value_bool avoid_edges = get(sym_, feature_, vars_); - value_double opacity = get(sym_, feature_, vars_); - value_bool ignore_placement = get(sym_, feature_, vars_); - value_double spacing = get(sym_, feature_, vars_); - value_double max_error = get(sym_, feature_, vars_); - box2d bbox(0,0, src_.width(),src_.height()); - direction_enum direction = get(sym_, feature_, vars_); - markers_placement_params params { bbox, marker_trans_, spacing * scale_factor_, max_error, allow_overlap, avoid_edges, direction }; markers_placement_finder placement_finder( - placement_method, path, detector_, params); + params_.placement_method, path, detector_, params_.placement_params); double x, y, angle = .0; - while (placement_finder.get_point(x, y, angle, ignore_placement)) + while (placement_finder.get_point(x, y, angle, params_.ignore_placement)) { - agg::trans_affine matrix = marker_trans_; + agg::trans_affine matrix = params_.placement_params.tr; matrix.rotate(angle); matrix.translate(x, y); - render_marker(matrix, opacity); + renderer_context_.render_marker(src_, params_, matrix); } } - virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0; - protected: + markers_dispatch_params params_; + markers_renderer_context & renderer_context_; image_rgba8 const& src_; - agg::trans_affine const& marker_trans_; - symbolizer_base const& sym_; Detector & detector_; - feature_impl const& feature_; - attributes const& vars_; - double scale_factor_; }; void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, attributes const& vars, diff --git a/include/mapnik/markers_placements/point.hpp b/include/mapnik/markers_placements/point.hpp index 65b95ce79..13f174d9b 100644 --- a/include/mapnik/markers_placements/point.hpp +++ b/include/mapnik/markers_placements/point.hpp @@ -40,8 +40,8 @@ namespace mapnik { struct markers_placement_params { - box2d const& size; - agg::trans_affine const& tr; + box2d size; + agg::trans_affine tr; double spacing; double max_error; bool allow_overlap; @@ -132,23 +132,8 @@ protected: // Rotates the size_ box and translates the position. box2d perform_transform(double angle, double dx, double dy) { - double x1 = params_.size.minx(); - double x2 = params_.size.maxx(); - double y1 = params_.size.miny(); - double y2 = params_.size.maxy(); agg::trans_affine tr = params_.tr * agg::trans_affine_rotation(angle).translate(dx, dy); - double xA = x1, yA = y1, - xB = x2, yB = y1, - xC = x2, yC = y2, - xD = x1, yD = y2; - tr.transform(&xA, &yA); - tr.transform(&xB, &yB); - tr.transform(&xC, &yC); - tr.transform(&xD, &yD); - box2d result(xA, yA, xC, yC); - result.expand_to_include(xB, yB); - result.expand_to_include(xD, yD); - return result; + return box2d(params_.size, tr); } bool set_direction(double & angle) diff --git a/include/mapnik/renderer_common/process_markers_symbolizer.hpp b/include/mapnik/renderer_common/process_markers_symbolizer.hpp index 66a002dab..53d4c4123 100644 --- a/include/mapnik/renderer_common/process_markers_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_markers_symbolizer.hpp @@ -37,7 +37,6 @@ struct render_marker_symbolizer_visitor { using vector_dispatch_type = VD; using raster_dispatch_type = RD; - using buffer_type = typename std::tuple_element<0,ContextType>::type; using vertex_converter_type = vertex_converter +template void render_markers_symbolizer(markers_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans, RendererType const& common, box2d const& clip_box, - ContextType const& renderer_context) + markers_renderer_context & renderer_context) { + using Detector = decltype(*common.detector_); + using VD = vector_markers_dispatch; + using RD = raster_markers_dispatch; + using ContextType = markers_renderer_context & ; + using namespace mapnik::svg; std::string filename = get(sym, keys::file, feature, common.vars_, "shape://ellipse"); if (!filename.empty()) diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index 767d0951a..1c408352d 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -60,106 +60,58 @@ namespace mapnik { namespace detail { -template -struct vector_markers_rasterizer_dispatch : public vector_markers_dispatch +template +struct agg_markers_renderer_context : markers_renderer_context { using renderer_base = typename SvgRenderer::renderer_base; using vertex_source_type = typename SvgRenderer::vertex_source_type; using attribute_source_type = typename SvgRenderer::attribute_source_type; using pixfmt_type = typename renderer_base::pixfmt_type; - using BufferType = typename std::tuple_element<0,RendererContext>::type; - using RasterizerType = typename std::tuple_element<1,RendererContext>::type; - - vector_markers_rasterizer_dispatch(svg_path_ptr const& src, - vertex_source_type & path, - svg_attribute_type const& attrs, - agg::trans_affine const& marker_trans, - symbolizer_base const& sym, - Detector & detector, - double scale_factor, - feature_impl & feature, - attributes const& vars, - bool snap_to_pixels, - RendererContext const& renderer_context) -: vector_markers_dispatch(src, marker_trans, sym, detector, scale_factor, feature, vars), - buf_(std::get<0>(renderer_context)), + agg_markers_renderer_context(symbolizer_base const& sym, + feature_impl const& feature, + attributes const& vars, + BufferType & buf, + RasterizerType & ras) + : buf_(buf), pixf_(buf_), renb_(pixf_), - svg_renderer_(path, attrs), - ras_(std::get<1>(renderer_context)), - snap_to_pixels_(snap_to_pixels) + ras_(ras) { - pixf_.comp_op(static_cast(get(sym, feature, vars))); + auto comp_op = get(sym, feature, vars); + pixf_.comp_op(static_cast(comp_op)); } - ~vector_markers_rasterizer_dispatch() {} - - void render_marker(agg::trans_affine const& marker_tr, double opacity) + virtual void render_marker(svg_path_ptr const& src, + svg_path_adapter & path, + svg_attribute_type const& attrs, + markers_dispatch_params const& params, + agg::trans_affine const& marker_tr) { - render_vector_marker(svg_renderer_, ras_, renb_, this->src_->bounding_box(), - marker_tr, opacity, snap_to_pixels_); + SvgRenderer svg_renderer(path, attrs); + render_vector_marker(svg_renderer, ras_, renb_, src->bounding_box(), + marker_tr, params.opacity, params.snap_to_pixels); + } + + + virtual void render_marker(image_rgba8 const& src, + markers_dispatch_params const& params, + agg::trans_affine const& marker_tr) + { + // In the long term this should be a visitor pattern based on the type of + // render src provided that converts the destination pixel type required. + render_raster_marker(renb_, ras_, src, marker_tr, params.opacity, + params.scale_factor, params.snap_to_pixels); } private: BufferType & buf_; pixfmt_type pixf_; renderer_base renb_; - SvgRenderer svg_renderer_; RasterizerType & ras_; - bool snap_to_pixels_; }; -template -struct raster_markers_rasterizer_dispatch : public raster_markers_dispatch -{ - using BufferType = typename std::remove_reference::type>::type; - using RasterizerType = typename std::tuple_element<1,RendererContext>::type; - - using color_type = agg::rgba8; - using order_type = agg::order_rgba; - using pixel_type = agg::pixel32_type; - using blender_type = agg::comp_op_adaptor_rgba_pre; // comp blender - using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba; - using renderer_base = agg::renderer_base; - - raster_markers_rasterizer_dispatch(image_rgba8 const& src, - agg::trans_affine const& marker_trans, - symbolizer_base const& sym, - Detector & detector, - double scale_factor, - feature_impl & feature, - attributes const& vars, - RendererContext const& renderer_context, - bool snap_to_pixels = false) - : raster_markers_dispatch(src, marker_trans, sym, detector, scale_factor, feature, vars), - buf_(std::get<0>(renderer_context)), - pixf_(buf_), - renb_(pixf_), - ras_(std::get<1>(renderer_context)), - snap_to_pixels_(snap_to_pixels) - { - pixf_.comp_op(static_cast(get(sym, feature, vars))); - } - - ~raster_markers_rasterizer_dispatch() {} - - void render_marker(agg::trans_affine const& marker_tr, double opacity) - { - // In the long term this should be a visitor pattern based on the type of render this->src_ provided that converts - // the destination pixel type required. - render_raster_marker(renb_, ras_, this->src_, marker_tr, opacity, this->scale_factor_, snap_to_pixels_); - } - -private: - BufferType & buf_; - pixfmt_comp_type pixf_; - renderer_base renb_; - RasterizerType & ras_; - bool snap_to_pixels_; -}; - -} +} // namespace detail template void agg_renderer::process(markers_symbolizer const& sym, @@ -194,16 +146,16 @@ void agg_renderer::process(markers_symbolizer const& sym, buf_type render_buffer(current_buffer_->bytes(), current_buffer_->width(), current_buffer_->height(), current_buffer_->row_size()); box2d clip_box = clipping_extent(common_); - auto renderer_context = std::tie(render_buffer,*ras_ptr,pixmap_); - using markers_context_type = decltype(renderer_context); - using vector_dispatch_type = detail::vector_markers_rasterizer_dispatch; - using raster_dispatch_type = detail::raster_markers_rasterizer_dispatch; + using context_type = detail::agg_markers_renderer_context; + context_type renderer_context(sym, feature, common_.vars_, render_buffer, *ras_ptr); - render_markers_symbolizer( + render_markers_symbolizer( sym, feature, prj_trans, common_, clip_box, renderer_context); } template void agg_renderer::process(markers_symbolizer const&, mapnik::feature_impl &, proj_transform const&); -} +} // namespace mapnik diff --git a/src/cairo/process_markers_symbolizer.cpp b/src/cairo/process_markers_symbolizer.cpp index faffd3d6a..0fabc22ef 100644 --- a/src/cairo/process_markers_symbolizer.cpp +++ b/src/cairo/process_markers_symbolizer.cpp @@ -42,73 +42,40 @@ namespace mapnik { -class feature_impl; -class proj_transform; - namespace detail { -template -struct vector_markers_dispatch_cairo : public vector_markers_dispatch +struct cairo_markers_renderer_context : markers_renderer_context { - vector_markers_dispatch_cairo(svg_path_ptr const& src, - svg::svg_path_adapter & path, - svg_attribute_type const& attrs, - agg::trans_affine const& marker_trans, - markers_symbolizer const& sym, - Detector & detector, - double scale_factor, - feature_impl & feature, - mapnik::attributes const& vars, - bool /* snap_to_pixels */, // only used in agg renderer currently - RendererContext const& renderer_context) - : vector_markers_dispatch(src, marker_trans, sym, detector, scale_factor, feature, vars), - path_(path), - attr_(attrs), - ctx_(std::get<0>(renderer_context)) + explicit cairo_markers_renderer_context(cairo_context & ctx) + : ctx_(ctx) {} - void render_marker(agg::trans_affine const& marker_tr, double opacity) + virtual void render_marker(svg_path_ptr const& src, + svg_path_adapter & path, + svg_attribute_type const& attrs, + markers_dispatch_params const& params, + agg::trans_affine const& marker_tr) { render_vector_marker(ctx_, - path_, - attr_, - this->src_->bounding_box(), + path, + attrs, + src->bounding_box(), marker_tr, - opacity); + params.opacity); } -private: - svg::svg_path_adapter & path_; - svg_attribute_type const& attr_; - cairo_context & ctx_; -}; - -template -struct raster_markers_dispatch_cairo : public raster_markers_dispatch -{ - raster_markers_dispatch_cairo(image_rgba8 const& src, - agg::trans_affine const& marker_trans, - markers_symbolizer const& sym, - Detector & detector, - double scale_factor, - feature_impl & feature, - mapnik::attributes const& vars, - RendererContext const& renderer_context) - : raster_markers_dispatch(src, marker_trans, sym, detector, scale_factor, feature, vars), - ctx_(std::get<0>(renderer_context)) {} - - ~raster_markers_dispatch_cairo() {} - - void render_marker(agg::trans_affine const& marker_tr, double opacity) + virtual void render_marker(image_rgba8 const& src, + markers_dispatch_params const& params, + agg::trans_affine const& marker_tr) { - ctx_.add_image(marker_tr, this->src_, opacity); + ctx_.add_image(marker_tr, src, params.opacity); } private: cairo_context & ctx_; }; -} +} // namespace detail template void cairo_renderer::process(markers_symbolizer const& sym, @@ -120,17 +87,10 @@ void cairo_renderer::process(markers_symbolizer const& sym, context_.set_operator(comp_op); box2d clip_box = common_.query_extent_; - auto renderer_context = std::tie(context_); + using context_type = detail::cairo_markers_renderer_context; + context_type renderer_context(context_); - using RendererContextType = decltype(renderer_context); - using vector_dispatch_type = detail::vector_markers_dispatch_cairo; - - using raster_dispatch_type = detail::raster_markers_dispatch_cairo; - - - render_markers_symbolizer( + render_markers_symbolizer( sym, feature, prj_trans, common_, clip_box, renderer_context); } @@ -139,6 +99,6 @@ template void cairo_renderer::process(markers_symbolizer const&, mapnik::feature_impl &, proj_transform const&); -} +} // namespace mapnik #endif // HAVE_CAIRO diff --git a/src/grid/process_markers_symbolizer.cpp b/src/grid/process_markers_symbolizer.cpp index 52d3f5577..6d644ffd6 100644 --- a/src/grid/process_markers_symbolizer.cpp +++ b/src/grid/process_markers_symbolizer.cpp @@ -81,109 +81,72 @@ namespace mapnik { namespace detail { -template -struct vector_markers_rasterizer_dispatch : public vector_markers_dispatch +template +struct grid_markers_renderer_context : markers_renderer_context { using renderer_base = typename SvgRenderer::renderer_base; using vertex_source_type = typename SvgRenderer::vertex_source_type; using attribute_source_type = typename SvgRenderer::attribute_source_type; using pixfmt_type = typename renderer_base::pixfmt_type; - using BufferType = typename std::tuple_element<0,RendererContext>::type; - using RasterizerType = typename std::tuple_element<1,RendererContext>::type; - using PixMapType = typename std::tuple_element<2,RendererContext>::type; - - vector_markers_rasterizer_dispatch(svg_path_ptr const& src, - vertex_source_type & path, - svg_attribute_type const& attrs, - agg::trans_affine const& marker_trans, - markers_symbolizer const& sym, - Detector & detector, - double scale_factor, - mapnik::feature_impl & feature, - attributes const& vars, - bool snap_to_pixels, - RendererContext const& renderer_context) - : vector_markers_dispatch(src, marker_trans, sym, detector, scale_factor, feature, vars), - buf_(std::get<0>(renderer_context)), + grid_markers_renderer_context(feature_impl const& feature, + BufferType & buf, + RasterizerType & ras, + PixMapType & pixmap) + : feature_(feature), + buf_(buf), pixf_(buf_), renb_(pixf_), - svg_renderer_(path, attrs), - ras_(std::get<1>(renderer_context)), - pixmap_(std::get<2>(renderer_context)), + ras_(ras), + pixmap_(pixmap), placed_(false) {} - void render_marker(agg::trans_affine const& marker_tr, double opacity) + virtual void render_marker(svg_path_ptr const& src, + svg_path_adapter & path, + svg_attribute_type const& attrs, + markers_dispatch_params const& params, + agg::trans_affine const& marker_tr) { + SvgRenderer svg_renderer_(path, attrs); agg::scanline_bin sl_; - svg_renderer_.render_id(ras_, sl_, renb_, this->feature_.id(), marker_tr, opacity, this->src_->bounding_box()); + svg_renderer_.render_id(ras_, sl_, renb_, feature_.id(), marker_tr, + params.opacity, src->bounding_box()); + place_feature(); + } + + virtual void render_marker(image_rgba8 const& src, + markers_dispatch_params const& params, + agg::trans_affine const& marker_tr) + { + // In the long term this should be a visitor pattern based on the type of + // render src provided that converts the destination pixel type required. + render_raster_marker(ScanlineRenderer(renb_), ras_, src, feature_, + marker_tr, params.opacity); + place_feature(); + } + + void place_feature() + { if (!placed_) { - pixmap_.add_feature(this->feature_); + pixmap_.add_feature(feature_); placed_ = true; } } private: + feature_impl const& feature_; BufferType & buf_; pixfmt_type pixf_; renderer_base renb_; - SvgRenderer svg_renderer_; RasterizerType & ras_; PixMapType & pixmap_; bool placed_; }; -template -struct raster_markers_rasterizer_dispatch : public raster_markers_dispatch -{ - using pixfmt_type = typename RendererBase::pixfmt_type; - using color_type = typename RendererBase::pixfmt_type::color_type; - - using BufferType = typename std::tuple_element<0,RendererContext>::type; - using RasterizerType = typename std::tuple_element<1,RendererContext>::type; - using PixMapType = typename std::tuple_element<2,RendererContext>::type; - - raster_markers_rasterizer_dispatch(image_rgba8 const& src, - agg::trans_affine const& marker_trans, - markers_symbolizer const& sym, - Detector & detector, - double scale_factor, - mapnik::feature_impl & feature, - attributes const& vars, - RendererContext const& renderer_context) - : raster_markers_dispatch(src, marker_trans, sym, detector, scale_factor, feature, vars), - buf_(std::get<0>(renderer_context)), - pixf_(buf_), - renb_(pixf_), - ras_(std::get<1>(renderer_context)), - pixmap_(std::get<2>(renderer_context)), - placed_(false) - {} - - void render_marker(agg::trans_affine const& marker_tr, double opacity) - { - // In the long term this should be a visitor pattern based on the type of render this->src_ provided that converts - // the destination pixel type required. - render_raster_marker(RendererType(renb_), ras_, this->src_, this->feature_, marker_tr, opacity); - if (!placed_) - { - pixmap_.add_feature(this->feature_); - placed_ = true; - } - } - -private: - BufferType & buf_; - pixfmt_type pixf_; - RendererBase renb_; - RasterizerType & ras_; - PixMapType & pixmap_; - bool placed_; -}; - -} +} // namespace detail template void grid_renderer::process(markers_symbolizer const& sym, @@ -193,7 +156,6 @@ void grid_renderer::process(markers_symbolizer const& sym, using buf_type = grid_rendering_buffer; using pixfmt_type = typename grid_renderer_base_type::pixfmt_type; using renderer_type = agg::renderer_scanline_bin_solid; - using detector_type = label_collision_detector4; using namespace mapnik::svg; using svg_attribute_type = agg::pod_bvector; @@ -206,22 +168,20 @@ void grid_renderer::process(markers_symbolizer const& sym, ras_ptr->reset(); box2d clip_box = common_.query_extent_; - auto renderer_context = std::tie(render_buf,*ras_ptr,pixmap_); - using grid_context_type = decltype(renderer_context); - using vector_dispatch_type = detail::vector_markers_rasterizer_dispatch; - using raster_dispatch_type = detail::raster_markers_rasterizer_dispatch; - render_markers_symbolizer( - sym, feature, prj_trans, common_, clip_box,renderer_context); + using context_type = detail::grid_markers_renderer_context; + context_type renderer_context(feature, render_buf, *ras_ptr, pixmap_); + + render_markers_symbolizer( + sym, feature, prj_trans, common_, clip_box, renderer_context); } template void grid_renderer::process(markers_symbolizer const&, mapnik::feature_impl &, proj_transform const&); -} +} // namespace mapnik #endif diff --git a/src/renderer_common/render_thunk_extractor.cpp b/src/renderer_common/render_thunk_extractor.cpp index 58346694a..a760409f3 100644 --- a/src/renderer_common/render_thunk_extractor.cpp +++ b/src/renderer_common/render_thunk_extractor.cpp @@ -38,68 +38,38 @@ virtual_renderer_common::virtual_renderer_common(renderer_common const& other) namespace detail { -template -struct vector_marker_thunk_dispatch : public vector_markers_dispatch +struct thunk_markers_renderer_context : markers_renderer_context { - vector_marker_thunk_dispatch(svg_path_ptr const& src, - svg_path_adapter & path, - svg_attribute_type const& attrs, - agg::trans_affine const& marker_trans, - symbolizer_base const& sym, - Detector & detector, - double scale_factor, - feature_impl & feature, - attributes const& vars, - bool snap_to_pixels, - RendererContext const& renderer_context) - : vector_markers_dispatch(src, marker_trans, sym, detector, scale_factor, feature, vars), - attrs_(attrs), comp_op_(get(sym, feature, vars)), - snap_to_pixels_(snap_to_pixels), thunks_(std::get<0>(renderer_context)) + thunk_markers_renderer_context(symbolizer_base const& sym, + feature_impl const& feature, + attributes const& vars, + render_thunk_list & thunks) + : comp_op_(get(sym, feature, vars)) + , thunks_(thunks) {} - ~vector_marker_thunk_dispatch() {} - - void render_marker(agg::trans_affine const& marker_tr, double opacity) + virtual void render_marker(svg_path_ptr const& src, + svg_path_adapter & path, + svg_attribute_type const& attrs, + markers_dispatch_params const& params, + agg::trans_affine const& marker_tr) { - vector_marker_render_thunk thunk(this->src_, this->attrs_, marker_tr, opacity, comp_op_, snap_to_pixels_); + vector_marker_render_thunk thunk(src, attrs, marker_tr, params.opacity, + comp_op_, params.snap_to_pixels); thunks_.push_back(std::make_unique(std::move(thunk))); } -private: - svg_attribute_type const& attrs_; - composite_mode_e comp_op_; - bool snap_to_pixels_; - render_thunk_list & thunks_; -}; - -template -struct raster_marker_thunk_dispatch : public raster_markers_dispatch -{ - raster_marker_thunk_dispatch(image_rgba8 const& src, - agg::trans_affine const& marker_trans, - symbolizer_base const& sym, - Detector & detector, - double scale_factor, - feature_impl & feature, - attributes const& vars, - RendererContext const& renderer_context, - bool snap_to_pixels = false) - : raster_markers_dispatch(src, marker_trans, sym, detector, scale_factor, feature, vars), - comp_op_(get(sym, feature, vars)), - snap_to_pixels_(snap_to_pixels), thunks_(std::get<0>(renderer_context)) - {} - - ~raster_marker_thunk_dispatch() {} - - void render_marker(agg::trans_affine const& marker_tr, double opacity) + virtual void render_marker(image_rgba8 const& src, + markers_dispatch_params const& params, + agg::trans_affine const& marker_tr) { - raster_marker_render_thunk thunk(this->src_, marker_tr, opacity, comp_op_, snap_to_pixels_); + raster_marker_render_thunk thunk(src, marker_tr, params.opacity, + comp_op_, params.snap_to_pixels); thunks_.push_back(std::make_unique(std::move(thunk))); } private: composite_mode_e comp_op_; - bool snap_to_pixels_; render_thunk_list & thunks_; }; @@ -118,12 +88,10 @@ render_thunk_extractor::render_thunk_extractor(box2d & box, void render_thunk_extractor::operator()(markers_symbolizer const& sym) const { - auto renderer_context = std::tie(thunks_); - using thunk_context_type = decltype(renderer_context); - using vector_dispatch_type = detail::vector_marker_thunk_dispatch; - using raster_dispatch_type = detail::raster_marker_thunk_dispatch; + using context_type = detail::thunk_markers_renderer_context; + context_type renderer_context(sym, feature_, vars_, thunks_); - render_markers_symbolizer( + render_markers_symbolizer( sym, feature_, prj_trans_, common_, clipping_extent_, renderer_context); update_box();