use common dispatch for symbolizers

This commit is contained in:
Dane Springmeyer 2014-10-03 19:07:08 -07:00
parent 2cf3990e0d
commit e0ba9e9a8c
4 changed files with 8 additions and 104 deletions

View file

@ -53,7 +53,6 @@ enum eAttributeCollectionPolicy
template <typename Processor>
class MAPNIK_DECL feature_style_processor
{
struct symbol_dispatch;
public:
explicit feature_style_processor(Map const& m,
double scale_factor = 1.0);

View file

@ -31,7 +31,6 @@
#include <mapnik/feature.hpp>
#include <mapnik/feature_style_processor.hpp>
#include <mapnik/query.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/feature_type_style.hpp>
#include <mapnik/box2d.hpp>
@ -45,6 +44,8 @@
#include <mapnik/proj_transform.hpp>
#include <mapnik/util/featureset_buffer.hpp>
#include <mapnik/util/variant.hpp>
#include <mapnik/symbolizer_dispatch.hpp>
// stl
#include <vector>
#include <stdexcept>
@ -52,79 +53,6 @@
namespace mapnik
{
template <typename T0,typename T1> struct has_process;
template <bool>
struct process_impl
{
template <typename T0, typename T1, typename T2, typename T3>
static void process(T0 & ren, T1 const& sym, T2 & f, T3 const& tr)
{
ren.process(sym,f,tr);
}
};
template <> // No-op specialization
struct process_impl<false>
{
template <typename T0, typename T1, typename T2, typename T3>
static void process(T0 & /*ren*/, T1 const& /*sym*/, T2 & /*f*/, T3 const& /*tr*/)
{
#ifdef MAPNIK_DEBUG
#ifdef _MSC_VER
#pragma NOTE(process function not implemented)
#else
#warning process function not implemented
#endif
#endif
}
};
/** Calls the renderer's process function,
* \param output Renderer
* \param f Feature to process
* \param prj_trans Projection
* \param sym Symbolizer object
*/
template <typename Processor>
struct feature_style_processor<Processor>::symbol_dispatch : public util::static_visitor<>
{
symbol_dispatch (Processor & output,
mapnik::feature_impl & f,
proj_transform const& prj_trans)
: output_(output),
f_(f),
prj_trans_(prj_trans) {}
template <typename T>
void operator () (T const& sym) const
{
process_impl<has_process<Processor,T>::value>::process(output_,sym,f_,prj_trans_);
}
Processor & output_;
mapnik::feature_impl & f_;
proj_transform const& prj_trans_;
};
using no_tag = char (&)[1];
using yes_tag = char (&)[2];
template <typename T0, typename T1, void (T0::*)(T1 const&, mapnik::feature_impl &, proj_transform const&) >
struct process_memfun_helper {};
template <typename T0, typename T1> no_tag has_process_helper(...);
template <typename T0, typename T1> yes_tag has_process_helper(process_memfun_helper<T0, T1, &T0::process>* p);
template<typename T0,typename T1>
struct has_process
{
using processor_impl_type = typename T0::processor_impl_type;
BOOST_STATIC_CONSTANT(bool
, value = sizeof(has_process_helper<processor_impl_type,T1>(0)) == sizeof(yes_tag)
);
};
// Store material for layer rendering in a two step process
struct layer_rendering_material
{
@ -665,7 +593,7 @@ void feature_style_processor<Processor>::render_style(
{
for (symbolizer const& sym : symbols)
{
util::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
util::apply_visitor(symbolizer_dispatch<Processor>(p,*feature,prj_trans),sym);
}
}
if (style->get_filter_mode() == FILTER_FIRST)
@ -686,7 +614,7 @@ void feature_style_processor<Processor>::render_style(
{
for (symbolizer const& sym : symbols)
{
util::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
util::apply_visitor(symbolizer_dispatch<Processor>(p,*feature,prj_trans),sym);
}
}
}
@ -701,7 +629,7 @@ void feature_style_processor<Processor>::render_style(
{
for (symbolizer const& sym : symbols)
{
util::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
util::apply_visitor(symbolizer_dispatch<Processor>(p,*feature,prj_trans),sym);
}
}
}

View file

@ -166,31 +166,6 @@ private:
svg::svg_generator<OutputIterator> generator_;
bool painted_;
renderer_common common_;
// Visitor that makes the calls to process each symbolizer when stored in a variant.
// This object follows the model of that found in feature_style_processor. It appears here, because
// the logic that iterates over the set of symbolizer has been moved to an SVG renderer's internal
// method.
struct symbol_dispatch : public util::static_visitor<>
{
symbol_dispatch(svg_renderer<OutputIterator>& processor,
mapnik::feature_impl & feature,
proj_transform const& prj_trans)
: processor_(processor),
feature_(feature),
prj_trans_(prj_trans) {}
template <typename Symbolizer>
void operator()(Symbolizer const& sym) const
{
processor_.process(sym, feature_, prj_trans_);
}
svg_renderer<OutputIterator>& processor_;
mapnik::feature_impl & feature_;
proj_transform const& prj_trans_;
};
};
}

View file

@ -30,6 +30,8 @@
#include <mapnik/svg/geometry_svg_generator_impl.hpp>
#include <mapnik/svg/output/svg_output_grammars.hpp>
#include <mapnik/svg/output/svg_output_attributes.hpp>
#include <mapnik/symbolizer_dispatch.hpp>
// boost
#include <boost/spirit/include/karma.hpp>
@ -89,7 +91,7 @@ bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms,
{
process_path = true;
}
util::apply_visitor(symbol_dispatch(*this, feature, prj_trans), sym);
util::apply_visitor(symbolizer_dispatch<svg_renderer<OutputIterator>>(*this, feature, prj_trans), sym);
}
if (process_path)