SVG points - implement using boost::spirit::x3 + refactor parse_rule
instantiations into separate *.cpp
This commit is contained in:
parent
584fda88e0
commit
95cc560167
7 changed files with 57 additions and 99 deletions
|
@ -23,26 +23,24 @@
|
||||||
#ifndef MAPNIK_SVG_PATH_GRAMMAR_X3_HPP
|
#ifndef MAPNIK_SVG_PATH_GRAMMAR_X3_HPP
|
||||||
#define MAPNIK_SVG_PATH_GRAMMAR_X3_HPP
|
#define MAPNIK_SVG_PATH_GRAMMAR_X3_HPP
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#include <mapnik/svg/svg_grammar_config_x3.hpp>
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/home/x3.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
namespace mapnik { namespace svg { namespace grammar {
|
namespace mapnik { namespace svg { namespace grammar {
|
||||||
|
|
||||||
namespace x3 = boost::spirit::x3;
|
namespace x3 = boost::spirit::x3;
|
||||||
|
|
||||||
class relative_tag;
|
|
||||||
class svg_path_tag;
|
|
||||||
|
|
||||||
using svg_path_grammar_type = x3::rule<class svg_path_rule_tag>;
|
using svg_path_grammar_type = x3::rule<class svg_path_rule_tag>;
|
||||||
|
using svg_points_grammar_type = x3::rule<class svg_points_rule_tag>;
|
||||||
|
|
||||||
BOOST_SPIRIT_DECLARE(svg_path_grammar_type);
|
BOOST_SPIRIT_DECLARE(svg_path_grammar_type,
|
||||||
|
svg_points_grammar_type);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
grammar::svg_path_grammar_type const& svg_path_grammar();
|
grammar::svg_path_grammar_type const& svg_path_grammar();
|
||||||
|
|
||||||
|
grammar::svg_points_grammar_type const& svg_points_grammar();
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif // MAPNIK_SVG_PATH_GRAMMAR_X3_HPP
|
#endif // MAPNIK_SVG_PATH_GRAMMAR_X3_HPP
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#ifndef MAPNIK_SVG_PATH_GRAMMAR_X3_DEF_HPP
|
#ifndef MAPNIK_SVG_PATH_GRAMMAR_X3_DEF_HPP
|
||||||
#define MAPNIK_SVG_PATH_GRAMMAR_X3_DEF_HPP
|
#define MAPNIK_SVG_PATH_GRAMMAR_X3_DEF_HPP
|
||||||
|
|
||||||
|
// mapnik
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/svg/svg_path_grammar_x3.hpp>
|
#include <mapnik/svg/svg_path_grammar_x3.hpp>
|
||||||
|
@ -137,11 +138,15 @@ auto const absolute = [] (auto const& ctx)
|
||||||
|
|
||||||
svg_path_grammar_type const svg_path = "SVG Path";
|
svg_path_grammar_type const svg_path = "SVG Path";
|
||||||
|
|
||||||
|
svg_points_grammar_type const svg_points = "SVG_Points";
|
||||||
|
|
||||||
auto const coord = x3::rule<class coord_tag, coord_type>{} = double_ > -lit(',') > double_;
|
auto const coord = x3::rule<class coord_tag, coord_type>{} = double_ > -lit(',') > double_;
|
||||||
|
|
||||||
|
auto const svg_points_def = coord[move_to] // move_to
|
||||||
|
> *(-lit(',') >> coord[line_to]); // *line_to
|
||||||
|
|
||||||
auto const M = x3::rule<class M_tag> {} = (lit('M')[absolute] | lit('m')[relative])
|
auto const M = x3::rule<class M_tag> {} = (lit('M')[absolute] | lit('m')[relative])
|
||||||
> coord[move_to] // move_to
|
> svg_points ;
|
||||||
> *(-lit(',') >> coord[line_to]); // *line_to
|
|
||||||
|
|
||||||
auto const H = x3::rule<class H_tag> {} = (lit('H')[absolute] | lit('h')[relative])
|
auto const H = x3::rule<class H_tag> {} = (lit('H')[absolute] | lit('h')[relative])
|
||||||
> (double_[ hline_to] % -lit(',')) ; // +hline_to
|
> (double_[ hline_to] % -lit(',')) ; // +hline_to
|
||||||
|
@ -179,7 +184,8 @@ auto const svg_path_def = +cmd;
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
BOOST_SPIRIT_DEFINE(
|
BOOST_SPIRIT_DEFINE(
|
||||||
svg_path
|
svg_path,
|
||||||
|
svg_points
|
||||||
);
|
);
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
@ -190,6 +196,11 @@ grammar::svg_path_grammar_type const& svg_path_grammar()
|
||||||
return grammar::svg_path;
|
return grammar::svg_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grammar::svg_points_grammar_type const& svg_points_grammar()
|
||||||
|
{
|
||||||
|
return grammar::svg_points;
|
||||||
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif // MAPNIK_SVG_PATH_GRAMMAR_X3_HPP
|
#endif // MAPNIK_SVG_PATH_GRAMMAR_X3_HPP
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
// NOTE: This is an implementation header file and is only meant to be included
|
|
||||||
// from implementation files. It therefore doesn't have an include guard.
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/svg/svg_points_grammar.hpp>
|
|
||||||
#include <mapnik/svg/svg_path_commands.hpp>
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_function.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
namespace mapnik { namespace svg {
|
|
||||||
|
|
||||||
using namespace boost::spirit;
|
|
||||||
using namespace boost::phoenix;
|
|
||||||
|
|
||||||
template <typename Iterator, typename PathType, typename SkipType>
|
|
||||||
svg_points_grammar<Iterator, PathType,SkipType>::svg_points_grammar()
|
|
||||||
: svg_points_grammar::base_type(start)
|
|
||||||
{
|
|
||||||
qi::_1_type _1;
|
|
||||||
qi::_r1_type _r1;
|
|
||||||
qi::lit_type lit;
|
|
||||||
qi::double_type double_;
|
|
||||||
// commands
|
|
||||||
function<move_to> move_to_;
|
|
||||||
function<line_to> line_to_;
|
|
||||||
function<close> close_;
|
|
||||||
|
|
||||||
start = coord[move_to_(_r1, _1, false)] // move_to
|
|
||||||
>> *(-lit(',') >> coord [ line_to_(_r1, _1,false) ] ); // *line_to
|
|
||||||
|
|
||||||
coord = double_ >> -lit(',') >> double_;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
|
@ -226,6 +226,7 @@ source = Split(
|
||||||
svg/svg_path_parser.cpp
|
svg/svg_path_parser.cpp
|
||||||
svg/svg_points_parser.cpp
|
svg/svg_points_parser.cpp
|
||||||
svg/svg_transform_parser.cpp
|
svg/svg_transform_parser.cpp
|
||||||
|
svg/svg_path_grammar_x3.cpp
|
||||||
warp.cpp
|
warp.cpp
|
||||||
css_color_grammar_x3.cpp
|
css_color_grammar_x3.cpp
|
||||||
vertex_cache.cpp
|
vertex_cache.cpp
|
||||||
|
|
|
@ -20,28 +20,18 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef SVG_POINTS_GRAMMAR_HPP
|
#include <mapnik/svg/svg_path_grammar_x3_def.hpp>
|
||||||
#define SVG_POINTS_GRAMMAR_HPP
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
namespace mapnik { namespace svg { namespace grammar {
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/include/qi.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
namespace mapnik { namespace svg {
|
#define BOOST_SPIRIT_INSTANTIATE_UNUSED(rule_type, Iterator, Context) \
|
||||||
|
template bool parse_rule<Iterator, Context, boost::spirit::x3::unused_type const>( \
|
||||||
|
rule_type rule_ \
|
||||||
|
, Iterator& first, Iterator const& last \
|
||||||
|
, Context const& context, boost::spirit::x3::unused_type const& ); \
|
||||||
|
/***/
|
||||||
|
|
||||||
using namespace boost::spirit;
|
BOOST_SPIRIT_INSTANTIATE_UNUSED(svg_path_grammar_type, iterator_type, svg_parse_context_type);
|
||||||
using namespace boost::phoenix;
|
BOOST_SPIRIT_INSTANTIATE_UNUSED(svg_points_grammar_type, iterator_type, svg_parse_context_type);
|
||||||
|
|
||||||
template <typename Iterator, typename PathType, typename SkipType>
|
}}}
|
||||||
struct svg_points_grammar : qi::grammar<Iterator, void(PathType&), SkipType>
|
|
||||||
{
|
|
||||||
// ctor
|
|
||||||
svg_points_grammar();
|
|
||||||
// rules
|
|
||||||
qi::rule<Iterator, void(PathType&), SkipType> start;
|
|
||||||
qi::rule<Iterator, boost::fusion::vector2<double, double>(), SkipType> coord;
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif // SVG_POINTS_GRAMMAR_HPP
|
|
|
@ -23,7 +23,7 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
|
|
||||||
#include <mapnik/svg/svg_path_parser.hpp>
|
#include <mapnik/svg/svg_path_parser.hpp>
|
||||||
#include <mapnik/svg/svg_path_grammar_x3_def.hpp>
|
#include <mapnik/svg/svg_path_grammar_x3.hpp>
|
||||||
// stl
|
// stl
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -36,18 +36,17 @@ bool parse_path(const char* wkt, PathType& p)
|
||||||
{
|
{
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
using iterator_type = char const*;
|
using iterator_type = char const*;
|
||||||
using skip_type = x3::ascii::space_type;
|
|
||||||
skip_type space;
|
|
||||||
iterator_type first = wkt;
|
iterator_type first = wkt;
|
||||||
iterator_type last = wkt + std::strlen(wkt);
|
iterator_type last = wkt + std::strlen(wkt);
|
||||||
bool relative = false;
|
bool relative = false;
|
||||||
|
using space_type = mapnik::svg::grammar::space_type;
|
||||||
auto const grammar = x3::with<mapnik::svg::grammar::svg_path_tag>(std::ref(p))
|
auto const grammar = x3::with<mapnik::svg::grammar::svg_path_tag>(std::ref(p))
|
||||||
[ x3::with<mapnik::svg::grammar::relative_tag>(std::ref(relative))
|
[ x3::with<mapnik::svg::grammar::relative_tag>(std::ref(relative))
|
||||||
[mapnik::svg::svg_path_grammar()]];
|
[mapnik::svg::svg_path_grammar()]];
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!x3::phrase_parse(first, last, grammar, space)
|
if (!x3::phrase_parse(first, last, grammar, space_type())
|
||||||
|| first != last)
|
|| first != last)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to parse svg-path");
|
throw std::runtime_error("Failed to parse svg-path");
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/svg/svg_path_parser.hpp>
|
#include <mapnik/svg/svg_path_parser.hpp>
|
||||||
#include <mapnik/svg/svg_points_grammar_impl.hpp>
|
#include <mapnik/svg/svg_path_grammar_x3.hpp>
|
||||||
// stl
|
// stl
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -34,12 +34,29 @@ template <typename PathType>
|
||||||
bool parse_points(const char* wkt, PathType& p)
|
bool parse_points(const char* wkt, PathType& p)
|
||||||
{
|
{
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
using iterator_type = const char*;
|
using iterator_type = char const*;
|
||||||
using skip_type = ascii::space_type;
|
using space_type = mapnik::svg::grammar::space_type;
|
||||||
static const svg_points_grammar<iterator_type, PathType, skip_type> g;
|
|
||||||
iterator_type first = wkt;
|
iterator_type first = wkt;
|
||||||
iterator_type last = wkt + std::strlen(wkt);
|
iterator_type last = wkt + std::strlen(wkt);
|
||||||
return qi::phrase_parse(first, last, (g)(boost::phoenix::ref(p)), skip_type());
|
bool relative = false;
|
||||||
|
|
||||||
|
auto const grammar = x3::with<mapnik::svg::grammar::svg_path_tag>(std::ref(p))
|
||||||
|
[ x3::with<mapnik::svg::grammar::relative_tag>(std::ref(relative))
|
||||||
|
[mapnik::svg::svg_points_grammar()]];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!x3::phrase_parse(first, last, grammar, space_type())
|
||||||
|
|| first != last)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse svg-path");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template bool parse_points<svg_converter_type>(const char*, svg_converter_type&);
|
template bool parse_points<svg_converter_type>(const char*, svg_converter_type&);
|
||||||
|
|
Loading…
Reference in a new issue