From 76bb2d9c018fbb4c94b835da1af3e22a2adf1723 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 4 Mar 2016 13:15:11 +0100 Subject: [PATCH] make `svg_transform_grammar` stateless ref #3343 (https://github.com/mapnik/mapnik/pull/2231) --- include/mapnik/svg/svg_transform_grammar.hpp | 141 +++++++------------ src/svg/svg_transform_parser.cpp | 36 ++--- 2 files changed, 68 insertions(+), 109 deletions(-) diff --git a/include/mapnik/svg/svg_transform_grammar.hpp b/include/mapnik/svg/svg_transform_grammar.hpp index e7cd37853..dedd72125 100644 --- a/include/mapnik/svg/svg_transform_grammar.hpp +++ b/include/mapnik/svg/svg_transform_grammar.hpp @@ -49,108 +49,76 @@ inline double deg2rad(double d) return M_PI * d / 180.0; } -template struct process_matrix { using result_type = void; - explicit process_matrix( TransformType & tr) - :tr_(tr) {} - - void operator () (double a, double b, double c, double d, double e, double f) const + 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_; + tr = agg::trans_affine(a,b,c,d,e,f) * tr; } - - TransformType & tr_; }; -template struct process_rotate { using result_type = void; - explicit process_rotate( TransformType & tr) - :tr_(tr) {} - template - void operator () (T0 a, T1 cx, T2 cy) const + 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_; + 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_; + tr = t * tr; } } - - TransformType & tr_; }; -template struct process_translate { using result_type = void; - explicit process_translate( TransformType & tr) - :tr_(tr) {} - - template - void operator () (T0 tx, T1 ty) const + 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_; + if (ty) tr = agg::trans_affine_translation(tx,*ty) * tr; + else tr = agg::trans_affine_translation(tx,0.0) * tr; } - - TransformType & tr_; }; -template struct process_scale { using result_type = void; - explicit process_scale( TransformType & tr) - :tr_(tr) {} - - template - void operator () (T0 sx, T1 sy) const + 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_; + if (sy) tr = agg::trans_affine_scaling(sx,*sy) * tr; + else tr = agg::trans_affine_scaling(sx,sx) * tr; } - - TransformType & tr_; }; -template struct process_skew { using result_type = void; - explicit process_skew( TransformType & tr) - :tr_(tr) {} - template - void operator () (T0 skew_x, T1 skew_y) const + template + void operator () (TransformType & tr, T0 skew_x, T1 skew_y) const { - tr_ = agg::trans_affine_skewing(deg2rad(skew_x),deg2rad(skew_y)) * tr_; + tr = agg::trans_affine_skewing(deg2rad(skew_x),deg2rad(skew_y)) * tr; } - - TransformType & tr_; }; -template -struct svg_transform_grammar : qi::grammar +template +struct svg_transform_grammar : qi::grammar { - explicit svg_transform_grammar(TransformType & tr) - : svg_transform_grammar::base_type(start), - matrix_action(process_matrix(tr)), - rotate_action(process_rotate(tr)), - translate_action(process_translate(tr)), - scale_action(process_scale(tr)), - skew_action(process_skew(tr)) + svg_transform_grammar() + : svg_transform_grammar::base_type(start) { qi::_1_type _1; qi::_2_type _2; @@ -161,66 +129,57 @@ struct svg_transform_grammar : qi::grammar 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_ ; + start = +transform_(_r1) ; - transform_ = matrix | rotate | translate | scale | rotate | skewX | skewY ; + 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(_1,_2,_3,_4,_5,_6) ] - >> lit(')') - ; + 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(_1,_2) ] - >> lit(')'); + >> lit('(') >> (double_ >> -lit(',') >> -double_)[translate_action(_r1, _1, _2)] >> lit(')'); scale = no_case[lit("scale")] - >> lit('(') - >> (double_ >> -lit(',') - >> -double_ )[ scale_action(_1,_2)] - >> lit(')'); + >> 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(_a,_b,_c)]; + >> lit(')') [ rotate_action(_r1, _a,_b,_c)]; - skewX = no_case[lit("skewX")] >> lit('(') >> double_ [ skew_action(_1, 0.0)] >> lit(')'); + skewX = no_case[lit("skewX")] >> lit('(') >> double_ [ skew_action(_r1, _1, 0.0)] >> lit(')'); - skewY = no_case[lit("skewY")] >> lit('(') >> double_ [ skew_action(0.0, _1)] >> lit(')'); + skewY = no_case[lit("skewY")] >> lit('(') >> double_ [ skew_action(_r1, 0.0, _1)] >> lit(')'); } // rules - qi::rule start; - qi::rule transform_; - qi::rule matrix; - qi::rule translate; - qi::rule scale; - qi::rule, SkipType> rotate; - qi::rule skewX; - qi::rule skewY; + qi::rule start; + qi::rule transform_; + qi::rule matrix; + qi::rule translate; + qi::rule scale; + qi::rule, 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; + function matrix_action; + function rotate_action; + function translate_action; + function scale_action; + function skew_action; }; }} diff --git a/src/svg/svg_transform_parser.cpp b/src/svg/svg_transform_parser.cpp index cd92bef14..a138c55d5 100644 --- a/src/svg/svg_transform_parser.cpp +++ b/src/svg/svg_transform_parser.cpp @@ -21,28 +21,28 @@ *****************************************************************************/ // mapnik -#include +//#include #include // stl #include #include -namespace mapnik { namespace svg { +namespace mapnik { +namespace svg { - template - bool parse_svg_transform(const char * wkt, TransformType & p) - { - using namespace boost::spirit; - using iterator_type = const char *; - using skip_type = ascii::space_type; - // FIXME! - for best performance this needs to be static const - // but for that not to crash the argument needs to be passed to phrase_parse - // rather than the grammar ctor - https://github.com/mapnik/mapnik/pull/2231 - svg_transform_grammar g(p); - iterator_type first = wkt; - iterator_type last = wkt + std::strlen(wkt); - return qi::phrase_parse(first, last, g, skip_type()); - } +template +bool parse_svg_transform(const char* wkt, TransformType& tr) +{ + using namespace boost::spirit; + using iterator_type = const char*; + using skip_type = ascii::space_type; + static const svg_transform_grammar g; + iterator_type first = wkt; + iterator_type last = wkt + std::strlen(wkt); + 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 MAPNIK_DECL bool parse_svg_transform(const char*, agg::trans_affine&); + +} // namespace svg +} // namespace mapnik