diff --git a/include/mapnik/transform_expression_grammar_x3_def.hpp b/include/mapnik/transform_expression_grammar_x3_def.hpp index 14244730b..fa150e628 100644 --- a/include/mapnik/transform_expression_grammar_x3_def.hpp +++ b/include/mapnik/transform_expression_grammar_x3_def.hpp @@ -33,30 +33,6 @@ #include #pragma GCC diagnostic pop -// adapt transform nodes -// martrix -BOOST_FUSION_ADAPT_STRUCT(mapnik::matrix_node, - (mapnik::expr_node, a_) - (mapnik::expr_node, b_) - (mapnik::expr_node, c_) - (mapnik::expr_node, d_) - (mapnik::expr_node, e_) - (mapnik::expr_node, f_)) -// translate -BOOST_FUSION_ADAPT_STRUCT(mapnik::translate_node, - (mapnik::expr_node, tx_) - (mapnik::expr_node, ty_)) - -// scale -BOOST_FUSION_ADAPT_STRUCT(mapnik::scale_node, - (mapnik::expr_node, sx_) - (mapnik::expr_node, sy_)) - -// rotate -BOOST_FUSION_ADAPT_STRUCT(mapnik::rotate_node, - (mapnik::expr_node, angle_) - (mapnik::expr_node, cx_) - (mapnik::expr_node, cy_)) // skewX BOOST_FUSION_ADAPT_STRUCT(mapnik::skewX_node, (mapnik::expr_node, angle_)) @@ -94,82 +70,146 @@ inline void move_to(mapnik:: namespace mapnik { namespace grammar { - namespace x3 = boost::spirit::x3; - namespace ascii = boost::spirit::x3::ascii; +namespace x3 = boost::spirit::x3; +namespace ascii = boost::spirit::x3::ascii; - // [http://www.w3.org/TR/SVG/coords.html#TransformAttribute] +// [http://www.w3.org/TR/SVG/coords.html#TransformAttribute] - // The value of the ‘transform’ attribute is a , which - // is defined as a list of transform definitions, which are applied in - // the order provided. The individual transform definitions are - // separated by whitespace and/or a comma. +// The value of the ‘transform’ attribute is a , which +// is defined as a list of transform definitions, which are applied in +// the order provided. The individual transform definitions are +// separated by whitespace and/or a comma. - using x3::double_; - using x3::no_skip; - using x3::no_case; - using x3::lit; +using x3::double_; +using x3::no_skip; +using x3::no_case; +using x3::lit; - // starting rule - transform_expression_grammar_type const transform("transform"); - // rules - x3::rule transform_list_rule("transform list"); - x3::rule transform_node_rule("transform node"); - x3::rule matrix("matrix node"); - x3::rule translate("translate node"); - x3::rule scale("scale node"); - x3::rule rotate("rotate node"); - x3::rule skewX("skew X node"); - x3::rule skewY("skew Y node"); +auto const create_expr_node = [](auto const& ctx) +{ + _val(ctx) = _attr(ctx); +}; - // Import the expression rule - namespace { auto const& expr = expression_grammar(); } +auto const construct_matrix = [] (auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& a = boost::fusion::at>(attr); + auto const& b = boost::fusion::at>(attr); + auto const& c = boost::fusion::at>(attr); + auto const& d = boost::fusion::at>(attr); + auto const& e = boost::fusion::at>(attr); + auto const& f = boost::fusion::at>(attr); + _val(ctx) = mapnik::matrix_node(a, b, c, d, e, f); +}; - // start - auto const transform_def = transform_list_rule; +auto const construct_translate = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& dx = boost::fusion::at>(attr); + auto const& dy = boost::fusion::at>(attr); //optional + _val(ctx) = mapnik::translate_node(dx, dy); +}; - auto const transform_list_rule_def = transform_node_rule % *lit(','); +auto const construct_scale = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& sx = boost::fusion::at>(attr); + auto const& sy = boost::fusion::at>(attr); //optional + _val(ctx) = mapnik::scale_node(sx, sy); +}; - auto const transform_node_rule_def = matrix | translate | scale | rotate | skewX | skewY ; +auto const construct_rotate = [](auto const& ctx) +{ + auto const& attr = _attr(ctx); + auto const& a = boost::fusion::at>(attr); + auto const& sx = boost::fusion::at>(attr); //optional + auto const& sy = boost::fusion::at>(attr); //optional + _val(ctx) = mapnik::rotate_node(a, sx, sy); +}; - // matrix( ) - auto const matrix_def = no_case[lit("matrix")] - > '(' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ')' - ; +// starting rule +transform_expression_grammar_type const transform("transform"); +// rules +x3::rule transform_list_rule("transform list"); +x3::rule transform_node_rule("transform node"); +x3::rule matrix("matrix node"); +x3::rule translate("translate node"); +x3::rule scale("scale node"); +x3::rule rotate("rotate node"); +x3::rule skewX("skew X node"); +x3::rule skewY("skew Y node"); +x3::rule expr("Expression"); +x3::rule sep_expr("Separated Expression"); - // translate( []) - auto const translate_def = no_case[lit("translate")] - > '(' > expr > -(',' > expr ) > ')' - ; +// start +auto const transform_def = transform_list_rule; - // scale( []) - auto const scale_def = no_case[lit("scale")] - > '(' > expr > -(',' > expr ) > ')' - ; +auto const transform_list_rule_def = transform_node_rule % *lit(','); - // rotate( [ ]) - auto const rotate_def = no_case[lit("rotate")] - > '(' > expr > -(',' > expr > ',' > expr) > ')' - ; +auto const transform_node_rule_def = matrix | translate | scale | rotate | skewX | skewY ; - // skewX() - auto const skewX_def = no_case[lit("skewX")] - > '(' > expr > ')'; +// number or attribute +auto const atom = x3::rule {} = double_[create_expr_node] + ; +// FIXME - ^ add feature attribute support e.g attr [ _val = construct(_1) ]; - // skewY() - auto const skewY_def = no_case[lit("skewY")] - > '(' > expr > ')'; +auto const sep_atom = x3::rule {} = -lit(',') >> double_[create_expr_node] + ; +auto const expr_def = expression_grammar(); +// Individual arguments in lists containing one or more compound +// expressions are separated by a comma. +auto const sep_expr_def = lit(',') > expr + ; - BOOST_SPIRIT_DEFINE ( - transform, - transform_list_rule, - transform_node_rule, - matrix, - translate, - scale, - rotate, - skewX, - skewY); +// matrix( ) +auto const matrix_def = no_case[lit("matrix")] > '(' + > ((atom >> sep_atom >> sep_atom >> sep_atom >> sep_atom >> sep_atom >> lit(')'))[construct_matrix] + | + (expr > sep_expr > sep_expr > sep_expr > sep_expr > sep_expr > lit(')'))[construct_matrix]) + ; + +// translate( []) +auto const translate_def = no_case[lit("translate")] > lit('(') + > (( atom >> -sep_atom >> lit(')'))[construct_translate] + | + ( expr > -sep_expr > lit(')'))[construct_translate] + ); + +// scale( []) +auto const scale_def = no_case[lit("scale")] > lit('(') + > (( atom >> -sep_atom >> lit(')'))[construct_scale] + | + ( expr > -sep_expr > lit(')'))[construct_scale] + ); + +// rotate( [ ]) +auto const rotate_def = no_case[lit("rotate")] > lit('(') + > ((atom >> -sep_atom >> -sep_atom >> lit(')'))[construct_rotate] + | + (expr > -sep_expr > -sep_expr > lit(')'))[construct_rotate] + ); + +// skewX() +auto const skewX_def = no_case[lit("skewX")] + > '(' > expr > ')'; + +// skewY() +auto const skewY_def = no_case[lit("skewY")] + > '(' > expr > ')'; + +BOOST_SPIRIT_DEFINE ( + expr, + sep_expr, + transform, + transform_list_rule, + transform_node_rule, + matrix, + translate, + scale, + rotate, + skewX, + skewY); }} // ns