From 7761d32ec5989fc0bf7c60148904fb963461cb0f Mon Sep 17 00:00:00 2001 From: Mickey Rose Date: Fri, 22 Jan 2016 14:13:25 +0100 Subject: [PATCH] split common group symbolizer stuff --- Makefile | 2 +- include/mapnik/marker.hpp | 6 +- .../process_group_symbolizer.hpp | 168 +----------------- .../mapnik/renderer_common/render_thunk.hpp | 115 ++++++++++++ .../render_thunk_extractor.hpp | 109 ++++++++++++ src/build.py | 2 +- ...bolizer.cpp => render_thunk_extractor.cpp} | 101 ++++------- 7 files changed, 261 insertions(+), 242 deletions(-) create mode 100644 include/mapnik/renderer_common/render_thunk.hpp create mode 100644 include/mapnik/renderer_common/render_thunk_extractor.hpp rename src/renderer_common/{process_group_symbolizer.cpp => render_thunk_extractor.cpp} (67%) diff --git a/Makefile b/Makefile index 713fc6102..737438066 100755 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ src/json/libmapnik-json.a: # we first build memory intensive files with -j1 $(PYTHON) scons/scons.py -j1 \ --config=cache --implicit-cache --max-drift=1 \ - src/renderer_common/process_group_symbolizer.os \ + src/renderer_common/render_thunk_extractor.os \ src/json/libmapnik-json.a \ src/wkt/libmapnik-wkt.a \ src/css_color_grammar.os \ diff --git a/include/mapnik/marker.hpp b/include/mapnik/marker.hpp index 66e56b2ae..bde8d65a2 100644 --- a/include/mapnik/marker.hpp +++ b/include/mapnik/marker.hpp @@ -41,8 +41,10 @@ namespace mapnik struct image_any; namespace svg { struct path_attributes; } -using attr_storage = agg::pod_bvector; -using svg_storage_type = mapnik::svg::svg_storage; +using svg::svg_path_adapter; + +using svg_attribute_type = agg::pod_bvector; +using svg_storage_type = svg::svg_storage; using svg_path_ptr = std::shared_ptr; using image_ptr = std::shared_ptr; diff --git a/include/mapnik/renderer_common/process_group_symbolizer.hpp b/include/mapnik/renderer_common/process_group_symbolizer.hpp index edec30830..e8da8d5c6 100644 --- a/include/mapnik/renderer_common/process_group_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_group_symbolizer.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,176 +37,9 @@ #include #include #include -#include -#include -#include -#include -#include - -// agg -#include namespace mapnik { -class text_symbolizer_helper; - -using svg::svg_path_adapter; -using svg_attribute_type = agg::pod_bvector; - -struct virtual_renderer_common : private util::noncopyable -{ - virtual_renderer_common(renderer_common & common) : - width_(common.width_), - height_(common.height_), - scale_factor_(common.scale_factor_), - vars_(common.vars_), - shared_font_library_(common.shared_font_library_), - font_library_(*shared_font_library_), - font_manager_(common.font_manager_), - query_extent_(common.query_extent_), - t_(common.t_), - detector_(std::make_shared(common.detector_->extent())) {} - - unsigned & width_; - unsigned & height_; - double & scale_factor_; - attributes & vars_; - // TODO: dirty hack for cairo renderer, figure out how to remove this - std::shared_ptr & shared_font_library_; - font_library & font_library_; - face_manager_freetype & font_manager_; - box2d & query_extent_; - view_transform & t_; - std::shared_ptr detector_; -}; - - -// General: - -// The approach here is to run the normal symbolizers, but in -// a 'virtual' blank environment where the changes that they -// make are recorded (the detector, the render_* calls). -// -// The recorded boxes are then used to lay out the items and -// the offsets from old to new positions can be used to perform -// the actual rendering calls. - -// This should allow us to re-use as much as possible of the -// existing symbolizer layout and rendering code while still -// being able to interpose our own decisions about whether -// a collision has occurred or not. - -// Thunk for rendering a particular instance of a point - this -// stores all the arguments necessary to re-render this point -// symbolizer at a later time. - -struct vector_marker_render_thunk : util::noncopyable -{ - svg_path_ptr src_; - svg_attribute_type attrs_; - agg::trans_affine tr_; - double opacity_; - composite_mode_e comp_op_; - bool snap_to_pixels_; - - vector_marker_render_thunk(svg_path_ptr const& src, - svg_attribute_type const& attrs, - agg::trans_affine const& marker_trans, - double opacity, - composite_mode_e comp_op, - bool snap_to_pixels); - - vector_marker_render_thunk(vector_marker_render_thunk && rhs); -}; - -struct raster_marker_render_thunk : util::noncopyable -{ - image_rgba8 const& src_; - agg::trans_affine tr_; - double opacity_; - composite_mode_e comp_op_; - bool snap_to_pixels_; - - raster_marker_render_thunk(image_rgba8 const& src, - agg::trans_affine const& marker_trans, - double opacity, - composite_mode_e comp_op, - bool snap_to_pixels); - - raster_marker_render_thunk(raster_marker_render_thunk && rhs); -}; - -using helper_ptr = std::unique_ptr; - -struct text_render_thunk : util::noncopyable -{ - // helper is stored here in order - // to keep in scope the text rendering structures - helper_ptr helper_; - placements_list const& placements_; - double opacity_; - composite_mode_e comp_op_; - halo_rasterizer_enum halo_rasterizer_; - - text_render_thunk(helper_ptr && helper, - double opacity, composite_mode_e comp_op, - halo_rasterizer_enum halo_rasterizer); - - text_render_thunk(text_render_thunk && rhs); - -}; - -// Variant type for render thunks to allow us to re-render them -// via a static visitor later. - -using render_thunk = util::variant; -using render_thunk_ptr = std::unique_ptr; -using render_thunk_list = std::list; - -// Base class for extracting the bounding boxes associated with placing -// a symbolizer at a fake, virtual point - not real geometry. -// -// The bounding boxes can be used for layout, and the thunks are -// used to re-render at locations according to the group layout. - -struct render_thunk_extractor -{ - render_thunk_extractor(box2d & box, - render_thunk_list & thunks, - feature_impl & feature, - attributes const& vars, - proj_transform const& prj_trans, - virtual_renderer_common & common, - box2d const& clipping_extent); - - void operator()(markers_symbolizer const& sym) const; - - void operator()(text_symbolizer const& sym) const; - - void operator()(shield_symbolizer const& sym) const; - - template - void operator()(T const& ) const - { - // TODO: warning if unimplemented? - } - -private: - void extract_text_thunk(helper_ptr && helper, text_symbolizer const& sym) const; - - box2d & box_; - render_thunk_list & thunks_; - feature_impl & feature_; - attributes const& vars_; - proj_transform const& prj_trans_; - virtual_renderer_common & common_; - box2d clipping_extent_; - - void update_box() const; -}; - template void render_offset_placements(placements_list const& placements, pixel_position const& offset, diff --git a/include/mapnik/renderer_common/render_thunk.hpp b/include/mapnik/renderer_common/render_thunk.hpp new file mode 100644 index 000000000..2a957d260 --- /dev/null +++ b/include/mapnik/renderer_common/render_thunk.hpp @@ -0,0 +1,115 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_RENDERER_COMMON_RENDER_THUNK_HPP +#define MAPNIK_RENDERER_COMMON_RENDER_THUNK_HPP + +// mapnik +#include // composite_mode_e +#include // svg_attribute_type, svg_path_ptr +#include // halo_rasterizer_enum +#include +#include +#include +#include + +// agg +#include + +namespace mapnik { + +// Thunk for rendering a particular instance of a point - this +// stores all the arguments necessary to re-render this point +// symbolizer at a later time. + +struct vector_marker_render_thunk : util::movable +{ + svg_path_ptr src_; + svg_attribute_type attrs_; + agg::trans_affine tr_; + double opacity_; + composite_mode_e comp_op_; + bool snap_to_pixels_; + + vector_marker_render_thunk(svg_path_ptr const& src, + svg_attribute_type const& attrs, + agg::trans_affine const& marker_trans, + double opacity, + composite_mode_e comp_op, + bool snap_to_pixels) + : src_(src), attrs_(attrs), tr_(marker_trans), opacity_(opacity), + comp_op_(comp_op), snap_to_pixels_(snap_to_pixels) + {} +}; + +struct raster_marker_render_thunk : util::movable +{ + image_rgba8 const& src_; + agg::trans_affine tr_; + double opacity_; + composite_mode_e comp_op_; + bool snap_to_pixels_; + + raster_marker_render_thunk(image_rgba8 const& src, + agg::trans_affine const& marker_trans, + double opacity, + composite_mode_e comp_op, + bool snap_to_pixels) + : src_(src), tr_(marker_trans), opacity_(opacity), comp_op_(comp_op), + snap_to_pixels_(snap_to_pixels) + {} +}; + +struct text_render_thunk : util::movable +{ + using helper_ptr = std::unique_ptr; + // helper is stored here in order + // to keep in scope the text rendering structures + helper_ptr helper_; + placements_list const& placements_; + double opacity_; + composite_mode_e comp_op_; + halo_rasterizer_enum halo_rasterizer_; + + text_render_thunk(helper_ptr && helper, + double opacity, composite_mode_e comp_op, + halo_rasterizer_enum halo_rasterizer) + : helper_(std::move(helper)), + placements_(helper_->get()), + opacity_(opacity), + comp_op_(comp_op), + halo_rasterizer_(halo_rasterizer) + {} +}; + +// Variant type for render thunks to allow us to re-render them +// via a static visitor later. + +using render_thunk = util::variant; +using render_thunk_ptr = std::unique_ptr; +using render_thunk_list = std::list; + +} // namespace mapnik + +#endif // MAPNIK_RENDERER_COMMON_RENDER_THUNK_HPP diff --git a/include/mapnik/renderer_common/render_thunk_extractor.hpp b/include/mapnik/renderer_common/render_thunk_extractor.hpp new file mode 100644 index 000000000..97e6c83cd --- /dev/null +++ b/include/mapnik/renderer_common/render_thunk_extractor.hpp @@ -0,0 +1,109 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2016 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_RENDERER_COMMON_RENDER_THUNK_EXTRACTOR_HPP +#define MAPNIK_RENDERER_COMMON_RENDER_THUNK_EXTRACTOR_HPP + +// mapnik +#include +#include +#include +#include + +namespace mapnik { + +// The approach here is to run the normal symbolizers, but in +// a 'virtual' blank environment where the changes that they +// make are recorded (the detector, the render_* calls). +// +// The recorded boxes are then used to lay out the items and +// the offsets from old to new positions can be used to perform +// the actual rendering calls. + +// This should allow us to re-use as much as possible of the +// existing symbolizer layout and rendering code while still +// being able to interpose our own decisions about whether +// a collision has occurred or not. + +struct virtual_renderer_common : private util::noncopyable +{ + virtual_renderer_common(renderer_common & common); + ~virtual_renderer_common(); + + unsigned & width_; + unsigned & height_; + double & scale_factor_; + attributes & vars_; + // TODO: dirty hack for cairo renderer, figure out how to remove this + std::shared_ptr & shared_font_library_; + font_library & font_library_; + face_manager_freetype & font_manager_; + box2d & query_extent_; + view_transform & t_; + std::unique_ptr detector_; +}; + +// Base class for extracting the bounding boxes associated with placing +// a symbolizer at a fake, virtual point - not real geometry. +// +// The bounding boxes can be used for layout, and the thunks are +// used to re-render at locations according to the group layout. + +struct render_thunk_extractor +{ + render_thunk_extractor(box2d & box, + render_thunk_list & thunks, + feature_impl & feature, + attributes const& vars, + proj_transform const& prj_trans, + virtual_renderer_common & common, + box2d const& clipping_extent); + + void operator()(markers_symbolizer const& sym) const; + + void operator()(text_symbolizer const& sym) const; + + void operator()(shield_symbolizer const& sym) const; + + template + void operator()(T const& ) const + { + // TODO: warning if unimplemented? + } + +private: + void extract_text_thunk(text_symbolizer const& sym) const; + + box2d & box_; + render_thunk_list & thunks_; + feature_impl & feature_; + attributes const& vars_; + proj_transform const& prj_trans_; + virtual_renderer_common & common_; + box2d clipping_extent_; + + void update_box() const; +}; + +} // namespace mapnik + +#endif // MAPNIK_RENDERER_COMMON_RENDER_THUNK_EXTRACTOR_HPP diff --git a/src/build.py b/src/build.py index ef211a9cc..f135b64ab 100644 --- a/src/build.py +++ b/src/build.py @@ -254,7 +254,7 @@ source = Split( color_factory.cpp renderer_common.cpp renderer_common/render_pattern.cpp - renderer_common/process_group_symbolizer.cpp + renderer_common/render_thunk_extractor.cpp math.cpp """ ) diff --git a/src/renderer_common/process_group_symbolizer.cpp b/src/renderer_common/render_thunk_extractor.cpp similarity index 67% rename from src/renderer_common/process_group_symbolizer.cpp rename to src/renderer_common/render_thunk_extractor.cpp index 5f75fe620..d2f4e29f1 100644 --- a/src/renderer_common/process_group_symbolizer.cpp +++ b/src/renderer_common/render_thunk_extractor.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2015 Artem Pavlenko + * Copyright (C) 2016 Artem Pavlenko * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,64 +21,32 @@ *****************************************************************************/ // mapnik -#include -#include +#include #include +#include +#include +#include namespace mapnik { -vector_marker_render_thunk::vector_marker_render_thunk(svg_path_ptr const& src, - svg_attribute_type const& attrs, - agg::trans_affine const& marker_trans, - double opacity, - composite_mode_e comp_op, - bool snap_to_pixels) - : src_(src), attrs_(attrs), tr_(marker_trans), opacity_(opacity), - comp_op_(comp_op), snap_to_pixels_(snap_to_pixels) +virtual_renderer_common::virtual_renderer_common(renderer_common & common) + : width_(common.width_), + height_(common.height_), + scale_factor_(common.scale_factor_), + vars_(common.vars_), + shared_font_library_(common.shared_font_library_), + font_library_(*shared_font_library_), + font_manager_(common.font_manager_), + query_extent_(common.query_extent_), + t_(common.t_), + detector_(new label_collision_detector4(common.detector_->extent())) {} -vector_marker_render_thunk::vector_marker_render_thunk(vector_marker_render_thunk && rhs) - : src_(std::move(rhs.src_)), - attrs_(std::move(rhs.attrs_)), - tr_(std::move(rhs.tr_)), - opacity_(std::move(rhs.opacity_)), - comp_op_(std::move(rhs.comp_op_)), - snap_to_pixels_(std::move(rhs.snap_to_pixels_)) {} - - -raster_marker_render_thunk::raster_marker_render_thunk(image_rgba8 const& src, - agg::trans_affine const& marker_trans, - double opacity, - composite_mode_e comp_op, - bool snap_to_pixels) - : src_(src), tr_(marker_trans), opacity_(opacity), comp_op_(comp_op), - snap_to_pixels_(snap_to_pixels) -{} - -raster_marker_render_thunk::raster_marker_render_thunk(raster_marker_render_thunk && rhs) - : src_(rhs.src_), - tr_(std::move(rhs.tr_)), - opacity_(std::move(rhs.opacity_)), - comp_op_(std::move(rhs.comp_op_)), - snap_to_pixels_(std::move(rhs.snap_to_pixels_)) {} - - -text_render_thunk::text_render_thunk(helper_ptr && helper, - double opacity, composite_mode_e comp_op, - halo_rasterizer_enum halo_rasterizer) - : helper_(std::move(helper)), - placements_(helper_->get()), - opacity_(opacity), - comp_op_(comp_op), - halo_rasterizer_(halo_rasterizer) -{} - -text_render_thunk::text_render_thunk(text_render_thunk && rhs) - : helper_(std::move(rhs.helper_)), - placements_(std::move(rhs.placements_)), - opacity_(std::move(rhs.opacity_)), - comp_op_(std::move(rhs.comp_op_)), - halo_rasterizer_(std::move(rhs.halo_rasterizer_)) {} +virtual_renderer_common::~virtual_renderer_common() +{ + // defined in .cpp to make this destructible elsewhere without + // having to #include +} namespace detail { @@ -147,7 +115,7 @@ private: render_thunk_list & thunks_; }; -} // end detail ns +} // namespace detail render_thunk_extractor::render_thunk_extractor(box2d & box, render_thunk_list & thunks, @@ -175,32 +143,23 @@ void render_thunk_extractor::operator()(markers_symbolizer const& sym) const void render_thunk_extractor::operator()(text_symbolizer const& sym) const { - box2d clip_box = clipping_extent_; - helper_ptr helper = std::make_unique( - sym, feature_, vars_, prj_trans_, - common_.width_, common_.height_, - common_.scale_factor_, - common_.t_, common_.font_manager_, *common_.detector_, - clip_box, agg::trans_affine()); - - extract_text_thunk(std::move(helper), sym); + extract_text_thunk(sym); } void render_thunk_extractor::operator()(shield_symbolizer const& sym) const { - box2d clip_box = clipping_extent_; - helper_ptr helper = std::make_unique( + extract_text_thunk(sym); +} + +void render_thunk_extractor::extract_text_thunk(text_symbolizer const& sym) const +{ + auto helper = std::make_unique( sym, feature_, vars_, prj_trans_, common_.width_, common_.height_, common_.scale_factor_, common_.t_, common_.font_manager_, *common_.detector_, - clip_box, agg::trans_affine()); + clipping_extent_, agg::trans_affine::identity); - extract_text_thunk(std::move(helper), sym); -} - -void render_thunk_extractor::extract_text_thunk(helper_ptr && helper, text_symbolizer const& sym) const -{ double opacity = get(sym, keys::opacity, feature_, common_.vars_, 1.0); composite_mode_e comp_op = get(sym, keys::comp_op, feature_, common_.vars_, src_over); halo_rasterizer_enum halo_rasterizer = get(sym, keys::halo_rasterizer, feature_, common_.vars_, HALO_RASTERIZER_FULL);