split common group symbolizer stuff

This commit is contained in:
Mickey Rose 2016-01-22 14:13:25 +01:00
parent 971508d752
commit 7761d32ec5
7 changed files with 261 additions and 242 deletions

View file

@ -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 \

View file

@ -41,8 +41,10 @@ namespace mapnik
struct image_any;
namespace svg { struct path_attributes; }
using attr_storage = agg::pod_bvector<mapnik::svg::path_attributes>;
using svg_storage_type = mapnik::svg::svg_storage<mapnik::svg::svg_path_storage,attr_storage>;
using svg::svg_path_adapter;
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_path_ptr = std::shared_ptr<svg_storage_type>;
using image_ptr = std::shared_ptr<image_any>;

View file

@ -29,6 +29,7 @@
#include <mapnik/feature.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/renderer_common.hpp>
#include <mapnik/renderer_common/render_thunk_extractor.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/attribute_collector.hpp>
#include <mapnik/group/group_layout_manager.hpp>
@ -36,176 +37,9 @@
#include <mapnik/group/group_symbolizer_properties.hpp>
#include <mapnik/text/glyph_positions.hpp>
#include <mapnik/util/conversions.hpp>
#include <mapnik/util/variant.hpp>
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>
// agg
#include <agg_trans_affine.h>
namespace mapnik {
class text_symbolizer_helper;
using svg::svg_path_adapter;
using svg_attribute_type = agg::pod_bvector<svg::path_attributes>;
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<label_collision_detector4>(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<font_library> & shared_font_library_;
font_library & font_library_;
face_manager_freetype & font_manager_;
box2d<double> & query_extent_;
view_transform & t_;
std::shared_ptr<label_collision_detector4> 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<text_symbolizer_helper>;
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<vector_marker_render_thunk,
raster_marker_render_thunk,
text_render_thunk>;
using render_thunk_ptr = std::unique_ptr<render_thunk>;
using render_thunk_list = std::list<render_thunk_ptr>;
// 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<double> & box,
render_thunk_list & thunks,
feature_impl & feature,
attributes const& vars,
proj_transform const& prj_trans,
virtual_renderer_common & common,
box2d<double> 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 <typename T>
void operator()(T const& ) const
{
// TODO: warning if unimplemented?
}
private:
void extract_text_thunk(helper_ptr && helper, text_symbolizer const& sym) const;
box2d<double> & box_;
render_thunk_list & thunks_;
feature_impl & feature_;
attributes const& vars_;
proj_transform const& prj_trans_;
virtual_renderer_common & common_;
box2d<double> clipping_extent_;
void update_box() const;
};
template <typename F>
void render_offset_placements(placements_list const& placements,
pixel_position const& offset,

View file

@ -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 <mapnik/image_compositing.hpp> // composite_mode_e
#include <mapnik/marker.hpp> // svg_attribute_type, svg_path_ptr
#include <mapnik/symbolizer_enumerations.hpp> // halo_rasterizer_enum
#include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/util/variant.hpp>
// agg
#include <agg_trans_affine.h>
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<text_symbolizer_helper>;
// 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<vector_marker_render_thunk,
raster_marker_render_thunk,
text_render_thunk>;
using render_thunk_ptr = std::unique_ptr<render_thunk>;
using render_thunk_list = std::list<render_thunk_ptr>;
} // namespace mapnik
#endif // MAPNIK_RENDERER_COMMON_RENDER_THUNK_HPP

View file

@ -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 <mapnik/renderer_common.hpp>
#include <mapnik/renderer_common/render_thunk.hpp>
#include <mapnik/symbolizer_base.hpp>
#include <mapnik/util/noncopyable.hpp>
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<font_library> & shared_font_library_;
font_library & font_library_;
face_manager_freetype & font_manager_;
box2d<double> & query_extent_;
view_transform & t_;
std::unique_ptr<label_collision_detector4> 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<double> & box,
render_thunk_list & thunks,
feature_impl & feature,
attributes const& vars,
proj_transform const& prj_trans,
virtual_renderer_common & common,
box2d<double> 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 <typename T>
void operator()(T const& ) const
{
// TODO: warning if unimplemented?
}
private:
void extract_text_thunk(text_symbolizer const& sym) const;
box2d<double> & box_;
render_thunk_list & thunks_;
feature_impl & feature_;
attributes const& vars_;
proj_transform const& prj_trans_;
virtual_renderer_common & common_;
box2d<double> clipping_extent_;
void update_box() const;
};
} // namespace mapnik
#endif // MAPNIK_RENDERER_COMMON_RENDER_THUNK_EXTRACTOR_HPP

View file

@ -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
"""
)

View file

@ -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 <mapnik/renderer_common/process_group_symbolizer.hpp>
#include <mapnik/renderer_common/process_markers_symbolizer.hpp>
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/make_unique.hpp>
#include <mapnik/marker_helpers.hpp>
#include <mapnik/renderer_common/process_markers_symbolizer.hpp>
#include <mapnik/renderer_common/render_thunk_extractor.hpp>
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 <mapnik/label_collision_detector.hpp>
}
namespace detail {
@ -147,7 +115,7 @@ private:
render_thunk_list & thunks_;
};
} // end detail ns
} // namespace detail
render_thunk_extractor::render_thunk_extractor(box2d<double> & 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<double> clip_box = clipping_extent_;
helper_ptr helper = std::make_unique<text_symbolizer_helper>(
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<double> clip_box = clipping_extent_;
helper_ptr helper = std::make_unique<text_symbolizer_helper>(
extract_text_thunk(sym);
}
void render_thunk_extractor::extract_text_thunk(text_symbolizer const& sym) const
{
auto helper = std::make_unique<text_symbolizer_helper>(
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<double>(sym, keys::opacity, feature_, common_.vars_, 1.0);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature_, common_.vars_, src_over);
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, feature_, common_.vars_, HALO_RASTERIZER_FULL);