diff --git a/include/mapnik/vertex_converters.hpp b/include/mapnik/vertex_converters.hpp new file mode 100644 index 000000000..a0521c6b8 --- /dev/null +++ b/include/mapnik/vertex_converters.hpp @@ -0,0 +1,231 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2012 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_VERTEX_CONVERTERS_HPP +#define MAPNIK_VERTEX_CONVERTERS_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// fusion +//#include +//#include + +#include +#include +#include + +// agg +#include "agg_conv_clip_polygon.h" +#include "agg_conv_clip_polyline.h" +#include "agg_conv_smooth_poly1.h" + + +namespace mapnik { + +struct transform {}; +struct clip_line {}; +struct clip_poly {}; +struct smooth {}; + +namespace detail { + +template +struct converter_traits +{ + typedef T0 geometry_type; + typedef geometry_type conv_type; + template + static void setup(geometry_type & geom,Symbolizer const& sym) + { + throw "BOOM!"; + } +}; + +template +struct converter_traits +{ + typedef T geometry_type; + typedef typename agg::conv_smooth_poly1_curve conv_type; + + template + static void setup(geometry_type & geom, Symbolizer const& sym) + { + //std::cout << "SETUP:" << typeid(geom).name() << std::endl; + geom.smooth_value(sym.smooth()); + } +}; + +/* +template +struct converter_traits +{ + typedef T geometry_type; + typedef typename agg::conv_clip_polyline conv_type; + + template + static void setup(geometry_type & geom, Symbolizer const& sym) + { + //std::cout << "SETUP:" << typeid(geom).name() << std::endl; + geom.clip_box(0,0,100,100); + } +}; +*/ + +template +struct converter_traits +{ + typedef T geometry_type; + typedef typename agg::conv_clip_polygon conv_type; + + template + static void setup(geometry_type & geom, Symbolizer const& sym) + { + //std::cout << "SETUP:" << typeid(geom).name() << std::endl; + geom.clip_box(0,0,100,100); + } +}; + +template +struct converter_fwd +{ + template + static void forward(Base& base, T0 & geom,T1 const& sym) + { + typedef T0 geometry_type; + typedef T2 conv_tag; + typedef typename detail::converter_traits::conv_type conv_type; + conv_type conv(geom); + detail::converter_traits::setup(conv, sym); + base.template dispatch(conv, typename boost::is_same::type()); + } +}; + +template <> +struct converter_fwd +{ + template + static void forward(Base& base, T0 & geom,T1 const& sym) + { + base.template dispatch(geom, typename boost::is_same::type()); + } +}; + +template +struct dispatcher +{ + typedef dispatcher this_type; + typedef S symbolizer_type; + typedef R rasterizer_type; + typedef C conv_types; + dispatcher(rasterizer_type & ras, symbolizer_type const& sym) + : ras_(ras), + sym_(sym) + { + std::memset(&vec_[0], 0, sizeof(unsigned)*vec_.size()); + } + + template + void dispatch(Geometry & geom, boost::mpl::true_) + { + ras_.add_path(geom); + } + + template + void dispatch(Geometry & geom, boost::mpl::false_) + { + typedef typename boost::mpl::deref::type conv_tag; + typedef typename detail::converter_traits::conv_type conv_type; + typedef typename boost::mpl::next::type Next; + + std::size_t index = boost::mpl::distance::value - 1; + if (vec_[index] == 1) + { + converter_fwd::value>:: + template forward(*this,geom,sym_); + } + else + { + converter_fwd:: + template forward(*this,geom,sym_); + } + + } + + template + void apply(Geometry & geom) + { + typedef typename boost::mpl::begin::type begin; + typedef typename boost::mpl::end ::type end; + dispatch(geom, boost::false_type()); + } + + boost::array::value> vec_; + rasterizer_type & ras_; + symbolizer_type const& sym_; + +}; +} + +template +struct vertex_converter : private boost::noncopyable +{ + typedef C conv_types; + typedef R rasterizer_type; + typedef S symbolizer_type; + vertex_converter(rasterizer_type & ras, symbolizer_type const& sym) + : disp_(ras,sym) {} + + template + void apply(T & geom) + { + typedef T geometry_type; + //BOOST_FOREACH(geometry_type & geom, cont) + { + disp_.template apply(geom); + } + } + + template + void set() + { + typedef typename boost::mpl::find::type iter; + typedef typename boost::mpl::end::type end; + std::size_t index = boost::mpl::distance::value - 1; + if (index < disp_.vec_.size()) + disp_.vec_[index]=1; + } + + detail::dispatcher disp_; +}; + +} + +#endif // MAPNIK_VERTEX_CONVERTERS_HPP