SVG generator outputs path vertices in user coordinates.

This commit is contained in:
Carlos López 2010-07-30 18:40:41 +00:00
parent 3791e95eda
commit 9af87ba8db
2 changed files with 70 additions and 4 deletions

View file

@ -29,14 +29,18 @@
#include <mapnik/ctrans.hpp> #include <mapnik/ctrans.hpp>
// boost // boost
#include <boost/fusion/include/adapt_class.hpp>
#include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/adapt_class.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/home/phoenix/bind/bind_member_function.hpp>
BOOST_FUSION_ADAPT_CLASS( BOOST_FUSION_ADAPT_CLASS(
mapnik::vertex_vector2<mapnik::vertex2d>::vertex_type, mapnik::vertex_vector2<mapnik::vertex2d>::vertex_type,
(unsigned, unsigned, obj.get<2>(), /**/) (unsigned, unsigned, obj.get<2>(), /**/)
(mapnik::vertex_vector2<mapnik::vertex2d>::value_type, mapnik::vertex_vector2<mapnik::vertex2d>::value_type, obj.get<0>(), /**/) (mapnik::vertex_vector2<mapnik::vertex2d>::value_type, mapnik::vertex_vector2<mapnik::vertex2d>::value_type, obj.get<0>(), /**/)
(mapnik::vertex_vector2<mapnik::vertex2d>::value_type, mapnik::vertex_vector2<mapnik::vertex2d>::value_type, obj.get<1>(), /**/) (mapnik::vertex_vector2<mapnik::vertex2d>::value_type, mapnik::vertex_vector2<mapnik::vertex2d>::value_type, obj.get<1>(), /**/)
(mapnik::vertex_vector2<mapnik::vertex2d>::value_type, mapnik::vertex_vector2<mapnik::vertex2d>::value_type, obj.get<0>(), /**/)
(mapnik::vertex_vector2<mapnik::vertex2d>::value_type, mapnik::vertex_vector2<mapnik::vertex2d>::value_type, obj.get<1>(), /**/)
) )
namespace boost { namespace spirit { namespace traits { namespace boost { namespace spirit { namespace traits {
@ -76,20 +80,82 @@ namespace boost { namespace spirit { namespace traits {
namespace mapnik { namespace svg { namespace mapnik { namespace svg {
using namespace boost::spirit; using namespace boost::spirit;
using namespace boost::phoenix;
template <typename PathType>
struct path_coordinate_transformer
{
explicit path_coordinate_transformer(PathType const& path_type)
: path_type_(path_type),
current_x_(0.0),
current_y_(0.0)
{}
void set_current_x(double& x)
{
current_x_ = x;
}
void set_current_y(double& y)
{
current_y_ = y;
path_type_.vertex(&current_x_, &current_y_);
}
void current_x(double& x) const
{
x = current_x_;
}
void current_y(double& y) const
{
y = current_y_;
}
PathType const& path_type_;
double current_x_;
double current_y_;
};
template <typename OutputIterator, typename PathType> template <typename OutputIterator, typename PathType>
struct svg_generator_path_grammar : karma::grammar<OutputIterator, mapnik::geometry2d()> struct svg_generator_path_grammar : karma::grammar<OutputIterator, mapnik::geometry2d()>
{ {
typedef path_coordinate_transformer<PathType> coordinate_transformer;
typedef mapnik::vertex_vector2<mapnik::vertex2d>::vertex_type vertex_type;
typedef mapnik::vertex_vector2<mapnik::vertex2d>::value_type vertex_component_type;
explicit svg_generator_path_grammar(PathType const& path_type) explicit svg_generator_path_grammar(PathType const& path_type)
: svg_generator_path_grammar::base_type(svg_path), : svg_generator_path_grammar::base_type(svg_path),
path_type_(path_type) path_type_(path_type),
ct_(path_type)
{ {
svg_path = *(karma::int_ << karma::lit(' ') << karma::double_ << karma::lit(' ') << karma::double_ << karma::eol); using karma::int_;
using karma::double_;
using karma::eol;
using karma::omit;
using karma::_1;
using karma::_a;
svg_path = *(path_vertex);
path_vertex = int_
<< omit[path_vertex_component_x] << omit[path_vertex_component_y]
<< path_vertex_transformed_x
<< ' '
<< path_vertex_transformed_y
<< eol;
path_vertex_component_x = double_[_1 = _a][bind(&coordinate_transformer::set_current_x, &ct_, _a)][_a = _val];
path_vertex_component_y = double_[_1 = _a][bind(&coordinate_transformer::set_current_y, &ct_, _a)][_a = _val];
path_vertex_transformed_x = double_[_1 = _a][bind(&coordinate_transformer::current_x, &ct_, _a)];
path_vertex_transformed_y = double_[_1 = _a][bind(&coordinate_transformer::current_y, &ct_, _a)];
} }
karma::rule<OutputIterator, mapnik::geometry2d()> svg_path; karma::rule<OutputIterator, mapnik::geometry2d()> svg_path;
karma::rule<OutputIterator, vertex_type()> path_vertex;
karma::rule<OutputIterator, vertex_component_type(), karma::locals<double> > path_vertex_component_x, path_vertex_component_y;
karma::rule<OutputIterator, vertex_component_type(), karma::locals<double> > path_vertex_transformed_x, path_vertex_transformed_y;
PathType const& path_type_; PathType const& path_type_;
coordinate_transformer ct_;
}; };
}} }}

View file

@ -190,6 +190,7 @@ if env['SVG_RENDERER']: # svg backend
source += Split( source += Split(
""" """
svg/svg_renderer.cpp svg/svg_renderer.cpp
svg/svg_generator.cpp
svg/process_building_symbolizer.cpp svg/process_building_symbolizer.cpp
svg/process_glyph_symbolizer.cpp svg/process_glyph_symbolizer.cpp
svg/process_line_pattern_symbolizer.cpp svg/process_line_pattern_symbolizer.cpp
@ -201,7 +202,6 @@ if env['SVG_RENDERER']: # svg backend
svg/process_raster_symbolizer.cpp svg/process_raster_symbolizer.cpp
svg/process_shield_symbolizer.cpp svg/process_shield_symbolizer.cpp
svg/process_text_symbolizer.cpp svg/process_text_symbolizer.cpp
svg/svg_generator.cpp
""") """)
mapnik = env.SharedLibrary('mapnik2', source, LIBS=libraries, LINKFLAGS=linkflags) mapnik = env.SharedLibrary('mapnik2', source, LIBS=libraries, LINKFLAGS=linkflags)