diff --git a/include/mapnik/svg/svg_path_grammar.hpp b/include/mapnik/svg/svg_path_grammar.hpp index d45c1d3a2..a65b27266 100644 --- a/include/mapnik/svg/svg_path_grammar.hpp +++ b/include/mapnik/svg/svg_path_grammar.hpp @@ -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 @@ -23,77 +23,21 @@ #ifndef MAPNIK_SVG_PATH_GRAMMAR_HPP #define MAPNIK_SVG_PATH_GRAMMAR_HPP -// mapnik -#include - // spirit +#pragma GCC diagnostic push +#include #include -#include -#include -#include +#pragma GCC diagnostic pop namespace mapnik { namespace svg { using namespace boost::spirit; -using namespace boost::phoenix; template struct svg_path_grammar : qi::grammar { - svg_path_grammar() - : svg_path_grammar::base_type(start) - { - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_5_type _5; - qi::_a_type _a; - qi::lit_type lit; - qi::_r1_type _r1; - qi::double_type double_; - qi::int_type int_; - qi::no_case_type no_case; - - start = +cmd(_r1); - - cmd = M(_r1) >> *drawto_cmd(_r1); - - drawto_cmd = L(_r1) | H(_r1) | V(_r1) | C(_r1) | S(_r1) | Q(_r1) | T(_r1) | A(_r1) | Z(_r1); - - M = (lit('M')[_a = false] | lit('m')[_a = true]) >> coord[move_to_(_r1, _1, _a)] // move_to - >> *(-lit(',') >> coord[line_to_(_r1, _1, _a)]); // *line_to - - H = (lit('H')[_a = false] | lit('h')[_a = true]) - >> (double_[ hline_to_(_r1, _1,_a) ] % -lit(',')) ; // +hline_to - - V = (lit('V')[_a = false] | lit('v')[_a = true]) - >> (double_ [ vline_to_(_r1, _1,_a) ] % -lit(',')); // +vline_to - - L = (lit('L')[_a = false] | lit('l')[_a = true]) - >> (coord [ line_to_(_r1, _1, _a) ] % -lit(',')); // +line_to - - C = (lit('C')[_a = false] | lit('c')[_a = true]) - >> ((coord >> -lit(',') >> coord >> -lit(',') >> coord)[curve4_(_r1, _1, _2, _3, _a)] % -lit(',')); // +curve4 - - S = (lit('S')[_a = false] | lit('s')[_a = true]) - >> ((coord >> -lit(',') >> coord) [ curve4_smooth_(_r1, _1,_2,_a) ] % -lit(',')); // +curve4_smooth (smooth curveto) - - Q = (lit('Q')[_a = false] | lit('q')[_a = true]) - >> ((coord >> -lit(',') >> coord) [ curve3_(_r1, _1,_2,_a) ] % -lit(',')); // +curve3 (quadratic-bezier-curveto) - - T = (lit('T')[_a = false] | lit('t')[_a = true]) - >> ((coord ) [ curve3_smooth_(_r1, _1,_a) ] % -lit(',')); // +curve3_smooth (smooth-quadratic-bezier-curveto) - - A = (lit('A')[_a = false] | lit('a')[_a = true]) - >> ((coord >> -lit(',') >> double_ >> -lit(',') >> int_ >> -lit(',') >> int_ >> -lit(',') >> coord) - [arc_to_(_r1, _1, _2, _3, _4, _5, _a)] % -lit(',')); // arc_to; - - Z = no_case[lit('z')] [close_(_r1)]; // close path - - coord = double_ >> -lit(',') >> double_; - } - + // ctor + svg_path_grammar(); // rules qi::rule start; qi::rule cmd; @@ -108,20 +52,7 @@ struct svg_path_grammar : qi::grammar qi::rule, void(PathType&), SkipType> T; // T,t qi::rule, void(PathType&), SkipType> A; // A,a qi::rule Z; // Z,z - qi::rule(), SkipType> coord; - - // commands - function move_to_; - function hline_to_; - function vline_to_; - function line_to_; - function curve4_; - function curve4_smooth_; - function curve3_; - function curve3_smooth_; - function arc_to_; - function close_; }; }} diff --git a/include/mapnik/svg/svg_path_grammar_impl.hpp b/include/mapnik/svg/svg_path_grammar_impl.hpp new file mode 100644 index 000000000..2946005ff --- /dev/null +++ b/include/mapnik/svg/svg_path_grammar_impl.hpp @@ -0,0 +1,110 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + + +// mapnik +#include +#include + +// spirit +#pragma GCC diagnostic push +#include +#include +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace svg { + +using namespace boost::spirit; +using namespace boost::phoenix; + + +template +svg_path_grammar::svg_path_grammar() + : svg_path_grammar::base_type(start) +{ + qi::_1_type _1; + qi::_2_type _2; + qi::_3_type _3; + qi::_4_type _4; + qi::_5_type _5; + qi::_a_type _a; + qi::lit_type lit; + qi::_r1_type _r1; + qi::double_type double_; + qi::int_type int_; + qi::no_case_type no_case; + + // commands + function move_to_; + function hline_to_; + function vline_to_; + function line_to_; + function curve4_; + function curve4_smooth_; + function curve3_; + function curve3_smooth_; + function arc_to_; + function close_; + // + start = +cmd(_r1); + + cmd = M(_r1) >> *drawto_cmd(_r1); + + drawto_cmd = L(_r1) | H(_r1) | V(_r1) | C(_r1) | S(_r1) | Q(_r1) | T(_r1) | A(_r1) | Z(_r1); + + M = (lit('M')[_a = false] | lit('m')[_a = true]) >> coord[move_to_(_r1, _1, _a)] // move_to + >> *(-lit(',') >> coord[line_to_(_r1, _1, _a)]); // *line_to + + H = (lit('H')[_a = false] | lit('h')[_a = true]) + >> (double_[ hline_to_(_r1, _1,_a) ] % -lit(',')) ; // +hline_to + + V = (lit('V')[_a = false] | lit('v')[_a = true]) + >> (double_ [ vline_to_(_r1, _1,_a) ] % -lit(',')); // +vline_to + + L = (lit('L')[_a = false] | lit('l')[_a = true]) + >> (coord [ line_to_(_r1, _1, _a) ] % -lit(',')); // +line_to + + C = (lit('C')[_a = false] | lit('c')[_a = true]) + >> ((coord >> -lit(',') >> coord >> -lit(',') >> coord)[curve4_(_r1, _1, _2, _3, _a)] % -lit(',')); // +curve4 + + S = (lit('S')[_a = false] | lit('s')[_a = true]) + >> ((coord >> -lit(',') >> coord) [ curve4_smooth_(_r1, _1,_2,_a) ] % -lit(',')); // +curve4_smooth (smooth curveto) + + Q = (lit('Q')[_a = false] | lit('q')[_a = true]) + >> ((coord >> -lit(',') >> coord) [ curve3_(_r1, _1,_2,_a) ] % -lit(',')); // +curve3 (quadratic-bezier-curveto) + + T = (lit('T')[_a = false] | lit('t')[_a = true]) + >> ((coord ) [ curve3_smooth_(_r1, _1,_a) ] % -lit(',')); // +curve3_smooth (smooth-quadratic-bezier-curveto) + + A = (lit('A')[_a = false] | lit('a')[_a = true]) + >> ((coord >> -lit(',') >> double_ >> -lit(',') >> int_ >> -lit(',') >> int_ >> -lit(',') >> coord) + [arc_to_(_r1, _1, _2, _3, _4, _5, _a)] % -lit(',')); // arc_to; + + Z = no_case[lit('z')] [close_(_r1)]; // close path + + coord = double_ >> -lit(',') >> double_; +} + +} // namespace svg +} // namespace mapnik diff --git a/include/mapnik/svg/svg_path_parser.hpp b/include/mapnik/svg/svg_path_parser.hpp index 35303f98d..5633b2ea9 100644 --- a/include/mapnik/svg/svg_path_parser.hpp +++ b/include/mapnik/svg/svg_path_parser.hpp @@ -23,20 +23,32 @@ #ifndef MAPNIK_SVG_PATH_PARSER_HPP #define MAPNIK_SVG_PATH_PARSER_HPP +// mapnik #include +#include +#include +// stl #include -namespace mapnik { namespace svg { +namespace mapnik { +namespace svg { - template - bool parse_path(const char * wkt, PathType & p); +template +bool parse_path(const char* wkt, PathType& p); - template - bool parse_points(const char * wkt, PathType & p); +template +bool parse_points(const char* wkt, PathType& p); + +template +bool MAPNIK_DECL parse_svg_transform(const char* wkt, TransformType& tr); + +// +extern template bool MAPNIK_DECL parse_path(const char*, svg_converter_type&); +extern template bool MAPNIK_DECL parse_points(const char*, svg_converter_type&); +extern template bool MAPNIK_DECL parse_svg_transform(const char*, svg_converter_type&); +} +} - template - bool MAPNIK_DECL parse_svg_transform(const char * wkt, TransformType & tr); -}} #endif // MAPNIK_SVG_PATH_PARSER_HPP diff --git a/include/mapnik/svg/svg_points_grammar.hpp b/include/mapnik/svg/svg_points_grammar.hpp index a816491b7..afbe7ee09 100644 --- a/include/mapnik/svg/svg_points_grammar.hpp +++ b/include/mapnik/svg/svg_points_grammar.hpp @@ -29,9 +29,6 @@ #pragma GCC diagnostic push #include #include -#include -#include -#include #pragma GCC diagnostic pop namespace mapnik { namespace svg { @@ -42,31 +39,12 @@ using namespace boost::phoenix; template struct svg_points_grammar : qi::grammar { - 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_; - - start = coord[move_to_(_r1, _1, false)] // move_to - >> *(-lit(',') >> coord [ line_to_(_r1, _1,false) ] ); // *line_to - - coord = double_ >> -lit(',') >> double_; - } - + // ctor + svg_points_grammar(); // rules qi::rule start; - qi::rule(),SkipType> coord; - - // commands - function move_to_; - function line_to_; - function close_; + qi::rule(), SkipType> coord; }; - }} - #endif // SVG_POINTS_GRAMMAR_HPP diff --git a/include/mapnik/svg/svg_points_grammar_impl.hpp b/include/mapnik/svg/svg_points_grammar_impl.hpp new file mode 100644 index 000000000..4431909fa --- /dev/null +++ b/include/mapnik/svg/svg_points_grammar_impl.hpp @@ -0,0 +1,60 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2015 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 + * + *****************************************************************************/ + + +// mapnik +#include +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace svg { + +using namespace boost::spirit; +using namespace boost::phoenix; + +template +svg_points_grammar::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_; + function line_to_; + function close_; + + start = coord[move_to_(_r1, _1, false)] // move_to + >> *(-lit(',') >> coord [ line_to_(_r1, _1,false) ] ); // *line_to + + coord = double_ >> -lit(',') >> double_; +} + +}} diff --git a/include/mapnik/svg/svg_transform_grammar.hpp b/include/mapnik/svg/svg_transform_grammar.hpp index dedd72125..895112d4a 100644 --- a/include/mapnik/svg/svg_transform_grammar.hpp +++ b/include/mapnik/svg/svg_transform_grammar.hpp @@ -26,144 +26,20 @@ // mapnik #include -// agg -#include - #pragma GCC diagnostic push #include #include -#include -#include -#include -#include #pragma GCC diagnostic pop namespace mapnik { namespace svg { using namespace boost::spirit; -using namespace boost::fusion; -using namespace boost::phoenix; - -inline double deg2rad(double d) -{ - return M_PI * d / 180.0; -} - -struct process_matrix -{ - using result_type = void; - template - void operator () (TransformType & tr, double a, double b, double c, double d, double e, double f) const - { - tr = agg::trans_affine(a,b,c,d,e,f) * tr; - } -}; - -struct process_rotate -{ - using result_type = void; - - template - void operator () (TransformType & tr, T0 a, T1 cx, T2 cy) const - { - if (cx == 0.0 && cy == 0.0) - { - tr = agg::trans_affine_rotation(deg2rad(a)) * tr; - } - else - { - agg::trans_affine t = agg::trans_affine_translation(-cx,-cy); - t *= agg::trans_affine_rotation(deg2rad(a)); - t *= agg::trans_affine_translation(cx, cy); - tr = t * tr; - } - } -}; - -struct process_translate -{ - using result_type = void; - template - void operator () (TransformType & tr, T0 tx, T1 ty) const - { - if (ty) tr = agg::trans_affine_translation(tx,*ty) * tr; - else tr = agg::trans_affine_translation(tx,0.0) * tr; - } -}; - -struct process_scale -{ - using result_type = void; - template - void operator () (TransformType & tr, T0 sx, T1 sy) const - { - if (sy) tr = agg::trans_affine_scaling(sx,*sy) * tr; - else tr = agg::trans_affine_scaling(sx,sx) * tr; - } -}; - - -struct process_skew -{ - using result_type = void; - - template - void operator () (TransformType & tr, T0 skew_x, T1 skew_y) const - { - tr = agg::trans_affine_skewing(deg2rad(skew_x),deg2rad(skew_y)) * tr; - } -}; template struct svg_transform_grammar : qi::grammar { - svg_transform_grammar() - : svg_transform_grammar::base_type(start) - { - qi::_1_type _1; - qi::_2_type _2; - qi::_3_type _3; - qi::_4_type _4; - qi::_5_type _5; - qi::_6_type _6; - qi::_a_type _a; - qi::_b_type _b; - qi::_c_type _c; - qi::_r1_type _r1; - qi::lit_type lit; - qi::double_type double_; - qi::no_case_type no_case; - - start = +transform_(_r1) ; - - transform_ = matrix(_r1) | rotate(_r1) | translate(_r1) | scale(_r1) | rotate(_r1) | skewX(_r1) | skewY (_r1) ; - - matrix = no_case[lit("matrix")] >> lit('(') - >> (double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_ >> -lit(',') - >> double_)[matrix_action(_r1, _1, _2, _3, _4, _5, _6)] >> lit(')'); - - translate = no_case[lit("translate")] - >> lit('(') >> (double_ >> -lit(',') >> -double_)[translate_action(_r1, _1, _2)] >> lit(')'); - - scale = no_case[lit("scale")] - >> lit('(') >> (double_ >> -lit(',') >> -double_)[scale_action(_r1, _1, _2)] >> lit(')'); - - rotate = no_case[lit("rotate")] - >> lit('(') - >> double_[_a = _1] >> -lit(',') - >> -(double_ [_b = _1] >> -lit(',') >> double_[_c = _1]) - >> lit(')') [ rotate_action(_r1, _a,_b,_c)]; - - skewX = no_case[lit("skewX")] >> lit('(') >> double_ [ skew_action(_r1, _1, 0.0)] >> lit(')'); - - skewY = no_case[lit("skewY")] >> lit('(') >> double_ [ skew_action(_r1, 0.0, _1)] >> lit(')'); - - } - + // ctor + svg_transform_grammar(); // rules qi::rule start; qi::rule transform_; @@ -173,13 +49,6 @@ struct svg_transform_grammar : qi::grammar, void(TransformType&), SkipType> rotate; qi::rule skewX; qi::rule skewY; - - // actions - function matrix_action; - function rotate_action; - function translate_action; - function scale_action; - function skew_action; }; }} diff --git a/include/mapnik/svg/svg_transform_grammar_impl.hpp b/include/mapnik/svg/svg_transform_grammar_impl.hpp new file mode 100644 index 000000000..464e0a556 --- /dev/null +++ b/include/mapnik/svg/svg_transform_grammar_impl.hpp @@ -0,0 +1,167 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2015 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 + * + *****************************************************************************/ + +// mapnik +#include +// agg +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace svg { + +using namespace boost::spirit; +using namespace boost::fusion; +using namespace boost::phoenix; + +inline double deg2rad(double d) +{ + return M_PI * d / 180.0; +} + +struct process_matrix +{ + using result_type = void; + template + void operator () (TransformType & tr, double a, double b, double c, double d, double e, double f) const + { + tr = agg::trans_affine(a,b,c,d,e,f) * tr; + } +}; + +struct process_rotate +{ + using result_type = void; + + template + void operator () (TransformType & tr, T0 a, T1 cx, T2 cy) const + { + if (cx == 0.0 && cy == 0.0) + { + tr = agg::trans_affine_rotation(deg2rad(a)) * tr; + } + else + { + agg::trans_affine t = agg::trans_affine_translation(-cx,-cy); + t *= agg::trans_affine_rotation(deg2rad(a)); + t *= agg::trans_affine_translation(cx, cy); + tr = t * tr; + } + } +}; + +struct process_translate +{ + using result_type = void; + template + void operator () (TransformType & tr, T0 tx, T1 ty) const + { + if (ty) tr = agg::trans_affine_translation(tx,*ty) * tr; + else tr = agg::trans_affine_translation(tx,0.0) * tr; + } +}; + +struct process_scale +{ + using result_type = void; + template + void operator () (TransformType & tr, T0 sx, T1 sy) const + { + if (sy) tr = agg::trans_affine_scaling(sx,*sy) * tr; + else tr = agg::trans_affine_scaling(sx,sx) * tr; + } +}; + + +struct process_skew +{ + using result_type = void; + + template + void operator () (TransformType & tr, T0 skew_x, T1 skew_y) const + { + tr = agg::trans_affine_skewing(deg2rad(skew_x),deg2rad(skew_y)) * tr; + } +}; + +template +svg_transform_grammar::svg_transform_grammar() + : svg_transform_grammar::base_type(start) +{ + qi::_1_type _1; + qi::_2_type _2; + qi::_3_type _3; + qi::_4_type _4; + qi::_5_type _5; + qi::_6_type _6; + qi::_a_type _a; + qi::_b_type _b; + qi::_c_type _c; + qi::_r1_type _r1; + qi::lit_type lit; + qi::double_type double_; + qi::no_case_type no_case; + + // actions + function matrix_action; + function rotate_action; + function translate_action; + function scale_action; + function skew_action; + + start = +transform_(_r1) ; + + transform_ = matrix(_r1) | rotate(_r1) | translate(_r1) | scale(_r1) | rotate(_r1) | skewX(_r1) | skewY (_r1) ; + + matrix = no_case[lit("matrix")] >> lit('(') + >> (double_ >> -lit(',') + >> double_ >> -lit(',') + >> double_ >> -lit(',') + >> double_ >> -lit(',') + >> double_ >> -lit(',') + >> double_)[matrix_action(_r1, _1, _2, _3, _4, _5, _6)] >> lit(')'); + + translate = no_case[lit("translate")] + >> lit('(') >> (double_ >> -lit(',') >> -double_)[translate_action(_r1, _1, _2)] >> lit(')'); + + scale = no_case[lit("scale")] + >> lit('(') >> (double_ >> -lit(',') >> -double_)[scale_action(_r1, _1, _2)] >> lit(')'); + + rotate = no_case[lit("rotate")] + >> lit('(') + >> double_[_a = _1] >> -lit(',') + >> -(double_ [_b = _1] >> -lit(',') >> double_[_c = _1]) + >> lit(')') [ rotate_action(_r1, _a,_b,_c)]; + + skewX = no_case[lit("skewX")] >> lit('(') >> double_ [ skew_action(_r1, _1, 0.0)] >> lit(')'); + + skewY = no_case[lit("skewY")] >> lit('(') >> double_ [ skew_action(_r1, 0.0, _1)] >> lit(')'); + +} + +}} diff --git a/src/svg/svg_path_parser.cpp b/src/svg/svg_path_parser.cpp index f02c73f2b..52f95ef6e 100644 --- a/src/svg/svg_path_parser.cpp +++ b/src/svg/svg_path_parser.cpp @@ -21,14 +21,9 @@ *****************************************************************************/ // mapnik -#include -#include -#include + #include - -// agg -#include "agg_path_storage.h" - +#include // stl #include #include diff --git a/src/svg/svg_points_parser.cpp b/src/svg/svg_points_parser.cpp index 1499fa60e..3e292ba70 100644 --- a/src/svg/svg_points_parser.cpp +++ b/src/svg/svg_points_parser.cpp @@ -22,8 +22,7 @@ // mapnik #include -#include -#include +#include // stl #include #include diff --git a/src/svg/svg_transform_parser.cpp b/src/svg/svg_transform_parser.cpp index a138c55d5..7b90ca4cb 100644 --- a/src/svg/svg_transform_parser.cpp +++ b/src/svg/svg_transform_parser.cpp @@ -21,8 +21,8 @@ *****************************************************************************/ // mapnik -//#include -#include +#include +#include // stl #include #include @@ -42,7 +42,7 @@ bool parse_svg_transform(const char* wkt, TransformType& tr) return qi::phrase_parse(first, last, (g)(boost::phoenix::ref(tr)), skip_type()); } -template MAPNIK_DECL bool parse_svg_transform(const char*, agg::trans_affine&); +template bool MAPNIK_DECL parse_svg_transform(const char*, agg::trans_affine&); } // namespace svg } // namespace mapnik