From ce0f87fb719a65416a6312084c3540f3a7cf12f5 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 26 Aug 2016 10:09:22 +0100 Subject: [PATCH] merge spirit-x3 --- Makefile | 9 +- SConstruct | 5 +- benchmark/run | 2 +- benchmark/test_expression_parse.cpp | 2 +- deps/agg/include/agg_vpgen_clip_polygon.h | 10 +- deps/agg/include/agg_vpgen_clip_polyline.h | 10 +- include/mapnik/box2d.hpp | 2 +- include/mapnik/box2d_impl.hpp | 46 +- include/mapnik/color.hpp | 7 +- include/mapnik/css_color_grammar.hpp | 67 --- include/mapnik/css_color_grammar_x3.hpp | 55 +++ ..._impl.hpp => css_color_grammar_x3_def.hpp} | 399 ++++++++++------ include/mapnik/datasource.hpp | 4 +- include/mapnik/evaluate_global_attributes.hpp | 4 +- include/mapnik/expression_grammar.hpp | 103 ----- include/mapnik/expression_grammar_impl.hpp | 280 ----------- include/mapnik/expression_grammar_x3.hpp | 51 +++ .../mapnik/expression_grammar_x3_config.hpp | 43 ++ include/mapnik/expression_grammar_x3_def.hpp | 433 ++++++++++++++++++ include/mapnik/expression_node.hpp | 82 +--- .../mapnik/feature_style_processor_impl.hpp | 4 +- include/mapnik/function_call.hpp | 4 +- include/mapnik/grid/grid_renderer.hpp | 4 +- include/mapnik/grid/grid_view.hpp | 4 +- include/mapnik/image_filter.hpp | 8 +- include/mapnik/image_filter_grammar.hpp | 87 ---- include/mapnik/image_filter_grammar_impl.hpp | 141 ------ include/mapnik/image_filter_grammar_x3.hpp | 56 +++ .../mapnik/image_filter_grammar_x3_def.hpp | 261 +++++++++++ include/mapnik/image_filter_types.hpp | 41 +- include/mapnik/json/geometry_grammar.hpp | 2 + include/mapnik/make_unique.hpp | 4 +- include/mapnik/offset_converter.hpp | 22 +- include/mapnik/path.hpp | 4 +- .../mapnik/path_expression_grammar_impl.hpp | 62 --- include/mapnik/path_expression_grammar_x3.hpp | 44 ++ .../mapnik/path_expression_grammar_x3_def.hpp | 63 +++ include/mapnik/quad_tree.hpp | 28 +- include/mapnik/query.hpp | 16 +- include/mapnik/raster.hpp | 4 +- include/mapnik/span_image_filter.hpp | 4 +- .../svg/output/svg_output_attributes.hpp | 4 +- include/mapnik/svg/output/svg_renderer.hpp | 4 +- include/mapnik/text/placements/list.hpp | 4 +- include/mapnik/transform_expression.hpp | 22 +- .../mapnik/transform_expression_grammar.hpp | 66 --- .../transform_expression_grammar_impl.hpp | 128 ------ ...pp => transform_expression_grammar_x3.hpp} | 44 +- .../transform_expression_grammar_x3_def.hpp | 184 ++++++++ include/mapnik/well_known_srs.hpp | 21 +- plugins/input/shape/dbfile.cpp | 14 +- src/agg/process_building_symbolizer.cpp | 1 + src/build.py | 14 +- src/cairo/process_building_symbolizer.cpp | 1 + src/cairo/process_group_symbolizer.cpp | 2 + src/cairo/process_line_pattern_symbolizer.cpp | 2 + src/cairo/process_raster_symbolizer.cpp | 2 + src/color_factory.cpp | 11 +- src/conversions.cpp | 264 ----------- src/conversions_numeric.cpp | 146 ++++++ src/conversions_string.cpp | 162 +++++++ ...r_grammar.cpp => css_color_grammar_x3.cpp} | 16 +- src/dasharray_parser.cpp | 25 +- src/expression.cpp | 24 +- ..._grammar.cpp => expression_grammar_x3.cpp} | 10 +- src/feature_type_style.cpp | 4 +- src/font_engine_freetype.cpp | 1 - ...r_types.cpp => generate_image_filters.cpp} | 18 +- src/grid/process_building_symbolizer.cpp | 1 + ...rammar.cpp => image_filter_grammar_x3.cpp} | 20 +- src/image_options.cpp | 54 +-- src/layer.cpp | 26 +- src/map.cpp | 46 +- src/memory_datasource.cpp | 8 +- src/parse_image_filters.cpp | 54 +++ src/parse_path.cpp | 21 +- src/parse_transform.cpp | 29 +- src/svg/svg_parser.cpp | 150 +++--- src/text/face.cpp | 4 +- src/text/font_feature_settings.cpp | 24 +- src/text/placement_finder.cpp | 1 + src/text/placements/simple.cpp | 38 +- src/text/text_layout.cpp | 1 + src/text/text_properties.cpp | 2 + ...pp => transform_expression_grammar_x3.cpp} | 12 +- src/webp_reader.cpp | 1 + src/wkb.cpp | 2 + src/xml_tree.cpp | 1 + test/unit/color/css_color.cpp | 160 ++++--- 89 files changed, 2418 insertions(+), 1908 deletions(-) delete mode 100644 include/mapnik/css_color_grammar.hpp create mode 100644 include/mapnik/css_color_grammar_x3.hpp rename include/mapnik/{css_color_grammar_impl.hpp => css_color_grammar_x3_def.hpp} (54%) delete mode 100644 include/mapnik/expression_grammar.hpp delete mode 100644 include/mapnik/expression_grammar_impl.hpp create mode 100644 include/mapnik/expression_grammar_x3.hpp create mode 100644 include/mapnik/expression_grammar_x3_config.hpp create mode 100644 include/mapnik/expression_grammar_x3_def.hpp delete mode 100644 include/mapnik/image_filter_grammar.hpp delete mode 100644 include/mapnik/image_filter_grammar_impl.hpp create mode 100644 include/mapnik/image_filter_grammar_x3.hpp create mode 100644 include/mapnik/image_filter_grammar_x3_def.hpp delete mode 100644 include/mapnik/path_expression_grammar_impl.hpp create mode 100644 include/mapnik/path_expression_grammar_x3.hpp create mode 100644 include/mapnik/path_expression_grammar_x3_def.hpp delete mode 100644 include/mapnik/transform_expression_grammar.hpp delete mode 100644 include/mapnik/transform_expression_grammar_impl.hpp rename include/mapnik/{path_expression_grammar.hpp => transform_expression_grammar_x3.hpp} (58%) create mode 100644 include/mapnik/transform_expression_grammar_x3_def.hpp delete mode 100644 src/conversions.cpp create mode 100644 src/conversions_numeric.cpp create mode 100644 src/conversions_string.cpp rename src/{image_filter_grammar.cpp => css_color_grammar_x3.cpp} (74%) rename src/{transform_expression_grammar.cpp => expression_grammar_x3.cpp} (81%) rename src/{image_filter_types.cpp => generate_image_filters.cpp} (66%) rename src/{css_color_grammar.cpp => image_filter_grammar_x3.cpp} (67%) create mode 100644 src/parse_image_filters.cpp rename src/{expression_grammar.cpp => transform_expression_grammar_x3.cpp} (77%) diff --git a/Makefile b/Makefile index 752791b1e..14daf29ae 100755 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ - OS := $(shell uname -s) PYTHON = python @@ -36,10 +35,10 @@ src/json/libmapnik-json.a: src/renderer_common/render_thunk_extractor.os \ src/json/libmapnik-json.a \ src/wkt/libmapnik-wkt.a \ - src/css_color_grammar.os \ - src/expression_grammar.os \ - src/transform_expression_grammar.os \ - src/image_filter_grammar.os \ + src/css_color_grammar_x3.os \ + src/expression_grammar_x3.os \ + src/transform_expression_grammar_x3.os \ + src/image_filter_grammar_x3.os \ src/marker_helpers.os \ src/svg/svg_transform_parser.os \ src/agg/process_line_symbolizer.os \ diff --git a/SConstruct b/SConstruct index 0523e184d..e88e0b373 100644 --- a/SConstruct +++ b/SConstruct @@ -41,7 +41,7 @@ ICU_LIBS_DEFAULT='/usr/' DEFAULT_CC = "cc" DEFAULT_CXX = "c++" -DEFAULT_CXX11_CXXFLAGS = " -std=c++11" +DEFAULT_CXX11_CXXFLAGS = " -std=c++14" DEFAULT_CXX11_LINKFLAGS = "" if sys.platform == 'darwin': # homebrew default @@ -1786,8 +1786,7 @@ if not preconfigured: common_cxx_flags = '-fvisibility=hidden -fvisibility-inlines-hidden -Wall %s %s -ftemplate-depth-300 -Wsign-compare -Wshadow ' % (env['WARNING_CXXFLAGS'], pthread) if 'clang++' in env['CXX']: - common_cxx_flags += ' -Wno-unsequenced -Wtautological-compare -Wheader-hygiene ' - + common_cxx_flags += ' -Wno-unsequenced -Wtautological-compare -Wheader-hygiene -Wc++14-extensions ' if env['DEBUG']: env.Append(CXXFLAGS = common_cxx_flags + '-O0') else: diff --git a/benchmark/run b/benchmark/run index 6a8fdd938..36cda4e92 100755 --- a/benchmark/run +++ b/benchmark/run @@ -24,7 +24,7 @@ run test_getline 30 10000000 #run test_polygon_clipping 10 1000 #run test_polygon_clipping_rendering 10 100 run test_proj_transform1 10 100 -run test_expression_parse 10 1000 +run test_expression_parse 10 10000 run test_face_ptr_creation 10 1000 run test_font_registration 10 100 run test_offset_converter 10 1000 diff --git a/benchmark/test_expression_parse.cpp b/benchmark/test_expression_parse.cpp index 7e399223c..f39fb8e84 100644 --- a/benchmark/test_expression_parse.cpp +++ b/benchmark/test_expression_parse.cpp @@ -1,8 +1,8 @@ #include "bench_framework.hpp" #include +#include #include #include -#include class test : public benchmark::test_case { diff --git a/deps/agg/include/agg_vpgen_clip_polygon.h b/deps/agg/include/agg_vpgen_clip_polygon.h index 4972a390b..7f98538e3 100644 --- a/deps/agg/include/agg_vpgen_clip_polygon.h +++ b/deps/agg/include/agg_vpgen_clip_polygon.h @@ -43,12 +43,12 @@ namespace agg { } - void clip_box(double x1, double y1, double x2, double y2) + void clip_box(double _x1, double _y1, double _x2, double _y2) { - m_clip_box.x1 = x1; - m_clip_box.y1 = y1; - m_clip_box.x2 = x2; - m_clip_box.y2 = y2; + m_clip_box.x1 = _x1; + m_clip_box.y1 = _y1; + m_clip_box.x2 = _x2; + m_clip_box.y2 = _y2; m_clip_box.normalize(); } diff --git a/deps/agg/include/agg_vpgen_clip_polyline.h b/deps/agg/include/agg_vpgen_clip_polyline.h index a2e60fa7b..c7b18c98a 100644 --- a/deps/agg/include/agg_vpgen_clip_polyline.h +++ b/deps/agg/include/agg_vpgen_clip_polyline.h @@ -41,12 +41,12 @@ namespace agg { } - void clip_box(double x1, double y1, double x2, double y2) + void clip_box(double _x1, double _y1, double _x2, double _y2) { - m_clip_box.x1 = x1; - m_clip_box.y1 = y1; - m_clip_box.x2 = x2; - m_clip_box.y2 = y2; + m_clip_box.x1 = _x1; + m_clip_box.y1 = _y1; + m_clip_box.x2 = _x2; + m_clip_box.y2 = _y2; m_clip_box.normalize(); } diff --git a/include/mapnik/box2d.hpp b/include/mapnik/box2d.hpp index 267120111..c6c794c83 100644 --- a/include/mapnik/box2d.hpp +++ b/include/mapnik/box2d.hpp @@ -51,11 +51,11 @@ template class MAPNIK_DECL box2d public: using value_type = T; using box2d_type = box2d; -private: T minx_; T miny_; T maxx_; T maxy_; +private: friend inline void swap(box2d_type & lhs, box2d_type & rhs) { using std::swap; diff --git a/include/mapnik/box2d_impl.hpp b/include/mapnik/box2d_impl.hpp index 7f3e9d1e7..b1c462d16 100644 --- a/include/mapnik/box2d_impl.hpp +++ b/include/mapnik/box2d_impl.hpp @@ -33,24 +33,35 @@ #pragma GCC diagnostic push #include -#include -#include -#include +#include +#include #pragma GCC diagnostic pop // agg #include "agg_trans_affine.h" -BOOST_FUSION_ADAPT_TPL_ADT( +BOOST_FUSION_ADAPT_TPL_STRUCT( (T), (mapnik::box2d)(T), - (T, T, obj.minx(), obj.set_minx(mapnik::safe_cast(val))) - (T, T, obj.miny(), obj.set_miny(mapnik::safe_cast(val))) - (T, T, obj.maxx(), obj.set_maxx(mapnik::safe_cast(val))) - (T, T, obj.maxy(), obj.set_maxy(mapnik::safe_cast(val)))) + (T, minx_), + (T, miny_), + (T, maxx_), + (T, maxy_)) -namespace mapnik +namespace mapnik { namespace detail { namespace { + +template +struct assign { + template + void operator() (Context & ctx) const + { + _val(ctx) = safe_cast(_attr(ctx)); + } +}; +} // anonymous +} // detail + template box2d::box2d() :minx_( std::numeric_limits::max()), @@ -61,13 +72,13 @@ box2d::box2d() template box2d::box2d(T minx,T miny,T maxx,T maxy) { - init(minx,miny,maxx,maxy); + init(minx, miny, maxx, maxy); } template box2d::box2d(coord const& c0, coord const& c1) { - init(c0.x,c0.y,c1.x,c1.y); + init(c0.x, c0.y, c1.x, c1.y); } template @@ -350,12 +361,15 @@ void box2d::pad(T padding) template bool box2d::from_string(std::string const& str) { - boost::spirit::qi::lit_type lit; - boost::spirit::qi::double_type double_; - boost::spirit::ascii::space_type space; - bool r = boost::spirit::qi::phrase_parse(str.begin(), + using boost::spirit::x3::lit; + boost::spirit::x3::double_type double_; + boost::spirit::x3::ascii::space_type space; + bool r = boost::spirit::x3::phrase_parse(str.begin(), str.end(), - double_ >> -lit(',') >> double_ >> -lit(',') >> double_ >> -lit(',') >> double_, + double_[detail::assign()] >> -lit(',') >> + double_[detail::assign()] >> -lit(',') >> + double_[detail::assign()] >> -lit(',') >> + double_[detail::assign()], space, *this); return r; diff --git a/include/mapnik/color.hpp b/include/mapnik/color.hpp index 434a9cf21..39bcc2eac 100644 --- a/include/mapnik/color.hpp +++ b/include/mapnik/color.hpp @@ -38,16 +38,15 @@ namespace mapnik { -class MAPNIK_DECL color - : boost::equality_comparable +class MAPNIK_DECL color : boost::equality_comparable { -private: +public: std::uint8_t red_; std::uint8_t green_; std::uint8_t blue_; std::uint8_t alpha_; bool premultiplied_; -public: + // default ctor color() : red_(0xff), diff --git a/include/mapnik/css_color_grammar.hpp b/include/mapnik/css_color_grammar.hpp deleted file mode 100644 index 8fbdeaa6f..000000000 --- a/include/mapnik/css_color_grammar.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************** - * - * 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 - * - *****************************************************************************/ - -#ifndef MAPNIK_CSS_COLOR_GRAMMAR_HPP -#define MAPNIK_CSS_COLOR_GRAMMAR_HPP - -// mapnik -#include -#include -#include - -// boost -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -// stl -#include - -namespace mapnik -{ - -namespace qi = boost::spirit::qi; -namespace ascii = boost::spirit::ascii; - -using ascii_space_type = boost::spirit::ascii::space_type; - -template -struct css_color_grammar : qi::grammar -{ - // ctor - css_color_grammar(); - // rules - qi::uint_parser< unsigned, 16, 2, 2 > hex2 ; - qi::uint_parser< unsigned, 16, 1, 1 > hex1 ; - qi::uint_parser< unsigned, 10, 1, 3 > dec3 ; - qi::rule rgba_color; - qi::rule rgba_percent_color; - qi::rule,color(), ascii_space_type> hsl_percent_color; - qi::rule hex_color; - qi::rule hex_color_small; - qi::rule css_color; -}; - -} - -#endif // MAPNIK_CSS_COLOR_GRAMMAR_HPP diff --git a/include/mapnik/css_color_grammar_x3.hpp b/include/mapnik/css_color_grammar_x3.hpp new file mode 100644 index 000000000..0719e44ec --- /dev/null +++ b/include/mapnik/css_color_grammar_x3.hpp @@ -0,0 +1,55 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#ifndef MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP +#define MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik +{ + +namespace x3 = boost::spirit::x3; + +namespace css_color_grammar +{ + +struct css_color_class; +using css_color_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(css_color_grammar_type); + +}} + + +namespace mapnik +{ +css_color_grammar::css_color_grammar_type color_grammar(); +} + + +#endif // MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP diff --git a/include/mapnik/css_color_grammar_impl.hpp b/include/mapnik/css_color_grammar_x3_def.hpp similarity index 54% rename from include/mapnik/css_color_grammar_impl.hpp rename to include/mapnik/css_color_grammar_x3_def.hpp index 22fa74472..2ad3cfa34 100644 --- a/include/mapnik/css_color_grammar_impl.hpp +++ b/include/mapnik/css_color_grammar_x3_def.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 @@ -20,84 +20,49 @@ * *****************************************************************************/ -// 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 -// boost +// REF: http://www.w3.org/TR/css3-color/ + +#ifndef MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP +#define MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP + +#include +#include +#include + #pragma GCC diagnostic push -#include -#include -#include -#include +#include +#include +#include +#include #pragma GCC diagnostic pop - -BOOST_FUSION_ADAPT_ADT( +BOOST_FUSION_ADAPT_STRUCT ( mapnik::color, - (unsigned, unsigned, obj.red(), obj.set_red(mapnik::safe_cast(val))) - (unsigned, unsigned, obj.green(), obj.set_green(mapnik::safe_cast(val))) - (unsigned, unsigned, obj.blue(), obj.set_blue(mapnik::safe_cast(val))) - (unsigned, unsigned, obj.alpha(), obj.set_alpha(mapnik::safe_cast(val))) + (std::uint8_t, red_) + (std::uint8_t, green_) + (std::uint8_t, blue_) + (std::uint8_t, alpha_) ) -namespace mapnik +namespace mapnik { + +namespace x3 = boost::spirit::x3; + +namespace css_color_grammar { + +using x3::lit; +using x3::uint_parser; +using x3::hex; +using x3::symbols; +using x3::omit; +using x3::attr; +using x3::double_; +using x3::no_case; +using x3::no_skip; + +struct named_colors_ : x3::symbols { -namespace phoenix = boost::phoenix; - -struct percent_conv_impl -{ - using result_type = unsigned; - unsigned operator() (double val) const - { - return safe_cast(std::lround((255.0 * val)/100.0)); - } -}; - -struct alpha_conv_impl -{ - using result_type = unsigned; - unsigned operator() (double val) const - { - return safe_cast(std::lround((255.0 * val))); - } -}; - -struct hsl_conv_impl -{ - using result_type = void; - template - void operator() (T0 & c, T1 h, T2 s, T3 l) const - { - double m1,m2; - // normalize values - h /= 360.0; - s /= 100.0; - l /= 100.0; - - if (l <= 0.5) - { - m2 = l * (s + 1.0); - } - else - { - m2 = l + s - l*s; - } - m1 = l * 2 - m2; - - double r = hue_to_rgb(m1, m2, h + 1.0/3.0); - double g = hue_to_rgb(m1, m2, h); - double b = hue_to_rgb(m1, m2, h - 1.0/3.0); - - c.set_red(safe_cast(std::lround(255.0 * r))); - c.set_green(safe_cast(std::lround(255.0 * g))); - c.set_blue(safe_cast(std::lround(255.0 * b))); - } -}; - -struct named_colors : qi::symbols -{ - named_colors() + named_colors_() { add ("aliceblue", color(240, 248, 255)) @@ -249,77 +214,241 @@ struct named_colors : qi::symbols ("transparent", color(0, 0, 0, 0)) ; } +} named_colors; + +x3::uint_parser hex2; +x3::uint_parser hex1; +x3::uint_parser dec3; + +// starting rule +css_color_grammar_type const css_color("css_color"); +// rules +x3::rule const hex2_color("hex2_color"); +x3::rule const hex1_color("hex1_color"); +x3::rule const rgb_color("rgb_color"); +x3::rule const rgba_color("rgba_color"); +x3::rule const rgb_color_percent("rgb_color_percent"); +x3::rule const rgba_color_percent("rgba_color_percent"); + +struct clip_opacity +{ + static double call(double val) + { + if (val > 1.0) return 1.0; + if (val < 0.0) return 0.0; + return val; + } }; -template -css_color_grammar::css_color_grammar() - : css_color_grammar::base_type(css_color) - +struct percent_converter { - qi::lit_type lit; - qi::_val_type _val; - qi::double_type double_; - qi::_1_type _1; - qi::_a_type _a; - qi::_b_type _b; - qi::_c_type _c; - qi::lexeme_type lexeme; - ascii::no_case_type no_case; - using phoenix::at_c; - // symbols - named_colors named; - // functions - phoenix::function percent_converter; - phoenix::function alpha_converter; - phoenix::function hsl_converter; + static std::uint8_t call(double val) + { + return safe_cast(std::lround((255.0 * val)/100.0)); + } +}; - css_color %= rgba_color - | rgba_percent_color - | hsl_percent_color - | hex_color - | hex_color_small - | no_case[named]; +auto dec_red = [](auto& ctx) +{ + _val(ctx).red_ = _attr(ctx); +}; - hex_color = lexeme[ lit('#') - >> hex2 [ at_c<0>(_val) = _1 ] - >> hex2 [ at_c<1>(_val) = _1 ] - >> hex2 [ at_c<2>(_val) = _1 ] - >>-hex2 [ at_c<3>(_val) = _1 ] ] - ; +auto dec_green = [](auto& ctx) +{ + _val(ctx).green_ = _attr(ctx); +}; - hex_color_small = lexeme[ lit('#') - >> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ] - >> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ] - >> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ] - >>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ] ] - ; +auto dec_blue = [](auto& ctx) +{ + _val(ctx).blue_ = _attr(ctx); +}; - rgba_color = lit("rgb") >> -lit('a') - >> lit('(') - >> dec3 [at_c<0>(_val) = _1] >> ',' - >> dec3 [at_c<1>(_val) = _1] >> ',' - >> dec3 [at_c<2>(_val) = _1] - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) - >> lit(')') - ; +auto opacity = [](auto& ctx) +{ + _val(ctx).alpha_ = uint8_t((255.0 * clip_opacity::call(_attr(ctx))) + 0.5); +}; - rgba_percent_color = lit("rgb") >> -lit('a') - >> lit('(') - >> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ',' - >> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ',' - >> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%' - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) - >> lit(')') - ; +auto percent_red = [] (auto & ctx) +{ + _val(ctx).red_ = percent_converter::call(_attr(ctx)); +}; - hsl_percent_color = lit("hsl") >> -lit('a') - >> lit('(') - >> double_ [ _a = _1] >> ',' // hue 0..360 - >> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100% - >> double_ [ _c = _1] >> '%' // lightness 0..100% - >> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1 - >> lit (')') [ hsl_converter(_val,_a,_b,_c)] - ; +auto percent_green = [] (auto & ctx) +{ + _val(ctx).green_ = percent_converter::call(_attr(ctx)); +}; + +auto percent_blue = [] (auto & ctx) +{ + _val(ctx).blue_ = percent_converter::call(_attr(ctx)); +}; + +auto hex1_red = [](auto& ctx) +{ + _val(ctx).red_ = _attr(ctx) | _attr(ctx) << 4; +}; + +auto hex1_green = [](auto& ctx) +{ + _val(ctx).green_ = _attr(ctx) | _attr(ctx) << 4; +}; + +auto hex1_blue = [](auto& ctx) +{ + _val(ctx).blue_ = _attr(ctx) | _attr(ctx) << 4; +}; + +auto hex1_opacity = [](auto& ctx) +{ + _val(ctx).alpha_ = _attr(ctx) | _attr(ctx) << 4; +}; + +auto hex2_red = [](auto& ctx) +{ + _val(ctx).red_ = _attr(ctx); +}; + +auto hex2_green = [](auto& ctx) +{ + _val(ctx).green_ = _attr(ctx); +}; + +auto hex2_blue = [](auto& ctx) +{ + _val(ctx).blue_ = _attr(ctx); +}; + +auto hex2_opacity = [](auto& ctx) +{ + _val(ctx).alpha_ = _attr(ctx); +}; + +auto hsl_to_rgba = [] (auto& ctx) +{ + double h = std::get<0>(_attr(ctx)); + double s = std::get<1>(_attr(ctx)); + double l = std::get<2>(_attr(ctx)); + double m1; + double m2; + // normalise values + h /= 360.0; + s /= 100.0; + l /= 100.0; + if (l <= 0.5) + { + m2 = l * (s + 1.0); + } + else + { + m2 = l + s - l*s; + } + m1 = l * 2 - m2; + + double r = hue_to_rgb(m1, m2, h + 1.0/3.0); + double g = hue_to_rgb(m1, m2, h); + double b = hue_to_rgb(m1, m2, h - 1.0/3.0); + uint8_t alpha = uint8_t((255.0 * clip_opacity::call(std::get<3>(_attr(ctx)))) + 0.5); + _val(ctx) = color(safe_cast(std::lround(255.0 * r)), + safe_cast(std::lround(255.0 * g)), + safe_cast(std::lround(255.0 * b)), + alpha); +}; + +auto const hex2_color_def = no_skip[lit('#') + >> hex2[hex2_red] + >> hex2[hex2_green] + >> hex2[hex2_blue] + >> (hex2[hex2_opacity] | attr(255)[hex2_opacity])]; + +auto const hex1_color_def = no_skip[lit('#') + >> hex1[hex1_red] + >> hex1[hex1_green] + >> hex1[hex1_blue] + >> (hex1[hex1_opacity] | attr(15)[hex1_opacity])]; + +auto const rgb_color_def = lit("rgb") + >> lit('(') >> dec3[dec_red] + >> lit(',') >> dec3[dec_green] + >> lit(',') >> dec3[dec_blue] + >> attr(255) >> lit(')'); + +auto const rgb_color_percent_def = lit("rgb") + >> lit('(') >> dec3[percent_red] >> lit('%') + >> lit(',') >> dec3[percent_green] >> lit('%') + >> lit(',') >> dec3[percent_blue] >> lit('%') + >> attr(255) >> lit(')'); + +auto const rgba_color_def = lit("rgba") + >> lit('(') >> dec3[dec_red] + >> lit(',') >> dec3[dec_green] + >> lit(',') >> dec3[dec_blue] + >> lit(',') >> double_[opacity] >> lit(')'); + +auto const rgba_color_percent_def = lit("rgba") + >> lit('(') >> dec3[percent_red] >> lit('%') + >> lit(',') >> dec3[percent_green] >> lit('%') + >> lit(',') >> dec3[percent_blue] >> lit('%') + >> lit(',') >> double_[opacity] >> lit(')'); + +auto const hsl_values = x3::rule> {} = + lit("hsl") + >> lit('(') >> dec3 + >> lit(',') >> dec3 >> lit('%') + >> lit(',') >> dec3 >> lit('%') + >> attr(1.0) >> lit(')') + ; + +auto const hsla_values = x3::rule> {} = + lit("hsla") + >> lit('(') >> dec3 + >> lit(',') >> dec3 >> lit('%') + >> lit(',') >> dec3 >> lit('%') + >> lit(',') >> double_ >> lit(')') + ; + +auto const hsl_color = x3::rule {} = hsl_values[hsl_to_rgba]; +auto const hsla_color = x3::rule {} = hsla_values[hsl_to_rgba]; + +auto const css_color_def = + no_case[named_colors] + | + hex2_color + | + hex1_color + | + rgb_color + | + rgba_color + | + rgb_color_percent + | + rgba_color_percent + | + hsl_color + | + hsla_color + ; + +#pragma GCC diagnostic push +#include +BOOST_SPIRIT_DEFINE( + css_color, + hex2_color, + hex1_color, + rgb_color, + rgba_color, + rgb_color_percent, + rgba_color_percent + ); +#pragma GCC diagnostic pop + +} // ns + +css_color_grammar::css_color_grammar_type color_grammar() +{ + return css_color_grammar::css_color; } -} +} //ns mapnik + +#endif //MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/datasource.hpp b/include/mapnik/datasource.hpp index ec14a621c..4f0b17526 100644 --- a/include/mapnik/datasource.hpp +++ b/include/mapnik/datasource.hpp @@ -69,8 +69,8 @@ public: Raster }; - datasource (parameters const& params) - : params_(params) {} + datasource (parameters const& _params) + : params_(_params) {} /*! * @brief Get the configuration parameters of the data source. diff --git a/include/mapnik/evaluate_global_attributes.hpp b/include/mapnik/evaluate_global_attributes.hpp index 3e3d63cbd..cf227821b 100644 --- a/include/mapnik/evaluate_global_attributes.hpp +++ b/include/mapnik/evaluate_global_attributes.hpp @@ -43,8 +43,8 @@ struct evaluate_expression { using value_type = T; - explicit evaluate_expression(Attributes const& attributes) - : attributes_(attributes) {} + explicit evaluate_expression(Attributes const& _attributes) + : attributes_(_attributes) {} value_type operator() (attribute const&) const { diff --git a/include/mapnik/expression_grammar.hpp b/include/mapnik/expression_grammar.hpp deleted file mode 100644 index ad35589bb..000000000 --- a/include/mapnik/expression_grammar.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/***************************************************************************** - * - * 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 - * - *****************************************************************************/ - -#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_HPP -#define MAPNIK_EXPRESSIONS_GRAMMAR_HPP - -// mapnik -#include -#include -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -namespace mapnik -{ -namespace qi = boost::spirit::qi; -namespace standard_wide = boost::spirit::standard_wide; -using standard_wide::space_type; - -template -struct integer_parser -{ - using type = qi::int_parser; -}; - -struct unary_function_types : qi::symbols -{ - unary_function_types(); -}; - -struct binary_function_types : qi::symbols -{ - binary_function_types(); -}; - - -#ifdef __GNUC__ -template -struct MAPNIK_DECL expression_grammar : qi::grammar -#else -template -struct expression_grammar : qi::grammar -#endif -{ - using rule_type = qi::rule; - - explicit expression_grammar(std::string const& encoding = "utf-8"); - - qi::real_parser > strict_double; - typename integer_parser::type int__; - mapnik::transcoder tr_; - - rule_type expr; - rule_type equality_expr; - rule_type cond_expr; - rule_type relational_expr; - rule_type logical_expr; - rule_type additive_expr; - rule_type multiplicative_expr; - rule_type unary_expr; - rule_type not_expr; - rule_type primary_expr; - qi::rule unary_function_expr; - qi::rule binary_function_expr; - qi::rule regex_match_expr; - qi::rule, space_type> regex_replace_expr; - qi::rule attr; - qi::rule global_attr; - qi::rule > quoted_ustring; - qi::rule unquoted_ustring; - qi::rule ustring; - - qi::symbols unesc_char; - qi::rule quote_char; - qi::symbols constant; - unary_function_types unary_func_type; - binary_function_types binary_func_type; - -}; - -} // namespace - -#endif // MAPNIK_EXPRESSIONS_GRAMMAR_HPP diff --git a/include/mapnik/expression_grammar_impl.hpp b/include/mapnik/expression_grammar_impl.hpp deleted file mode 100644 index 5bc85954a..000000000 --- a/include/mapnik/expression_grammar_impl.hpp +++ /dev/null @@ -1,280 +0,0 @@ -/***************************************************************************** - * - * 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 - * - *****************************************************************************/ - -// 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 -#include -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop - -BOOST_FUSION_ADAPT_STRUCT(mapnik::unary_function_call, - (mapnik::unary_function_impl, fun) - (mapnik::unary_function_call::argument_type, arg)) - -BOOST_FUSION_ADAPT_STRUCT(mapnik::binary_function_call, - (mapnik::binary_function_impl, fun) - (mapnik::binary_function_call::argument_type, arg1) - (mapnik::binary_function_call::argument_type, arg2)) - -// fwd declare -namespace mapnik { - struct attribute; - struct geometry_type_attribute; -} - -namespace mapnik -{ - -struct unicode_impl -{ - using result_type = mapnik::value_unicode_string; - explicit unicode_impl(mapnik::transcoder const& tr) - : tr_(tr) {} - - mapnik::value_unicode_string operator()(std::string const& str) const - { - return tr_.transcode(str.c_str()); - } - - mapnik::transcoder const& tr_; -}; - -struct regex_match_impl -{ - using result_type = expr_node; - explicit regex_match_impl(mapnik::transcoder const& tr) - : tr_(tr) {} - - template - expr_node operator() (T0 & node, T1 const& pattern) const; - - mapnik::transcoder const& tr_; -}; - -struct regex_replace_impl -{ - using result_type = expr_node; - explicit regex_replace_impl(mapnik::transcoder const& tr) - : tr_(tr) {} - - template - expr_node operator() (T0 & node, T1 const& pattern, T2 const& format) const; - - mapnik::transcoder const& tr_; -}; - -unary_function_types::unary_function_types() -{ - add - ("sin", sin_impl()) - ("cos", cos_impl()) - ("tan", tan_impl()) - ("atan", atan_impl()) - ("exp", exp_impl()) - ("log", log_impl()) - ("abs", abs_impl()) - ("length",length_impl()) - ; -} - -binary_function_types::binary_function_types() -{ - add - ("min", binary_function_impl(min_impl)) - ("max", binary_function_impl(max_impl)) - ("pow", binary_function_impl(pow_impl)) - ; -} - -template -expr_node regex_match_impl::operator() (T0 & node, T1 const& pattern) const -{ - return regex_match_node(tr_,node,pattern); -} - -template -expr_node regex_replace_impl::operator() (T0 & node, T1 const& pattern, T2 const& format) const -{ - return regex_replace_node(tr_,node,pattern,format); -} - -template -expression_grammar::expression_grammar(std::string const& encoding) - : expression_grammar::base_type(expr), - tr_(encoding) -{ - qi::_1_type _1; - qi::_a_type _a; - qi::_b_type _b; - qi::_r1_type _r1; - qi::no_skip_type no_skip; - qi::_val_type _val; - qi::lit_type lit; - qi::double_type double_; - qi::hex_type hex; - qi::omit_type omit; - qi::alpha_type alpha; - qi::alnum_type alnum; - standard_wide::char_type char_; - standard_wide::no_case_type no_case; - using boost::phoenix::construct; - using boost::phoenix::if_else; - - boost::phoenix::function unicode = unicode_impl(tr_); - boost::phoenix::function regex_match = regex_match_impl(tr_); - boost::phoenix::function regex_replace = regex_replace_impl(tr_); - - constant.add - ("null", mapnik::value_null()) - ("false", mapnik::value_bool(false)) - ("true", mapnik::value_bool(true)) - ("point", mapnik::value_integer(1)) - ("linestring", mapnik::value_integer(2)) - ("polygon", mapnik::value_integer(3)) - ("collection", mapnik::value_integer(4)) - ("pi", mapnik::value_double(3.1415926535897932384626433832795)) - ("deg_to_rad", mapnik::value_double(0.017453292519943295769236907684886)) - ("rad_to_deg", mapnik::value_double(57.295779513082320876798154814105)) - ; - - expr = logical_expr [_val = _1] - //| ustring [_val = unicode(_1)] - ; - - logical_expr = not_expr [_val = _1] - >> - *( ( ( lit("and") | lit("&&")) >> not_expr [_val && _1] ) - | (( lit("or") | lit("||")) >> not_expr [_val || _1]) - ) - ; - - not_expr = - cond_expr [_val = _1 ] - | ((lit("not") | lit('!')) >> cond_expr [ _val = !_1 ]) - ; - - cond_expr = equality_expr [_val = _1] | additive_expr [_val = _1] - ; - - equality_expr = - relational_expr [_val = _1] - >> *( ( (lit("=") | lit("eq") | lit("is")) >> relational_expr [_val == _1]) - | (( lit("!=") | lit("<>") | lit("neq") ) >> relational_expr [_val != _1]) - ) - ; - - regex_match_expr = lit(".match") - >> lit('(') - >> quoted_ustring [_val = _1] - >> lit(')') - ; - - regex_replace_expr = - lit(".replace") - >> lit('(') - >> quoted_ustring [_a = _1] - >> lit(',') - >> quoted_ustring [_b = _1] - >> lit(')') [_val = regex_replace(_r1,_a,_b)] - ; - - relational_expr = additive_expr[_val = _1] - >> - *( ( (lit("<=") | lit("le") ) >> additive_expr [ _val <= _1 ]) - | ( (lit('<') | lit("lt") ) >> additive_expr [ _val < _1 ]) - | ( (lit(">=") | lit("ge") ) >> additive_expr [ _val >= _1 ]) - | ( (lit('>') | lit("gt") ) >> additive_expr [ _val > _1 ]) - ) - ; - - additive_expr = multiplicative_expr [_val = _1] - >> * ( '+' >> multiplicative_expr[_val += _1] - | '-' >> multiplicative_expr[_val -= _1] - ) - ; - - multiplicative_expr = unary_expr [_val = _1] - >> *( '*' >> unary_expr [_val *= _1] - | '/' >> unary_expr [_val /= _1] - | '%' >> unary_expr [_val %= construct(_1)] //needed by clang++ with -std=c++11 - | regex_match_expr[_val = regex_match(_val, _1)] - | regex_replace_expr(_val) [_val = _1] - ) - ; - - unary_function_expr = unary_func_type >> '(' > logical_expr > ')' - ; - - binary_function_expr = binary_func_type >> '(' > logical_expr > ',' - > logical_expr > ')' - ; - - unary_expr = primary_expr [_val = _1] - | '+' >> primary_expr [_val = _1] - | '-' >> primary_expr [_val = -_1] - ; - - primary_expr = strict_double [_val = _1] - | int__[_val = _1] - | no_case[constant] [_val = _1] - | quoted_ustring [_val = unicode(_1)] - | attr [if_else(_1 == "mapnik::geometry_type", - _val = construct(), - _val = construct(_1))] - | global_attr [_val = construct( _1 )] - | unary_function_expr [_val = _1] - | binary_function_expr [_val = _1] - | '(' > logical_expr [_val = _1 ] > ')' - // TODO: this is a backward compatibility hack to allow unquoted strings - | unquoted_ustring [_val = unicode(_1)] - // ^ https://github.com/mapnik/mapnik/pull/3389 - ; - - unesc_char.add("\\a", '\a')("\\b", '\b')("\\f", '\f')("\\n", '\n') - ("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\') - ("\\\'", '\'')("\\\"", '\"') - ; - - ustring %= no_skip[alpha >> *alnum]; - quote_char %= char_('\'') | char_('"'); - quoted_ustring %= omit[quote_char[_a = _1]] - >> *(unesc_char | "\\x" >> hex | (char_ - lit(_a))) - >> lit(_a); - unquoted_ustring %= no_skip[alpha >> *alnum] - lit("not"); - attr %= '[' >> no_skip[+~char_(']')] >> ']'; - global_attr %= '@' >> no_skip[alpha >> * (alnum | char_('-'))]; - -} - -} diff --git a/include/mapnik/expression_grammar_x3.hpp b/include/mapnik/expression_grammar_x3.hpp new file mode 100644 index 000000000..889211939 --- /dev/null +++ b/include/mapnik/expression_grammar_x3.hpp @@ -0,0 +1,51 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP +#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +struct transcoder_tag; +struct expression_class; // top-most ID +using expression_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(expression_grammar_type); + +}} + + +namespace mapnik +{ +grammar::expression_grammar_type expression_grammar(); +} + + +#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP diff --git a/include/mapnik/expression_grammar_x3_config.hpp b/include/mapnik/expression_grammar_x3_config.hpp new file mode 100644 index 000000000..402fdd6b3 --- /dev/null +++ b/include/mapnik/expression_grammar_x3_config.hpp @@ -0,0 +1,43 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP +#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP + +#include +#include +#include + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using phrase_context_type = x3::phrase_parse_context::type; + +// define combined context +using context_type = x3::with_context const, + phrase_context_type>::type; + +}} + +#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP diff --git a/include/mapnik/expression_grammar_x3_def.hpp b/include/mapnik/expression_grammar_x3_def.hpp new file mode 100644 index 000000000..0ef8fe960 --- /dev/null +++ b/include/mapnik/expression_grammar_x3_def.hpp @@ -0,0 +1,433 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#ifndef MAPNIK_EXPRESSIONS_GRAMMAR_X3_DEF_HPP +#define MAPNIK_EXPRESSIONS_GRAMMAR_X3_DEF_HPP + +#include +#include +#include +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#include +#pragma GCC diagnostic pop + +BOOST_FUSION_ADAPT_STRUCT(mapnik::unary_function_call, + (mapnik::unary_function_impl, fun) + (mapnik::unary_function_call::argument_type, arg)) + +BOOST_FUSION_ADAPT_STRUCT(mapnik::binary_function_call, + (mapnik::binary_function_impl, fun) + (mapnik::binary_function_call::argument_type, arg1) + (mapnik::binary_function_call::argument_type, arg2)) + + +namespace mapnik { namespace grammar { + + namespace x3 = boost::spirit::x3; + namespace ascii = boost::spirit::x3::ascii; + using ascii::char_; + using ascii::string; + using x3::lit; + using x3::double_; + using x3::int_; + using x3::bool_; + using x3::_attr; + using x3::_val; + using x3::no_skip; + using x3::lexeme; + using x3::no_case; + using x3::alpha; + using x3::alnum; + using x3::hex; + struct transcoder_tag; + + auto do_assign = [] (auto & ctx) + { + _val(ctx) = std::move(_attr(ctx)); + }; + + auto do_negate = [] (auto & ctx) + { + _val(ctx) = std::move(unary_node(_attr(ctx))); + }; + + auto do_attribute = [] (auto & ctx) + { + _val(ctx) = std::move(attribute(_attr(ctx))); + }; + + auto do_global_attribute = [] (auto & ctx) + { + _val(ctx) = std::move(global_attribute(_attr(ctx))); + }; + + auto do_geometry_type_attribute = [] (auto & ctx) + { + _val(ctx) = std::move(geometry_type_attribute()); + }; + + auto do_add = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_subt = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_mult = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_div = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_mod = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_unicode = [] (auto & ctx) + { + auto & tr = x3::get(ctx).get(); + _val(ctx) = std::move(tr.transcode(_attr(ctx).c_str())); + }; + + auto do_null = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::value_null()); + }; + + auto do_not = [] (auto & ctx) + { + mapnik::unary_node node(_attr(ctx)); + _val(ctx) = std::move(node); + }; + + auto do_and = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_or = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_equal = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_not_equal = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_less = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_less_equal = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_greater = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + + auto do_greater_equal = [] (auto & ctx) + { + _val(ctx) = std::move(mapnik::binary_node(std::move(_val(ctx)), std::move(_attr(ctx)))); + }; + +// regex + auto do_regex_match = [] (auto & ctx) + { + auto const& tr = x3::get(ctx).get(); + _val(ctx) = std::move(mapnik::regex_match_node(tr, std::move(_val(ctx)) , std::move(_attr(ctx)))); + }; + + auto do_regex_replace = [] (auto & ctx) + { + auto const& tr = x3::get(ctx).get(); + auto const& pattern = std::get<0>(_attr(ctx)); + auto const& format = std::get<1>(_attr(ctx)); + _val(ctx) = mapnik::regex_replace_node(tr, _val(ctx) , pattern, format); + }; + +// mapnik::value_integer + auto const mapnik_int = x3::int_parser(); +// mapnik::value_double + auto const mapnik_double = x3::real_parser>(); +// mapnik::value_bool + struct boolean_ : x3::symbols + { + boolean_() + { + add + ("true", true) + ("false", false) + ; + } + } boolean; + + struct floating_point_constants : x3::symbols + { + floating_point_constants() + { + add + ("pi", 3.1415926535897932384626433832795) + ("deg_to_rad",0.017453292519943295769236907684886) + ("rad_to_deg",57.295779513082320876798154814105) + ; + } + } float_const; + +// unary functions + struct unary_function_types_ : x3::symbols + { + unary_function_types_() + { + add + ("sin", sin_impl()) + ("cos", cos_impl()) + ("tan", tan_impl()) + ("atan", atan_impl()) + ("exp", exp_impl()) + ("log", log_impl()) + ("abs", abs_impl()) + ("length",length_impl()) + ; + } + } unary_func_types ; + + +// binary functions + + struct binary_function_types_ : x3::symbols + { + binary_function_types_() + { + add + ("min", binary_function_impl(min_impl)) + ("max", binary_function_impl(max_impl)) + ("pow", binary_function_impl(pow_impl)) + ; + } + } binary_func_types; + +// geometry types + struct geometry_types_ : x3::symbols + { + geometry_types_() + { + add + ("point", 1) + ("linestring", 2) + ("polygon",3) + ("collection",4) + ; + } + } geometry_type; + + struct unesc_chars_ : x3::symbols + { + unesc_chars_() + { + add + ("\\a", '\a') + ("\\b", '\b') + ("\\f", '\f') + ("\\n", '\n') + ("\\r", '\r') + ("\\t", '\t') + ("\\v", '\v') + ("\\\\", '\\') + ("\\\'", '\'') + ("\\\"", '\"') + ; + } + } unesc_char; + // starting rule + expression_grammar_type const expression("expression"); + // rules + x3::rule const logical_expression("logical expression"); + x3::rule const not_expression("not expression"); + x3::rule const conditional_expression("conditional expression"); + x3::rule const equality_expression("equality expression"); + x3::rule const relational_expression("relational expression"); + x3::rule const additive_expression("additive expression"); + x3::rule const multiplicative_expression("multiplicative expression"); + x3::rule const unary_func_expression("unary function expression"); + x3::rule const binary_func_expression("binary function expression"); + x3::rule const unary_expression("unary expression"); + x3::rule const primary_expression("primary expression"); + x3::rule const regex_match_expression("regex match expression"); + x3::rule > const regex_replace_expression("regex replace expression"); + + // strings + auto const single_quoted_string = x3::rule {} = lit('\'') >> no_skip[*(unesc_char | ("\\x" > hex) | (char_ - '\''))] > '\''; + auto const double_quoted_string = x3::rule {} = lit('"') >> no_skip[*(unesc_char | ("\\x" > hex) | (char_ - '"'))] > '"'; + auto const quoted_string = x3::rule {} = single_quoted_string | double_quoted_string; + + auto const unquoted_ustring = x3::rule {} = no_skip[alpha > *alnum] - lit("not"); + + // start + auto const expression_def = logical_expression [do_assign] + ; + + auto const logical_expression_def = not_expression[do_assign] > + *(((lit("and") | lit("&&")) > not_expression[do_and]) + | + ((lit("or") | lit("||")) > not_expression[do_or])); + + auto const not_expression_def = conditional_expression[do_assign] + | + (lit("not") | lit('!')) > conditional_expression[do_not] + ; + + auto const conditional_expression_def = equality_expression[do_assign] + | + additive_expression[do_assign] + ; + + auto const equality_expression_def = relational_expression[do_assign] > + *( ( ( lit("=") | lit("eq") | lit("is")) > relational_expression [do_equal]) + | (( lit( "!=") | lit("<>") | lit("neq") ) > relational_expression [do_not_equal]) + ); + + auto const relational_expression_def = additive_expression[do_assign] > + *( ( (lit("<=") | lit("le")) > additive_expression [do_less_equal]) + | + ( (lit("<") | lit("lt")) >> additive_expression[do_less]) // allow backtracking to be able to handle '<' and '<>' correctly + | + ( (lit(">=") | lit("ge")) > additive_expression [do_greater_equal]) + | + ( (lit(">") | lit("gt")) > additive_expression [do_greater])); + + + auto const additive_expression_def = multiplicative_expression[do_assign] + > *( ('+' > multiplicative_expression[do_add]) + | + ('-' > multiplicative_expression[do_subt])); + + auto const feature_attr = lexeme['[' > +~char_(']') > ']']; + auto const global_attr = x3::rule {} = lexeme[lit('@') > alpha > *alnum]; + + auto const regex_match_expression_def = lit(".match") > '(' > quoted_string > ')'; + auto const regex_replace_expression_def = lit(".replace") > '(' > quoted_string > ',' > quoted_string > ')'; + auto const multiplicative_expression_def = unary_expression [do_assign] + > *( '*' > unary_expression [do_mult] + | + '/' > unary_expression [do_div] + | + '%' > unary_expression [do_mod] + | + regex_match_expression[do_regex_match] + | + regex_replace_expression[do_regex_replace] + ); + + auto const unary_func_expression_def = unary_func_types > '(' > expression > ')'; + auto const binary_func_expression_def = binary_func_types > '(' > expression > ',' > expression > ')'; + + auto const unary_expression_def = + primary_expression[do_assign] + | + '+' > primary_expression[do_assign] + | + '-' > primary_expression[do_negate] + ; + + auto const primary_expression_def = + mapnik_double[do_assign] + | + mapnik_int[do_assign] + | + no_case[boolean][do_assign] + | + no_case["null"][do_null] + | + no_case[geometry_type][do_assign] + | + float_const[do_assign] + | + quoted_string[do_unicode] + | + lit("[mapnik::geometry_type]")[do_geometry_type_attribute] + | + feature_attr[do_attribute] + | + global_attr[do_global_attribute] + | + unary_func_expression[do_assign] + | + binary_func_expression[do_assign] + | + ('(' > logical_expression[do_assign] > ')') + | + unquoted_ustring[do_unicode] + // ^ https://github.com/mapnik/mapnik/pull/3389 + ; + + BOOST_SPIRIT_DEFINE ( + expression, + logical_expression, + not_expression, + conditional_expression, + equality_expression, + relational_expression, + additive_expression, + regex_match_expression, + regex_replace_expression, + multiplicative_expression, + unary_func_expression, + binary_func_expression, + unary_expression, + primary_expression + ); + + }} + +namespace mapnik +{ +grammar::expression_grammar_type expression_grammar() +{ + return grammar::expression; +} +} + +#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/expression_node.hpp b/include/mapnik/expression_node.hpp index 77c45463a..e0b86ebec 100644 --- a/include/mapnik/expression_node.hpp +++ b/include/mapnik/expression_node.hpp @@ -59,6 +59,9 @@ template <> struct make_op { using type = std::logica template struct unary_node { + unary_node (expr_node && a) + : expr(std::move(a)) {} + unary_node (expr_node const& a) : expr(a) {} @@ -73,6 +76,10 @@ struct unary_node template struct binary_node { + binary_node(expr_node && a, expr_node && b) + : left(std::move(a)), + right(std::move(b)) {} + binary_node(expr_node const& a, expr_node const& b) : left(a), right(b) {} @@ -130,81 +137,6 @@ struct MAPNIK_DECL regex_replace_node std::shared_ptr<_regex_replace_impl> impl_; }; -inline expr_node & operator- (expr_node& expr) -{ - return expr = unary_node(expr); -} - -inline expr_node & operator += ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator -= ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator *= ( expr_node &left , expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator /= ( expr_node &left , expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator %= ( expr_node &left , expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator < ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator <= ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator > ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator >= ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator == ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator != ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator ! (expr_node & expr) -{ - return expr = unary_node(expr); -} - -inline expr_node & operator && ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - -inline expr_node & operator || ( expr_node &left, expr_node const& right) -{ - return left = binary_node(left,right); -} - } diff --git a/include/mapnik/feature_style_processor_impl.hpp b/include/mapnik/feature_style_processor_impl.hpp index 2fea9d8b3..712e0f014 100644 --- a/include/mapnik/feature_style_processor_impl.hpp +++ b/include/mapnik/feature_style_processor_impl.hpp @@ -368,10 +368,10 @@ void feature_style_processor::prepare_layer(layer_rendering_material continue; } - std::vector const& rules = style->get_rules(); + std::vector const& style_rules = style->get_rules(); bool active_rules = false; rule_cache rc; - for(rule const& r : rules) + for(rule const& r : style_rules) { if (r.active(scale_denom)) { diff --git a/include/mapnik/function_call.hpp b/include/mapnik/function_call.hpp index f50829bd6..84344592a 100644 --- a/include/mapnik/function_call.hpp +++ b/include/mapnik/function_call.hpp @@ -47,7 +47,6 @@ struct exp_impl { return std::exp(val.to_double()); } - }; // log @@ -58,7 +57,6 @@ struct log_impl { return std::log(val.to_double()); } - }; // sin @@ -102,7 +100,7 @@ struct abs_impl { value_type operator() (value_type const& val) const { - return std::fabs(val.to_double()); + return std::abs(val.to_double()); } }; diff --git a/include/mapnik/grid/grid_renderer.hpp b/include/mapnik/grid/grid_renderer.hpp index cc689e308..4b6060c69 100644 --- a/include/mapnik/grid/grid_renderer.hpp +++ b/include/mapnik/grid/grid_renderer.hpp @@ -124,9 +124,9 @@ public: return pixmap_.painted(); } - void painted(bool painted) + void painted(bool _painted) { - pixmap_.painted(painted); + pixmap_.painted(_painted); } inline eAttributeCollectionPolicy attribute_collection_policy() const diff --git a/include/mapnik/grid/grid_view.hpp b/include/mapnik/grid/grid_view.hpp index 80c539f53..80d459b78 100644 --- a/include/mapnik/grid/grid_view.hpp +++ b/include/mapnik/grid/grid_view.hpp @@ -52,7 +52,7 @@ public: hit_grid_view(unsigned x, unsigned y, unsigned width, unsigned height, - T const& data, + T const& _data, std::string const& key, std::string const& id_name, std::set const& names, @@ -63,7 +63,7 @@ public: y_(y), width_(width), height_(height), - data_(data), + data_(_data), key_(key), id_name_(id_name), names_(names), diff --git a/include/mapnik/image_filter.hpp b/include/mapnik/image_filter.hpp index a96d4cd9d..c8870d412 100644 --- a/include/mapnik/image_filter.hpp +++ b/include/mapnik/image_filter.hpp @@ -681,7 +681,7 @@ void apply_filter(Src & src, scale_hsla const& transform) } template -void color_blind_filter(Src & src, ColorBlindFilter const& op) +void apply_color_blind_filter(Src & src, ColorBlindFilter const& op) { using namespace boost::gil; rgba8_view_t src_view = rgba8_view(src); @@ -804,19 +804,19 @@ void color_blind_filter(Src & src, ColorBlindFilter const& op) template void apply_filter(Src & src, color_blind_protanope const& op) { - color_blind_filter(src, op); + apply_color_blind_filter(src, op); } template void apply_filter(Src & src, color_blind_deuteranope const& op) { - color_blind_filter(src, op); + apply_color_blind_filter(src, op); } template void apply_filter(Src & src, color_blind_tritanope const& op) { - color_blind_filter(src, op); + apply_color_blind_filter(src, op); } template diff --git a/include/mapnik/image_filter_grammar.hpp b/include/mapnik/image_filter_grammar.hpp deleted file mode 100644 index ca96116eb..000000000 --- a/include/mapnik/image_filter_grammar.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** - * - * 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 - * - *****************************************************************************/ - -#ifndef MAPNIK_IMAGE_FILTER_GRAMMAR_HPP -#define MAPNIK_IMAGE_FILTER_GRAMMAR_HPP - -// mapnik -#include -#include -#include - -#pragma GCC diagnostic push -#include -#include -#pragma GCC diagnostic pop - -// stl -#include - -namespace mapnik { - -namespace filter { -struct color_stop; -struct colorize_alpha; -} - -namespace qi = boost::spirit::qi; - -struct percent_offset_impl -{ - using result_type = double; - double operator() (double val) const - { - double result = std::abs(val/100.0); - if (result > 1.0) result = 1.0; - return result; - } -}; - - -template -struct image_filter_grammar : - qi::grammar -{ - using alternative_type = qi::rule; - - image_filter_grammar(); - - qi::rule start; - qi::rule> filter; - qi::rule no_args; - qi::symbols alternatives; - qi::uint_parser< unsigned, 10, 1, 3 > radius_; - css_color_grammar css_color_; - qi::rule color_stop_; - qi::rule color_stop_offset; - -private: - alternative_type & add(std::string const& symbol); - static constexpr unsigned max_alternatives = 16; - unsigned num_alternatives = 0; - alternative_type alternative_storage[max_alternatives]; -}; - -} // namespace mapnik - -#endif // MAPNIK_IMAGE_FILTER_GRAMMAR_HPP diff --git a/include/mapnik/image_filter_grammar_impl.hpp b/include/mapnik/image_filter_grammar_impl.hpp deleted file mode 100644 index bf1770083..000000000 --- a/include/mapnik/image_filter_grammar_impl.hpp +++ /dev/null @@ -1,141 +0,0 @@ -/***************************************************************************** - * - * 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 -#pragma GCC diagnostic pop - -namespace { // internal - - BOOST_PHOENIX_ADAPT_FUNCTION( - typename std::remove_reference::type, ovo, // = optional_value_or - boost::get_optional_value_or, 2) - -} // namespace internal - -namespace mapnik { - -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; - -template -image_filter_grammar::image_filter_grammar() - : image_filter_grammar::base_type(start) -{ - qi::lit_type lit; - qi::_val_type _val; - 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::_7_type _7; - qi::_8_type _8; - qi::_a_type _a; - qi::attr_type attr; - qi::double_type double_; - qi::hold_type hold; - qi::omit_type omit; - using phoenix::push_back; - using phoenix::construct; - - // functions - phoenix::function percent_offset; - - start = -(filter % *lit(',')) - ; - - filter = omit[alternatives[_a = _1]] >> qi::lazy(*_a) - ; - - add("emboss") = no_args >> attr(construct()); - add("blur") = no_args >> attr(construct()); - add("gray") = no_args >> attr(construct()); - add("edge-detect") = no_args >> attr(construct()); - add("sobel") = no_args >> attr(construct()); - add("sharpen") = no_args >> attr(construct()); - add("x-gradient") = no_args >> attr(construct()); - add("y-gradient") = no_args >> attr(construct()); - add("invert") = no_args >> attr(construct()); - add("color-blind-protanope") = no_args >> attr(construct()); - add("color-blind-deuteranope") = no_args >> attr(construct()); - add("color-blind-tritanope") = no_args >> attr(construct()); - - add("agg-stack-blur") = - (lit('(') >> radius_ >> -( lit(',') >> radius_ ) >> lit(')')) - [push_back(_val, construct(_1, ovo(_2, _1)))] - | - no_args - [push_back(_val, construct(1, 1))] - ; - - add("scale-hsla") = - (lit('(') - >> double_ >> lit(',') >> double_ >> lit(',') - >> double_ >> lit(',') >> double_ >> lit(',') - >> double_ >> lit(',') >> double_ >> lit(',') - >> double_ >> lit(',') >> double_ >> lit(')')) - [push_back(_val, construct(_1,_2,_3,_4,_5,_6,_7,_8))] - ; - - add("colorize-alpha") = qi::as() - [lit('(') >> color_stop_ % lit(',') >> lit(')')] - [push_back(_val, _1)] - ; - - color_stop_ = (css_color_ >> -color_stop_offset) - [_val = construct(_1, ovo(_2, 0.0))] - ; - - color_stop_offset = double_[_val = _1] - >> -lit('%')[_val = percent_offset(_val)] - ; - - add("color-to-alpha") = - hold[lit('(') >> css_color_ >> lit(')')] - [push_back(_val, construct(_1))] - ; - - no_args = -(lit('(') >> lit(')')); -} - -template -auto image_filter_grammar::add(std::string const& symbol) - -> alternative_type & -{ - if (num_alternatives >= max_alternatives) - { - throw std::length_error("too many alternatives in image_filter_grammar"); - } - - alternative_storage[num_alternatives].name(symbol); - alternatives.add(symbol, &alternative_storage[num_alternatives]); - return alternative_storage[num_alternatives++]; -} - -} // namespace mapnik diff --git a/include/mapnik/image_filter_grammar_x3.hpp b/include/mapnik/image_filter_grammar_x3.hpp new file mode 100644 index 000000000..ca452009e --- /dev/null +++ b/include/mapnik/image_filter_grammar_x3.hpp @@ -0,0 +1,56 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#ifndef MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP +#define MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP + +//#include +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik +{ + +namespace x3 = boost::spirit::x3; + +namespace image_filter +{ + +struct image_filter_class; +using image_filter_grammar_type = x3::rule >; + +BOOST_SPIRIT_DECLARE(image_filter_grammar_type); + + +}} + +namespace mapnik { + +image_filter::image_filter_grammar_type image_filter_grammar(); + +} + +#endif // MAPNIK_IMAGE_FILTER_GRAMMAR_X3_HPP diff --git a/include/mapnik/image_filter_grammar_x3_def.hpp b/include/mapnik/image_filter_grammar_x3_def.hpp new file mode 100644 index 000000000..2d680bea1 --- /dev/null +++ b/include/mapnik/image_filter_grammar_x3_def.hpp @@ -0,0 +1,261 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#ifndef MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP +#define MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP + + +#include +#include +#include + +#pragma GCC diagnostic push +#include +#include +#include +#include +#include // spirit support +#pragma GCC diagnostic pop + + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::filter::scale_hsla, + (double, h0) + (double, h1) + (double, s0) + (double, s1) + (double, l0) + (double, l1) + (double, a0) + (double, a1) +) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::filter::color_stop, + (mapnik::color, color ) + (double, offset) +) + +BOOST_FUSION_ADAPT_STRUCT( + mapnik::filter::color_to_alpha, + (mapnik::color, color) +) + +namespace mapnik { + +namespace x3 = boost::spirit::x3; + +namespace image_filter { + +using x3::lit; +using x3::uint_parser; +using x3::hex; +using x3::symbols; +using x3::omit; +using x3::attr; +using x3::double_; +using x3::no_case; +using x3::no_skip; +using x3::char_; + +auto push_back = [](auto& ctx) +{ + _val(ctx).push_back(_attr(ctx)); + +}; + +auto set_rx_ry = [](auto & ctx) +{ + _val(ctx).rx = _val(ctx).ry = _attr(ctx); +}; + +auto set_ry = [](auto & ctx) +{ + _val(ctx).ry = _attr(ctx); +}; + +auto offset_value = [](auto & ctx) +{ + _val(ctx) = _attr(ctx); +}; + +auto percent = [](auto & ctx) +{ + double val = std::abs(_val(ctx)/100.0); + if (val > 1.0) val = 1.0; + _val(ctx) = val; +}; + +x3::uint_parser radius; + +// Import the expression rule +namespace { auto const& css_color = color_grammar(); } + +// starting rule +image_filter_grammar_type const start("start"); +// rules +x3::rule const filter("filter"); + +x3::rule const emboss_filter("emboss"); +x3::rule const blur_filter("blur"); +x3::rule const gray_filter("gray"); +x3::rule const edge_detect_filter("edge-detect"); +x3::rule const sobel_filter("sobel"); +x3::rule const sharpen_filter("sharpen"); +x3::rule const x_gradient_filter("x-gradient"); +x3::rule const y_gradient_filter("y-gradient"); +x3::rule const invert_filter("invert"); +x3::rule const color_blind_protanope_filter("color-blind-protanope"); +x3::rule const color_blind_deuteranope_filter("color-blind-deuteranope"); +x3::rule const color_blind_tritanope_filter("color-blind-tritanope"); + +x3::rule const agg_blur_filter("agg blur filter"); +x3::rule const scale_hsla_filter("scale-hsla"); +x3::rule const colorize_alpha_filter("colorize-alpha"); +x3::rule const color_stop("color-stop"); +x3::rule const offset("color-stop-offset"); +x3::rule const color_to_alpha_filter("color-to-alpha"); + +auto const no_args = -(lit('(') > lit(')')); + +auto const start_def = -(filter[push_back] % *lit(',')); + +auto const filter_def = (emboss_filter + | + blur_filter + | + gray_filter + | + edge_detect_filter + | + sobel_filter + | + sharpen_filter + | + x_gradient_filter + | + y_gradient_filter + | + invert_filter + | + color_blind_protanope_filter + | + color_blind_deuteranope_filter + | + color_blind_tritanope_filter + | + agg_blur_filter + | + scale_hsla_filter + | + colorize_alpha_filter + | + color_to_alpha_filter + ) + ; + +auto const emboss_filter_def = lit("emboss") > no_args; + +auto const blur_filter_def = lit("blur") > no_args; + +auto const gray_filter_def = lit("gray") > no_args; + +auto const edge_detect_filter_def = lit("edge-detect") > no_args; + +auto const sobel_filter_def = lit("sobel") > no_args; + +auto const sharpen_filter_def = lit("sharpen") > no_args; + +auto const x_gradient_filter_def = lit("x-gradient") > no_args; + +auto const y_gradient_filter_def = lit("y-gradient") > no_args; + +auto const invert_filter_def = lit("invert") > no_args; + +auto const color_blind_protanope_filter_def = lit("color-blind-protanope") > no_args; + +auto const color_blind_deuteranope_filter_def = lit("color-blind-deuteranope") > no_args; + +auto const color_blind_tritanope_filter_def = lit("color-blind-tritanope") > no_args; + +auto const agg_blur_filter_def = lit("agg-stack-blur") + > -(lit('(') > -(radius[set_rx_ry] > -(lit(',') > radius[set_ry])) > lit(')')); + +auto const scale_hsla_filter_def = lit("scale-hsla") > lit('(') + > double_ > ',' + > double_ > ',' + > double_ > ',' + > double_ > ',' + > double_ > ',' + > double_ > ',' + > double_ > ',' + > double_ > ')' ; + + +auto const offset_def = double_[offset_value] > -lit('%')[percent]; +auto const color_stop_def = css_color > -offset; + +auto const colorize_alpha_filter_def = lit("colorize-alpha") + > lit('(') + > color_stop > *(lit(',') > color_stop) + > lit(')') ; + +auto const color_to_alpha_filter_def = lit("color-to-alpha") > lit('(') + > -css_color > lit(')'); + +#pragma GCC diagnostic push +#include + +BOOST_SPIRIT_DEFINE( + start, + filter, + emboss_filter, + blur_filter, + gray_filter, + edge_detect_filter, + sobel_filter, + sharpen_filter, + x_gradient_filter, + y_gradient_filter, + invert_filter, + agg_blur_filter, + color_blind_protanope_filter, + color_blind_deuteranope_filter, + color_blind_tritanope_filter, + scale_hsla_filter, + colorize_alpha_filter, + color_stop, + offset, + color_to_alpha_filter + ); +#pragma GCC diagnostic pop + +} // image_filter + +image_filter::image_filter_grammar_type image_filter_grammar() +{ + return image_filter::start; +} + +} //ns mapnik + +#endif //MAPNIK_IMAGE_FILTER_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/image_filter_types.hpp b/include/mapnik/image_filter_types.hpp index 7e04df87a..ba36aa5eb 100644 --- a/include/mapnik/image_filter_types.hpp +++ b/include/mapnik/image_filter_types.hpp @@ -56,32 +56,41 @@ struct y_gradient : image_filter_base {}; struct invert : image_filter_base {}; // http://vision.psychol.cam.ac.uk/jdmollon/papers/colourmaps.pdf -struct color_blind_protanope : image_filter_base +struct color_blind_filter : image_filter_base { - const double x = 0.7465; - const double y = 0.2535; - const double m = 1.273463; - const double yint = -0.073894; + color_blind_filter(double x_, double y_, double m_, double yint_) + : x(x_), y(y_), m(m_), yint(yint_) {} + double x; + double y; + double m; + double yint; }; -struct color_blind_deuteranope : image_filter_base +struct color_blind_protanope : color_blind_filter { - const double x = 1.4; - const double y = -0.4; - const double m = 0.968437; - const double yint = 0.003331; + color_blind_protanope() + : color_blind_filter(0.7465, 0.2535, 1.273463, -0.073894) {} }; -struct color_blind_tritanope : image_filter_base +struct color_blind_deuteranope : color_blind_filter { - const double x = 0.1748; - const double y = 0.0; - const double m = 0.062921; - const double yint = 0.292119; + color_blind_deuteranope() + : color_blind_filter(1.4, -0.4, 0.968437, 0.003331) {} }; +struct color_blind_tritanope : color_blind_filter +{ + color_blind_tritanope() + : color_blind_filter(0.1748, 0.0, 0.062921, 0.292119) {} +}; + + struct agg_stack_blur : image_filter_base { + agg_stack_blur() + : rx(1), ry(1) {} + agg_stack_blur(unsigned r) + : rx(r), ry(r) {} agg_stack_blur(unsigned rx_, unsigned ry_) : rx(rx_),ry(ry_) {} inline bool operator==(agg_stack_blur const& rhs) const @@ -94,6 +103,7 @@ struct agg_stack_blur : image_filter_base struct color_to_alpha : image_filter_base { + color_to_alpha() {} color_to_alpha(mapnik::color const& c) : color(c) {} inline bool operator==(color_to_alpha const& rhs) const @@ -105,6 +115,7 @@ struct color_to_alpha : image_filter_base struct scale_hsla : image_filter_base { + scale_hsla() {} scale_hsla(double _h0, double _h1, double _s0, double _s1, double _l0, double _l1, diff --git a/include/mapnik/json/geometry_grammar.hpp b/include/mapnik/json/geometry_grammar.hpp index fc0d3a43d..e4b60fd4f 100644 --- a/include/mapnik/json/geometry_grammar.hpp +++ b/include/mapnik/json/geometry_grammar.hpp @@ -36,6 +36,8 @@ #include #pragma GCC diagnostic pop +#include + namespace mapnik { namespace json { namespace qi = boost::spirit::qi; diff --git a/include/mapnik/make_unique.hpp b/include/mapnik/make_unique.hpp index f6fd4a230..577c0cf78 100644 --- a/include/mapnik/make_unique.hpp +++ b/include/mapnik/make_unique.hpp @@ -23,11 +23,11 @@ #ifndef MAPNIK_MAKE_UNIQUE_HPP #define MAPNIK_MAKE_UNIQUE_HPP -#include - // http://stackoverflow.com/questions/14131454/visual-studio-2012-cplusplus-and-c-11 #if defined(_MSC_VER) && _MSC_VER < 1800 || !defined(_MSC_VER) && __cplusplus <= 201103L +#include + namespace std { // C++14 backfill from http://herbsutter.com/gotw/_102/ diff --git a/include/mapnik/offset_converter.hpp b/include/mapnik/offset_converter.hpp index 310ed808a..0f0d1ceb4 100644 --- a/include/mapnik/offset_converter.hpp +++ b/include/mapnik/offset_converter.hpp @@ -269,7 +269,7 @@ private: if (position < -1e-6) return -1; return 0; } - + void displace2(vertex2d & v1, vertex2d const& v0, vertex2d const& v2, double a, double b) const { double sa = offset_ * std::sin(a); @@ -284,14 +284,14 @@ private: double abs_hcasa = std::abs(hcasa); double abs_hsa = std::abs(hsa); double abs_hca = std::abs(hca); - - vertex2d v_tmp(vertex2d::no_init); + + vertex2d v_tmp(vertex2d::no_init); v_tmp.x = v1.x - sa - hca; v_tmp.y = v1.y + ca - hsa; v_tmp.cmd = v1.cmd; - + int same = point_line_position(v0, v2, v_tmp)*point_line_position(v0, v2, v1); - + if (same >= 0 && std::abs(h) < 10) { v1.x = v_tmp.x; @@ -314,14 +314,14 @@ private: v1.y = v1.y + ca - hsa; } else - { + { if (abs_hsaca*abs_hsaca + abs_hcasa*abs_hcasa > abs_offset*abs_offset) { double d = (abs_hsaca*abs_hsaca + abs_hcasa*abs_hcasa); d = d < 1e-6 ? 1. : d; double scale = (abs_offset*abs_offset)/d; v1.x = v1.x + hcasa*scale; - v1.y = v1.y + hsaca*scale; + v1.y = v1.y + hsaca*scale; } else { @@ -330,8 +330,7 @@ private: } } } - - + status init_vertices() { if (status_ != initial) // already initialized @@ -482,8 +481,9 @@ private: } start_v2.x = v2.x; start_v2.y = v2.y; + vertex2d tmp_prev(vertex2d::no_init); - + while (i < points.size()) { v1 = v2; @@ -576,7 +576,7 @@ private: tmp_prev.cmd = v1.cmd; tmp_prev.x = v1.x; tmp_prev.y = v1.y; - + if (v1.cmd == SEG_MOVETO) { if (bulge_steps == 0) diff --git a/include/mapnik/path.hpp b/include/mapnik/path.hpp index 6d253466d..8d2e4f6f4 100644 --- a/include/mapnik/path.hpp +++ b/include/mapnik/path.hpp @@ -70,9 +70,9 @@ public: return static_cast(type_ >> geometry_bits); } - void set_type(types type) + void set_type(types _type) { - type_ = type; + type_ = _type; } container_type const& data() const diff --git a/include/mapnik/path_expression_grammar_impl.hpp b/include/mapnik/path_expression_grammar_impl.hpp deleted file mode 100644 index 22002bf33..000000000 --- a/include/mapnik/path_expression_grammar_impl.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/***************************************************************************** - * - * 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 -#pragma GCC diagnostic pop - -namespace mapnik -{ - -template -path_expression_grammar::path_expression_grammar() - : path_expression_grammar::base_type(expr) -{ - standard_wide::char_type char_; - qi::_1_type _1; - qi::_val_type _val; - qi::lit_type lit; - qi::lexeme_type lexeme; - using phoenix::push_back; - using boost::phoenix::construct; - - expr = - * ( - str [ push_back(_val, _1)] - | - ( '[' >> attr [ push_back(_val, construct( _1 )) ] >> ']') - ) - ; - - attr %= +(char_ - ']'); - str %= lexeme[+(char_ -'[')]; -} - -} diff --git a/include/mapnik/path_expression_grammar_x3.hpp b/include/mapnik/path_expression_grammar_x3.hpp new file mode 100644 index 000000000..86e811fea --- /dev/null +++ b/include/mapnik/path_expression_grammar_x3.hpp @@ -0,0 +1,44 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#ifndef MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP +#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP + +// mapnik +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +struct path_expression_class; // top-most ID +using path_expression_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(path_expression_grammar_type); + +}} + +#endif // MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP diff --git a/include/mapnik/path_expression_grammar_x3_def.hpp b/include/mapnik/path_expression_grammar_x3_def.hpp new file mode 100644 index 000000000..7dc772aa1 --- /dev/null +++ b/include/mapnik/path_expression_grammar_x3_def.hpp @@ -0,0 +1,63 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#ifndef MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP +#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP +// mapnik +#include +#include + +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using x3::standard_wide::char_; +using x3::lexeme; +auto create_string = [](auto & ctx) { _val(ctx).push_back(_attr(ctx)); }; +auto create_attribute = [](auto & ctx) { _val(ctx).push_back(mapnik::attribute(_attr(ctx))); }; +// top-most rule +path_expression_grammar_type const path_expression("path_expression"); +// rules +x3::rule const attr_expression("attribute"); +x3::rule const str_expression("string"); + +auto const attr_expression_def = +(char_ - ']'); +auto const str_expression_def = lexeme[+(char_ -'[')]; +auto const path_expression_def = *(str_expression[create_string] | '[' > attr_expression[create_attribute] > ']'); + +BOOST_SPIRIT_DEFINE( + path_expression, + attr_expression, + str_expression +); + +}} + +namespace mapnik { + +grammar::path_expression_grammar_type path_expression_grammar() +{ + return grammar::path_expression; +} + +} + +#endif //MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_DEF_HPP diff --git a/include/mapnik/quad_tree.hpp b/include/mapnik/quad_tree.hpp index c15f09f26..a44962ec1 100644 --- a/include/mapnik/quad_tree.hpp +++ b/include/mapnik/quad_tree.hpp @@ -27,8 +27,10 @@ #include #include #include + // stl -#include +#include +#include #include #include @@ -83,12 +85,12 @@ class quad_tree : util::noncopyable int num_subnodes() const { - int count = 0; + int _count = 0; for (int i = 0; i < 4; ++i) { - if (children_[i]) ++count; + if (children_[i]) ++_count; } - return count; + return _count; } ~node () {} }; @@ -164,9 +166,9 @@ public: int count_items() const { - int count = 0; - count_items(root_, count); - return count; + int _count = 0; + count_items(root_, _count); + return _count; } void trim() { @@ -276,23 +278,23 @@ private: if (!n) return 0; else { - int count = 1; + int _count = 1; for (int i = 0; i < 4; ++i) { - count += count_nodes(n->children_[i]); + _count += count_nodes(n->children_[i]); } - return count; + return _count; } } - void count_items(node const* n,int& count) const + void count_items(node const* n, int& _count) const { if (n) { - count += n->cont_.size(); + _count += n->cont_.size(); for (int i = 0; i < 4; ++i) { - count_items(n->children_[i],count); + count_items(n->children_[i],_count); } } } diff --git a/include/mapnik/query.hpp b/include/mapnik/query.hpp index 5d5a6e7c8..6a86cfa3b 100644 --- a/include/mapnik/query.hpp +++ b/include/mapnik/query.hpp @@ -40,12 +40,12 @@ public: using resolution_type = std::tuple; query(box2d const& bbox, - resolution_type const& resolution, - double scale_denominator, + resolution_type const& _resolution, + double _scale_denominator, box2d const& unbuffered_bbox) : bbox_(bbox), - resolution_(resolution), - scale_denominator_(scale_denominator), + resolution_(_resolution), + scale_denominator_(_scale_denominator), filter_factor_(1.0), unbuffered_bbox_(unbuffered_bbox), names_(), @@ -53,11 +53,11 @@ public: {} query(box2d const& bbox, - resolution_type const& resolution, - double scale_denominator = 1.0) + resolution_type const& _resolution, + double _scale_denominator = 1.0) : bbox_(bbox), - resolution_(resolution), - scale_denominator_(scale_denominator), + resolution_(_resolution), + scale_denominator_(_scale_denominator), filter_factor_(1.0), unbuffered_bbox_(bbox), names_(), diff --git a/include/mapnik/raster.hpp b/include/mapnik/raster.hpp index 02022d359..8ed30e5a2 100644 --- a/include/mapnik/raster.hpp +++ b/include/mapnik/raster.hpp @@ -52,9 +52,9 @@ public: data_(std::move(data)), filter_factor_(filter_factor) {} - void set_nodata(double nodata) + void set_nodata(double _nodata) { - nodata_ = nodata; + nodata_ = _nodata; } boost::optional const& nodata() const diff --git a/include/mapnik/span_image_filter.hpp b/include/mapnik/span_image_filter.hpp index c0a9adbb9..950f76c08 100644 --- a/include/mapnik/span_image_filter.hpp +++ b/include/mapnik/span_image_filter.hpp @@ -176,9 +176,9 @@ public: span_image_resample_rgba_affine(source_type & src, interpolator_type & inter, - agg::image_filter_lut const & filter, + agg::image_filter_lut const & _filter, boost::optional const & nodata_value) : - agg::span_image_resample_rgba_affine(src, inter, filter) + agg::span_image_resample_rgba_affine(src, inter, _filter) { } }; diff --git a/include/mapnik/svg/output/svg_output_attributes.hpp b/include/mapnik/svg/output/svg_output_attributes.hpp index 00deeea26..06a00f276 100644 --- a/include/mapnik/svg/output/svg_output_attributes.hpp +++ b/include/mapnik/svg/output/svg_output_attributes.hpp @@ -121,12 +121,12 @@ namespace mapnik { namespace svg { fill_color_("#000000") {} - rect_output_attributes(const int x, const int y, const unsigned width, const unsigned height, color const& fill_color) + rect_output_attributes(const int x, const int y, const unsigned width, const unsigned height, color const& _fill_color) : x_(x), y_(y), width_(width), height_(height), - fill_color_(fill_color.to_hex_string()) + fill_color_(_fill_color.to_hex_string()) {} void set_x(const int x); diff --git a/include/mapnik/svg/output/svg_renderer.hpp b/include/mapnik/svg/output/svg_renderer.hpp index 037ec0ddb..7ce3e044d 100644 --- a/include/mapnik/svg/output/svg_renderer.hpp +++ b/include/mapnik/svg/output/svg_renderer.hpp @@ -131,9 +131,9 @@ public: return painted_; } - void painted(bool painted) + void painted(bool _painted) { - painted_ = painted; + painted_ = _painted; } inline eAttributeCollectionPolicy attribute_collection_policy() const diff --git a/include/mapnik/text/placements/list.hpp b/include/mapnik/text/placements/list.hpp index c21a4d87c..88938ee1c 100644 --- a/include/mapnik/text/placements/list.hpp +++ b/include/mapnik/text/placements/list.hpp @@ -50,8 +50,8 @@ private: class text_placement_info_list : public text_placement_info { public: - text_placement_info_list(text_placements_list const* parent, double scale_factor) : - text_placement_info(parent, scale_factor), + text_placement_info_list(text_placements_list const* parent, double _scale_factor) : + text_placement_info(parent, _scale_factor), state(0), parent_(parent) {} bool next() const; private: diff --git a/include/mapnik/transform_expression.hpp b/include/mapnik/transform_expression.hpp index 471287932..586d89e4a 100644 --- a/include/mapnik/transform_expression.hpp +++ b/include/mapnik/transform_expression.hpp @@ -55,6 +55,8 @@ struct matrix_node expr_node e_; expr_node f_; + matrix_node() = default; + template explicit matrix_node(T const& m) : a_(m.sx), b_(m.shy), c_(m.shx), d_(m.sy), e_(m.tx), f_(m.ty) {} @@ -69,6 +71,8 @@ struct translate_node expr_node tx_; expr_node ty_; + translate_node() = default; + translate_node(expr_node const& tx, boost::optional const& ty) : tx_(tx) @@ -80,6 +84,8 @@ struct scale_node expr_node sx_; expr_node sy_; + scale_node() = default; + scale_node(expr_node const& sx, boost::optional const& sy) : sx_(sx) @@ -94,6 +100,8 @@ struct rotate_node expr_node cx_; expr_node cy_; + rotate_node() = default; + explicit rotate_node(expr_node const& angle) : angle_(angle) {} @@ -123,16 +131,16 @@ struct rotate_node struct skewX_node { expr_node angle_; - - explicit skewX_node(expr_node const& angle) + skewX_node() = default; + skewX_node(expr_node const& angle) : angle_(angle) {} }; struct skewY_node { expr_node angle_; - - explicit skewY_node(expr_node const& angle) + skewY_node() = default; + skewY_node(expr_node const& angle) : angle_(angle) {} }; @@ -225,9 +233,9 @@ bool is_null_node (T const& node) } // namespace detail -using transform_node = detail::transform_node ; -using transform_list = std::vector ; -using transform_list_ptr = std::shared_ptr ; +using transform_node = detail::transform_node; +using transform_list = std::vector; +using transform_list_ptr = std::shared_ptr; MAPNIK_DECL std::string to_expression_string(transform_node const& node); MAPNIK_DECL std::string to_expression_string(transform_list const& list); diff --git a/include/mapnik/transform_expression_grammar.hpp b/include/mapnik/transform_expression_grammar.hpp deleted file mode 100644 index f3945f39b..000000000 --- a/include/mapnik/transform_expression_grammar.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************** - * - * 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 - * - *****************************************************************************/ - -#ifndef MAPNIK_TRANSFORM_EXPRESSION_GRAMMAR_HPP -#define MAPNIK_TRANSFORM_EXPRESSION_GRAMMAR_HPP - -// mapnik -#include -#include -#include - -// spirit -#include - -namespace mapnik { - - namespace qi = boost::spirit::qi; - - template - struct transform_expression_grammar - : qi::grammar - { - explicit transform_expression_grammar(); - - using node_rule = qi::rule; - using list_rule = qi::rule; - - // rules - qi::rule attr; - qi::rule atom; - qi::rule expr; - qi::rule sep_atom; - qi::rule sep_expr; - qi::rule start; - qi::rule transform_; - qi::rule matrix; - qi::rule translate; - qi::rule scale; - qi::rule rotate; - qi::rule skewX; - qi::rule skewY; - mapnik::expression_grammar g_; - }; - -} // namespace mapnik - -#endif // MAPNIK_TRANSFORM_EXPRESSION_GRAMMAR_HPP diff --git a/include/mapnik/transform_expression_grammar_impl.hpp b/include/mapnik/transform_expression_grammar_impl.hpp deleted file mode 100644 index 4b8c2b92a..000000000 --- a/include/mapnik/transform_expression_grammar_impl.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/***************************************************************************** - * - * 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 - -// boost -#include -#include -#include - - -namespace mapnik { - -namespace qi = boost::spirit::qi; - -template -transform_expression_grammar::transform_expression_grammar() - : transform_expression_grammar::base_type(start) -{ - using boost::phoenix::construct; - qi::_1_type _1; - qi::_4_type _4; - qi::_2_type _2; - qi::_5_type _5; - qi::_3_type _3; - qi::_6_type _6; - qi::_val_type _val; - qi::double_type double_; - qi::lit_type lit; - qi::no_case_type no_case; - - // [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. - - start = transform_ % *lit(',') ; - - transform_ = matrix | translate | scale | rotate | skewX | skewY ; - - // matrix( ) - matrix = no_case[lit("matrix")] - >> (lit('(') - >> ( atom >> sep_atom >> sep_atom >> sep_atom >> sep_atom - >> sep_atom >> lit(')') - | expr >> sep_expr >> sep_expr >> sep_expr >> sep_expr - >> sep_expr >> lit(')') - )) - [ _val = construct(_1,_2,_3,_4,_5,_6) ]; - - // translate( []) - translate = no_case[lit("translate")] - >> lit('(') - >> ( ( atom >> -sep_atom >> lit(')') ) - [ _val = construct(_1,_2) ] - | ( expr >> -sep_expr >> lit(')') ) - [ _val = construct(_1,_2) ] - ); - - // scale( []) - scale = no_case[lit("scale")] - >> lit('(') - >> ( ( atom >> -sep_atom >> lit(')') ) - [ _val = construct(_1,_2) ] - | ( expr >> -sep_expr >> lit(')') ) - [ _val = construct(_1,_2) ] - ); - - // rotate( [ ]) - rotate = no_case[lit("rotate")] - >> lit('(') - >> ( ( atom >> -( sep_atom >> sep_atom ) >> lit(')') ) - [ _val = construct(_1,_2) ] - | ( expr >> -( sep_expr >> sep_expr ) >> lit(')') ) - [ _val = construct(_1,_2) ] - ); - - // skewX() - skewX = no_case[lit("skewX")] - >> lit('(') - >> expr [ _val = construct(_1) ] - >> lit(')'); - - // skewY() - skewY = no_case[lit("skewY")] - >> lit('(') - >> expr [ _val = construct(_1) ] - >> lit(')'); - - // number or attribute - atom = double_ [ _val = _1 ] - | attr [ _val = construct(_1) ]; - - // Individual arguments in lists consiting solely of numbers and/or - // attributes are separated by whitespace and/or a comma. - sep_atom = -lit(',') >> atom [ _val = _1 ]; - - // Individual arguments in lists containing one or more compound - // expressions are separated by a comma. - sep_expr = lit(',') >> expr [ _val = _1 ]; - - attr = g_.attr.alias(); - expr = g_.expr.alias(); -} - -} diff --git a/include/mapnik/path_expression_grammar.hpp b/include/mapnik/transform_expression_grammar_x3.hpp similarity index 58% rename from include/mapnik/path_expression_grammar.hpp rename to include/mapnik/transform_expression_grammar_x3.hpp index 61a3db7ed..ccf480c22 100644 --- a/include/mapnik/path_expression_grammar.hpp +++ b/include/mapnik/transform_expression_grammar_x3.hpp @@ -20,40 +20,32 @@ * *****************************************************************************/ -#ifndef MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP -#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP +#ifndef MAPNIK_TRANSFORM_GRAMMAR_X3_HPP +#define MAPNIK_TRANSFORM_GRAMMAR_X3_HPP -// mapnik -#include +#include #pragma GCC diagnostic push #include -#include +#include #pragma GCC diagnostic pop -// stl -#include -#include +namespace mapnik { + +namespace x3 = boost::spirit::x3; + +namespace grammar { + +struct transform_expression_class; // top-most ID +using transform_expression_grammar_type = x3::rule; + +BOOST_SPIRIT_DECLARE(transform_expression_grammar_type); + +}} // ns namespace mapnik { - -using namespace boost; -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; -namespace standard_wide = boost::spirit::standard_wide; - -using standard_wide::space_type; - -template -struct path_expression_grammar : qi::grammar(), space_type> -{ - path_expression_grammar(); - qi::rule() , space_type> expr; - qi::rule attr; - qi::rule str; -}; - +grammar::transform_expression_grammar_type transform_expression_grammar(); } -#endif // MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP +#endif diff --git a/include/mapnik/transform_expression_grammar_x3_def.hpp b/include/mapnik/transform_expression_grammar_x3_def.hpp new file mode 100644 index 000000000..602f30aee --- /dev/null +++ b/include/mapnik/transform_expression_grammar_x3_def.hpp @@ -0,0 +1,184 @@ +/***************************************************************************** + * + * 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 + * + *****************************************************************************/ + +#ifndef MAPNIK_TRANSFORM_GRAMMAR_X3_DEF_HPP +#define MAPNIK_TRANSFORM_GRAMMAR_X3_DEF_HPP + +#include +#include +#include + +#pragma GCC diagnostic push +#include +#include +#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_)) + +// skewY +BOOST_FUSION_ADAPT_STRUCT(mapnik::skewY_node, + (mapnik::expr_node, angle_)) + + +// Following specializations are required to avoid trasferring mapnik::skewX/Y nodes as underlying expressions +// +// template +// inline void +// move_to_plain(Source&& src, Dest& dest, mpl::true_) // src is a single-element tuple +// { +// dest = std::move(fusion::front(src)); +// } +// which will fail to compile with latest (more strict) `mapbox::variant` (boost_1_61) + +namespace boost { namespace spirit { namespace x3 { namespace traits { +template <> +inline void move_to(mapnik::skewX_node && src, mapnik::detail::transform_node& dst) +{ + dst = std::move(src); +} + +template <> +inline void move_to(mapnik::skewY_node && src, mapnik::detail::transform_node& dst) +{ + dst = std::move(src); +} + +}}}} + + +namespace mapnik { namespace grammar { + + namespace x3 = boost::spirit::x3; + namespace ascii = boost::spirit::x3::ascii; + + // [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. + + 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"); + + // Import the expression rule + namespace { auto const& expr = expression_grammar(); } + + // start + auto const transform_def = transform_list_rule; + + auto const transform_list_rule_def = transform_node_rule % *lit(','); + + auto const transform_node_rule_def = matrix | translate | scale | rotate | skewX | skewY ; + + // matrix( ) + auto const matrix_def = no_case[lit("matrix")] + > '(' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ')' + ; + + // translate( []) + auto const translate_def = no_case[lit("translate")] + > '(' > expr > -(',' > expr ) > ')' + ; + + // scale( []) + auto const scale_def = no_case[lit("scale")] + > '(' > expr > -(',' > expr ) > ')' + ; + + // rotate( [ ]) + auto const rotate_def = no_case[lit("rotate")] + > '(' > expr > -(',' > expr > ',' > expr) > ')' + ; + + // skewX() + auto const skewX_def = no_case[lit("skewX")] + > '(' > expr > ')'; + + // skewY() + auto const skewY_def = no_case[lit("skewY")] + > '(' > expr > ')'; + + + BOOST_SPIRIT_DEFINE ( + transform, + transform_list_rule, + transform_node_rule, + matrix, + translate, + scale, + rotate, + skewX, + skewY); + +}} // ns + +namespace mapnik +{ +grammar::transform_expression_grammar_type transform_expression_grammar() +{ + return grammar::transform; +} +} + +#endif diff --git a/include/mapnik/well_known_srs.hpp b/include/mapnik/well_known_srs.hpp index e8349e709..235a90859 100644 --- a/include/mapnik/well_known_srs.hpp +++ b/include/mapnik/well_known_srs.hpp @@ -51,11 +51,11 @@ static const double EARTH_DIAMETER = EARTH_RADIUS * 2.0; static const double EARTH_CIRCUMFERENCE = EARTH_DIAMETER * M_PI; static const double MAXEXTENT = EARTH_CIRCUMFERENCE / 2.0; static const double M_PI_by2 = M_PI / 2; -static const double D2R = M_PI / 180; -static const double R2D = 180 / M_PI; -static const double M_PIby360 = M_PI / 360; -static const double MAXEXTENTby180 = MAXEXTENT / 180; -static const double MAX_LATITUDE = R2D * (2 * std::atan(std::exp(180 * D2R)) - M_PI_by2); +static const double D2R = M_PI / 180.0; +static const double R2D = 180.0 / M_PI; +static const double M_PIby360 = M_PI / 360.0; +static const double MAXEXTENTby180 = MAXEXTENT / 180.0; +static const double MAX_LATITUDE = R2D * (2 * std::atan(std::exp(180.0 * D2R)) - M_PI_by2); static const std::string MAPNIK_LONGLAT_PROJ = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"; static const std::string MAPNIK_GMERC_PROJ = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"; @@ -63,24 +63,23 @@ boost::optional is_well_known_srs(std::string const& srs); boost::optional is_known_geographic(std::string const& srs); -static inline bool lonlat2merc(double * x, double * y , int point_count) +static inline bool lonlat2merc(double * x, double * y, std::size_t point_count) { - for(int i=0; i 180) x[i] = 180; else if (x[i] < -180) x[i] = -180; if (y[i] > MAX_LATITUDE) y[i] = MAX_LATITUDE; else if (y[i] < -MAX_LATITUDE) y[i] = -MAX_LATITUDE; x[i] = x[i] * MAXEXTENTby180; - y[i] = std::log(std::tan((90 + y[i]) * M_PIby360)) * R2D; - y[i] = y[i] * MAXEXTENTby180; + y[i] = std::log(std::tan((90.0 + y[i]) * M_PIby360)) * R2D * MAXEXTENTby180; } return true; } -static inline bool merc2lonlat(double * x, double * y , int point_count) +static inline bool merc2lonlat(double * x, double * y, std::size_t point_count) { - for(int i=0; i MAXEXTENT) x[i] = MAXEXTENT; else if (x[i] < -MAXEXTENT) x[i] = -MAXEXTENT; diff --git a/plugins/input/shape/dbfile.cpp b/plugins/input/shape/dbfile.cpp index 3594bcbd6..36d9a964c 100644 --- a/plugins/input/shape/dbfile.cpp +++ b/plugins/input/shape/dbfile.cpp @@ -30,7 +30,7 @@ #pragma GCC diagnostic push #include -#include +#include #if defined(MAPNIK_MEMORY_MAPPED_FILE) #include #include @@ -187,9 +187,9 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feat double val = 0.0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; - ascii::space_type space; - static qi::double_type double_; - if (qi::phrase_parse(itr,end,double_,space,val)) + x3::ascii::space_type space; + static x3::double_type double_; + if (x3::phrase_parse(itr,end,double_,space,val)) { f.put(name,val); } @@ -199,9 +199,9 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feat mapnik::value_integer val = 0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; - ascii::space_type space; - static qi::int_parser numeric_parser; - if (qi::phrase_parse(itr, end, numeric_parser, space, val)) + x3::ascii::space_type space; + static x3::int_parser numeric_parser; + if (x3::phrase_parse(itr, end, numeric_parser, space, val)) { f.put(name,val); } diff --git a/src/agg/process_building_symbolizer.cpp b/src/agg/process_building_symbolizer.cpp index d27b68b7c..6bcee3457 100644 --- a/src/agg/process_building_symbolizer.cpp +++ b/src/agg/process_building_symbolizer.cpp @@ -36,6 +36,7 @@ // stl #include +#include #pragma GCC diagnostic push #include diff --git a/src/build.py b/src/build.py index f4d444ee0..a1c7da041 100644 --- a/src/build.py +++ b/src/build.py @@ -152,15 +152,17 @@ else: # unix, non-macos source = Split( """ - expression_grammar.cpp + expression_grammar_x3.cpp fs.cpp request.cpp well_known_srs.cpp params.cpp - image_filter_types.cpp - image_filter_grammar.cpp + parse_image_filters.cpp + generate_image_filters.cpp + image_filter_grammar_x3.cpp color.cpp - conversions.cpp + conversions_numeric.cpp + conversions_string.cpp image_copy.cpp image_compositing.cpp image_scaling.cpp @@ -174,6 +176,7 @@ source = Split( expression_string.cpp expression.cpp transform_expression.cpp + transform_expression_grammar_x3.cpp feature_kv_iterator.cpp feature_style_processor.cpp feature_type_style.cpp @@ -200,7 +203,6 @@ source = Split( load_map.cpp palette.cpp marker_helpers.cpp - transform_expression_grammar.cpp plugin.cpp rule.cpp save_map.cpp @@ -224,7 +226,7 @@ source = Split( svg/svg_points_parser.cpp svg/svg_transform_parser.cpp warp.cpp - css_color_grammar.cpp + css_color_grammar_x3.cpp vertex_cache.cpp vertex_adapters.cpp text/font_library.cpp diff --git a/src/cairo/process_building_symbolizer.cpp b/src/cairo/process_building_symbolizer.cpp index 544414374..cc4c6baf5 100644 --- a/src/cairo/process_building_symbolizer.cpp +++ b/src/cairo/process_building_symbolizer.cpp @@ -34,6 +34,7 @@ // stl #include +#include namespace mapnik { diff --git a/src/cairo/process_group_symbolizer.cpp b/src/cairo/process_group_symbolizer.cpp index 0c35ba0ec..0885df49d 100644 --- a/src/cairo/process_group_symbolizer.cpp +++ b/src/cairo/process_group_symbolizer.cpp @@ -32,6 +32,8 @@ // mapnik symbolizer generics #include +#include + namespace mapnik { diff --git a/src/cairo/process_line_pattern_symbolizer.cpp b/src/cairo/process_line_pattern_symbolizer.cpp index f53d850a6..e4ae6f609 100644 --- a/src/cairo/process_line_pattern_symbolizer.cpp +++ b/src/cairo/process_line_pattern_symbolizer.cpp @@ -35,6 +35,8 @@ #include #include +#include + namespace mapnik { diff --git a/src/cairo/process_raster_symbolizer.cpp b/src/cairo/process_raster_symbolizer.cpp index 2b6fdc5c2..658ad8373 100644 --- a/src/cairo/process_raster_symbolizer.cpp +++ b/src/cairo/process_raster_symbolizer.cpp @@ -32,6 +32,8 @@ // mapnik symbolizer generics #include +#include + namespace mapnik { diff --git a/src/color_factory.cpp b/src/color_factory.cpp index dc54e89e5..83956d71f 100644 --- a/src/color_factory.cpp +++ b/src/color_factory.cpp @@ -24,21 +24,20 @@ #include #include #include -#include +#include namespace mapnik { color parse_color(std::string const& str) { // TODO - early return for @color? - static const css_color_grammar g; + auto const& grammar = mapnik::color_grammar(); color c; std::string::const_iterator first = str.begin(); std::string::const_iterator last = str.end(); - boost::spirit::ascii::space_type space; - bool result = boost::spirit::qi::phrase_parse(first, last, g, - space, - c); + using namespace boost::spirit::x3::ascii; + + bool result = boost::spirit::x3::phrase_parse(first, last, grammar, space, c); if (result && (first == last)) { return c; diff --git a/src/conversions.cpp b/src/conversions.cpp deleted file mode 100644 index fc63f1dcd..000000000 --- a/src/conversions.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/***************************************************************************** - * - * 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 - -#include -#include - -// karma is used by default -#define MAPNIK_KARMA_TO_STRING - -#pragma GCC diagnostic push -#include -#include -#ifdef MAPNIK_KARMA_TO_STRING - #include -#endif -#pragma GCC diagnostic pop - -#if _MSC_VER -#define snprintf _snprintf -#endif - -namespace mapnik { - -namespace util { - -using namespace boost::spirit; - -auto INTEGER = qi::int_type(); -#ifdef BIGINT -auto LONGLONG = qi::long_long_type(); -#endif -auto FLOAT = qi::float_type(); -auto DOUBLE = qi::double_type(); - -bool string2bool(std::string const& value, bool & result) -{ - if (value.empty() || value.size() > 5) { - return false; - } else if (value == "true") { - return result = true; - } else if (value == "false") { - result = false; - return true; - } - std::string val(value); - std::transform(val.begin(), val.end(), val.begin(), ::tolower); - if (val == "true" || val == "yes" || val == "1" || val == "on") { - return result = true; - } else if (val == "false" || val == "no" || val == "0" || val == "off") { - result = false; - return true; - } - return false; -} - -bool string2bool(const char * iter, const char * end, bool & result) -{ - std::string val(iter,end); - return string2bool(val,result); -} - -bool string2int(const char * iter, const char * end, int & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,INTEGER,space,result); - return r && (iter == end); -} - -bool string2int(std::string const& value, int & result) -{ - ascii::space_type space; - std::string::const_iterator str_beg = value.begin(); - std::string::const_iterator str_end = value.end(); - bool r = qi::phrase_parse(str_beg,str_end,INTEGER,space,result); - return r && (str_beg == str_end); -} - -#ifdef BIGINT -bool string2int(const char * iter, const char * end, mapnik::value_integer & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,LONGLONG,space,result); - return r && (iter == end); -} - -bool string2int(std::string const& value, mapnik::value_integer & result) -{ - ascii::space_type space; - std::string::const_iterator str_beg = value.begin(); - std::string::const_iterator str_end = value.end(); - bool r = qi::phrase_parse(str_beg,str_end,LONGLONG,space,result); - return r && (str_beg == str_end); -} -#endif - -bool string2double(std::string const& value, double & result) -{ - ascii::space_type space; - std::string::const_iterator str_beg = value.begin(); - std::string::const_iterator str_end = value.end(); - bool r = qi::phrase_parse(str_beg,str_end,DOUBLE,space,result); - return r && (str_beg == str_end); -} - -bool string2double(const char * iter, const char * end, double & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,DOUBLE,space,result); - return r && (iter == end); -} - -bool string2float(std::string const& value, float & result) -{ - ascii::space_type space; - std::string::const_iterator str_beg = value.begin(); - std::string::const_iterator str_end = value.end(); - bool r = qi::phrase_parse(str_beg,str_end,FLOAT,space,result); - return r && (str_beg == str_end); -} - -bool string2float(const char * iter, const char * end, float & result) -{ - ascii::space_type space; - bool r = qi::phrase_parse(iter,end,FLOAT,space,result); - return r && (iter == end); -} - -// double conversion - here we use sprintf over karma to work -// around https://github.com/mapnik/mapnik/issues/1741 -bool to_string(std::string & s, double val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%g", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} - -#ifdef MAPNIK_KARMA_TO_STRING - -bool to_string(std::string & str, int value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} - -#ifdef BIGINT -bool to_string(std::string & str, mapnik::value_integer value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} -#endif - -bool to_string(std::string & str, unsigned value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} - -bool to_string(std::string & str, bool value) -{ - namespace karma = boost::spirit::karma; - std::back_insert_iterator sink(str); - return karma::generate(sink, value); -} - -#else - -bool to_string(std::string & s, int val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%d", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} - -#ifdef BIGINT -bool to_string(std::string & s, mapnik::value_integer val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%lld", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} -#endif - -bool to_string(std::string & s, unsigned val) -{ - s.resize(s.capacity()); - while (true) - { - size_t n2 = static_cast(snprintf(&s[0], s.size()+1, "%u", val)); - if (n2 <= s.size()) - { - s.resize(n2); - break; - } - s.resize(n2); - } - return true; -} - -bool to_string(std::string & s, bool val) -{ - if (val) s = "true"; - else s = "false"; - return true; -} - -#endif - -} // end namespace util - -} diff --git a/src/conversions_numeric.cpp b/src/conversions_numeric.cpp new file mode 100644 index 000000000..d209ea6b6 --- /dev/null +++ b/src/conversions_numeric.cpp @@ -0,0 +1,146 @@ +/***************************************************************************** + * + * 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 + +#include + +#pragma GCC diagnostic push +#include +#include +#pragma GCC diagnostic pop + +namespace mapnik { namespace util { + +using namespace boost::spirit; + +auto INTEGER = x3::int_type(); +#ifdef BIGINT +//auto LONGLONG = x3::long_long_type(); +#endif +auto FLOAT = x3::float_type(); +auto DOUBLE = x3::double_type(); + +bool string2bool(std::string const& value, bool& result) +{ + if (value.empty() || value.size() > 5) + { + return false; + } + else if (value == "true") + { + return result = true; + } + else if (value == "false") + { + result = false; + return true; + } + std::string val(value); + std::transform(val.begin(), val.end(), val.begin(), ::tolower); + if (val == "true" || val == "yes" || val == "1" || val == "on") + { + return result = true; + } + else if (val == "false" || val == "no" || val == "0" || val == "off") + { + result = false; + return true; + } + return false; +} + +bool string2bool(const char* iter, const char* end, bool& result) +{ + std::string val(iter, end); + return string2bool(val, result); +} + +bool string2int(const char* iter, const char* end, int& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, INTEGER, space, result); + return r && (iter == end); +} + +bool string2int(std::string const& value, int& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, INTEGER, space, result); + return r && (str_beg == str_end); +} + +#ifdef BIGINT +bool string2int(const char* iter, const char* end, mapnik::value_integer& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, x3::long_long, space, result); + return r && (iter == end); +} + +bool string2int(std::string const& value, mapnik::value_integer& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, x3::long_long, space, result); + return r && (str_beg == str_end); +} +#endif + +bool string2double(std::string const& value, double& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, DOUBLE, space, result); + return r && (str_beg == str_end); +} + +bool string2double(const char* iter, const char* end, double& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, DOUBLE, space, result); + return r && (iter == end); +} + +bool string2float(std::string const& value, float& result) +{ + x3::ascii::space_type space; + std::string::const_iterator str_beg = value.begin(); + std::string::const_iterator str_end = value.end(); + bool r = x3::phrase_parse(str_beg, str_end, FLOAT, space, result); + return r && (str_beg == str_end); +} + +bool string2float(const char* iter, const char* end, float& result) +{ + x3::ascii::space_type space; + bool r = x3::phrase_parse(iter, end, FLOAT, space, result); + return r && (iter == end); +} +} // util +} // mapnik diff --git a/src/conversions_string.cpp b/src/conversions_string.cpp new file mode 100644 index 000000000..bd9e46df1 --- /dev/null +++ b/src/conversions_string.cpp @@ -0,0 +1,162 @@ +/***************************************************************************** + * + * 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 + +#include +#include + +// karma is used by default +#define MAPNIK_KARMA_TO_STRING + +#pragma GCC diagnostic push +#include +#ifdef MAPNIK_KARMA_TO_STRING +#include +#endif +#pragma GCC diagnostic pop + +#if _MSC_VER +#define snprintf _snprintf +#endif + +namespace mapnik { namespace util { + +using namespace boost::spirit; + +// double conversion - here we use sprintf over karma to work +// around https://github.com/mapnik/mapnik/issues/1741 +bool to_string(std::string& s, double val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%g", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} + +#ifdef MAPNIK_KARMA_TO_STRING + +bool to_string(std::string& str, int value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} + +#ifdef BIGINT +bool to_string(std::string& str, mapnik::value_integer value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} +#endif + +bool to_string(std::string& str, unsigned value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} + +bool to_string(std::string& str, bool value) +{ + namespace karma = boost::spirit::karma; + std::back_insert_iterator sink(str); + return karma::generate(sink, value); +} + +#else + +bool to_string(std::string& s, int val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%d", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} + +#ifdef BIGINT +bool to_string(std::string& s, mapnik::value_integer val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%lld", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} +#endif + +bool to_string(std::string& s, unsigned val) +{ + s.resize(s.capacity()); + while (true) + { + size_t n2 = static_cast(snprintf(&s[0], s.size() + 1, "%u", val)); + if (n2 <= s.size()) + { + s.resize(n2); + break; + } + s.resize(n2); + } + return true; +} + +bool to_string(std::string& s, bool val) +{ + if (val) + s = "true"; + else + s = "false"; + return true; +} + +#endif + +} // end namespace util +} diff --git a/src/image_filter_grammar.cpp b/src/css_color_grammar_x3.cpp similarity index 74% rename from src/image_filter_grammar.cpp rename to src/css_color_grammar_x3.cpp index 9a4bea35a..a89505496 100644 --- a/src/image_filter_grammar.cpp +++ b/src/css_color_grammar_x3.cpp @@ -20,10 +20,14 @@ * *****************************************************************************/ -#include -#include -#include -#include -#include +#include -template struct mapnik::image_filter_grammar>; +namespace mapnik { namespace css_color_grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; + +BOOST_SPIRIT_INSTANTIATE(css_color_grammar_type, iterator_type, context_type); + +}} diff --git a/src/dasharray_parser.cpp b/src/dasharray_parser.cpp index 963a2905a..3c884cb3f 100644 --- a/src/dasharray_parser.cpp +++ b/src/dasharray_parser.cpp @@ -25,11 +25,7 @@ #pragma GCC diagnostic push #include -#include -#include -#include -#include -#include +#include #pragma GCC diagnostic pop namespace mapnik { @@ -58,15 +54,14 @@ inline bool setup_dashes(std::vector & buf, dash_array & dash) } } + bool parse_dasharray(std::string const& value, dash_array & dash) { using namespace boost::spirit; - qi::double_type double_; - qi::_1_type _1; - qi::lit_type lit; - qi::char_type char_; - qi::ascii::space_type space; - qi::no_skip_type no_skip; + using x3::no_skip; + using x3::double_; + using x3::char_; + boost::spirit::x3::ascii::space_type space; // SVG // dasharray ::= (length | percentage) (comma-wsp dasharray)? // no support for 'percentage' as viewport is unknown at load_map @@ -74,11 +69,9 @@ bool parse_dasharray(std::string const& value, dash_array & dash) std::vector buf; auto first = value.begin(); auto last = value.end(); - bool r = qi::phrase_parse(first, last, - (double_[boost::phoenix::push_back(boost::phoenix::ref(buf), _1)] % - no_skip[char_(", ")] - | lit("none")), - space); + bool r = x3::phrase_parse(first, last, + (double_ % no_skip[char_(", ")] | "none"), + space, buf); if (r && first == last) { return setup_dashes(buf, dash); diff --git a/src/expression.cpp b/src/expression.cpp index f4bdeeb84..2988fc7d9 100644 --- a/src/expression.cpp +++ b/src/expression.cpp @@ -25,27 +25,31 @@ #include #include #include -#include - -// boost -#include +#include +#include namespace mapnik { expression_ptr parse_expression(std::string const& str) { - static const expression_grammar g; - boost::spirit::standard_wide::space_type space; auto node = std::make_shared(); - std::string::const_iterator itr = str.begin(); - std::string::const_iterator end = str.end(); + using boost::spirit::x3::ascii::space; + mapnik::transcoder const tr("utf8"); + auto parser = boost::spirit::x3::with(std::ref(tr)) + [ + mapnik::expression_grammar() + ]; + bool r = false; + std::string::const_iterator itr = str.begin(); + std::string::const_iterator const end = str.end(); + try { - r = boost::spirit::qi::phrase_parse(itr, end, g, space, *node); + r = boost::spirit::x3::phrase_parse(itr, end, parser, space, *node); } - catch (boost::spirit::qi::expectation_failure const& ex) + catch (boost::spirit::x3::expectation_failure const& ex) { // no need to show "boost::spirit::qi::expectation_failure" which is a std::runtime_error throw config_error("Failed to parse expression: \"" + str + "\""); diff --git a/src/transform_expression_grammar.cpp b/src/expression_grammar_x3.cpp similarity index 81% rename from src/transform_expression_grammar.cpp rename to src/expression_grammar_x3.cpp index 170b0a823..f55e7cc3b 100644 --- a/src/transform_expression_grammar.cpp +++ b/src/expression_grammar_x3.cpp @@ -20,7 +20,11 @@ * *****************************************************************************/ -#include -#include +#include +#include -template struct mapnik::transform_expression_grammar; +namespace mapnik { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(expression_grammar_type, iterator_type, context_type); + +}} diff --git a/src/feature_type_style.cpp b/src/feature_type_style.cpp index a2ddb33ba..6d0ee13fd 100644 --- a/src/feature_type_style.cpp +++ b/src/feature_type_style.cpp @@ -148,9 +148,9 @@ std::vector const& feature_type_style::direct_image_filter return direct_filters_; } -void feature_type_style::set_comp_op(composite_mode_e comp_op) +void feature_type_style::set_comp_op(composite_mode_e _comp_op) { - comp_op_ = comp_op; + comp_op_ = _comp_op; } boost::optional feature_type_style::comp_op() const diff --git a/src/font_engine_freetype.cpp b/src/font_engine_freetype.cpp index 9721d70bf..29e34a769 100644 --- a/src/font_engine_freetype.cpp +++ b/src/font_engine_freetype.cpp @@ -48,7 +48,6 @@ extern "C" #include #include - namespace mapnik { diff --git a/src/image_filter_types.cpp b/src/generate_image_filters.cpp similarity index 66% rename from src/image_filter_types.cpp rename to src/generate_image_filters.cpp index d30804378..03c55ab43 100644 --- a/src/image_filter_types.cpp +++ b/src/generate_image_filters.cpp @@ -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 @@ -19,9 +19,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ + // mapnik #include -#include #pragma GCC diagnostic push #include @@ -43,18 +43,4 @@ bool generate_image_filters(std::back_insert_iterator & sink, std:: return r; } -bool parse_image_filters(std::string const& filters, std::vector& image_filters) -{ - std::string::const_iterator itr = filters.begin(); - std::string::const_iterator end = filters.end(); - static const mapnik::image_filter_grammar > filter_grammar; - boost::spirit::qi::ascii::space_type space; - bool r = boost::spirit::qi::phrase_parse(itr,end, - filter_grammar, - space, - image_filters); - return r && itr==end; -} - }} diff --git a/src/grid/process_building_symbolizer.cpp b/src/grid/process_building_symbolizer.cpp index 13ee8d442..f3fb0f76d 100644 --- a/src/grid/process_building_symbolizer.cpp +++ b/src/grid/process_building_symbolizer.cpp @@ -38,6 +38,7 @@ // stl #include +#include #pragma GCC diagnostic push #include diff --git a/src/css_color_grammar.cpp b/src/image_filter_grammar_x3.cpp similarity index 67% rename from src/css_color_grammar.cpp rename to src/image_filter_grammar_x3.cpp index 2e9f60c92..8b1e84f8a 100644 --- a/src/css_color_grammar.cpp +++ b/src/image_filter_grammar_x3.cpp @@ -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 @@ -20,12 +20,14 @@ * *****************************************************************************/ -// NOTE: we define this here in a cpp because def is needed twice: -// once by src/color_factory.cpp and once by include/mapnik/image_filter_grammar.hpp -// otherwise it would make sense to simply do `#include ` -// in a single file -#include -#include -#include +#include -template struct mapnik::css_color_grammar; +namespace mapnik { namespace image_filter { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; + +BOOST_SPIRIT_INSTANTIATE(image_filter_grammar_type, iterator_type, context_type); + +}} // image_filter //mapnik diff --git a/src/image_options.cpp b/src/image_options.cpp index bbcb6c909..7494838cf 100644 --- a/src/image_options.cpp +++ b/src/image_options.cpp @@ -24,49 +24,43 @@ #pragma GCC diagnostic push #include -#include +#include #include #pragma GCC diagnostic pop -namespace mapnik { namespace detail { +namespace mapnik { namespace grammar { -namespace qi = boost::spirit::qi; +namespace x3 = boost::spirit::x3; -template -struct image_options_grammar - : qi::grammar -{ - using pair_type = std::pair>; - image_options_grammar() - : image_options_grammar::base_type(start) - { - qi::lit_type lit; - qi::char_type char_; - start = pair >> *(lit(':') >> pair) - ; - pair = key >> -('=' >> value) - ; - key = char_("a-zA-Z_") >> *char_("a-zA-Z_0-9\\.\\-") - ; - value = +char_("a-zA-Z_0-9\\.\\-") - ; - } +using x3::lit; +using x3::ascii::char_; +using pair_type = std::pair>; - qi::rule start; - qi::rule pair; - qi::rule key, value; -}; +x3::rule const image_options("image options"); +x3::rule const key_value("key_value"); +x3::rule const key("key"); +x3::rule const value("value"); -} // ns detail +auto const key_def = char_("a-zA-Z_") > *char_("a-zA-Z_0-9\\.\\-"); +auto const value_def = +char_("a-zA-Z_0-9\\.\\-"); +auto const key_value_def = key > -('=' > value); +auto const image_options_def = key_value % lit(':'); + +BOOST_SPIRIT_DEFINE(key); +BOOST_SPIRIT_DEFINE(value); +BOOST_SPIRIT_DEFINE(key_value); +BOOST_SPIRIT_DEFINE(image_options); + +} // grammar image_options_map parse_image_options(std::string const& str) { auto const begin = str.begin(); auto const end = str.end(); - boost::spirit::ascii::space_type space; - mapnik::detail::image_options_grammar g; + using boost::spirit::x3::space; + using mapnik::grammar::image_options; image_options_map options; - bool success = boost::spirit::qi::phrase_parse(begin, end, g, space, options); + bool success = boost::spirit::x3::phrase_parse(begin, end, image_options, space, options); if (!success) { throw std::runtime_error("Can't parse image options: " + str); diff --git a/src/layer.cpp b/src/layer.cpp index 442026b4d..a923ae11b 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -31,9 +31,9 @@ namespace mapnik { -layer::layer(std::string const& name, std::string const& srs) - : name_(name), - srs_(srs), +layer::layer(std::string const& _name, std::string const& _srs) + : name_(_name), + srs_(_srs), minimum_scale_denom_(0), maximum_scale_denom_(std::numeric_limits::max()), active_(true), @@ -114,9 +114,9 @@ bool layer::operator==(layer const& rhs) const layer::~layer() {} -void layer::set_name( std::string const& name) +void layer::set_name( std::string const& _name) { - name_ = name; + name_ = _name; } std::string const& layer::name() const @@ -124,9 +124,9 @@ std::string const& layer::name() const return name_; } -void layer::set_srs(std::string const& srs) +void layer::set_srs(std::string const& _srs) { - srs_ = srs; + srs_ = _srs; } std::string const& layer::srs() const @@ -169,9 +169,9 @@ double layer::maximum_scale_denominator() const return maximum_scale_denom_; } -void layer::set_active(bool active) +void layer::set_active(bool _active) { - active_=active; + active_ = _active; } bool layer::active() const @@ -184,9 +184,9 @@ bool layer::visible(double scale_denom) const return active() && scale_denom >= minimum_scale_denom_ - 1e-6 && scale_denom < maximum_scale_denom_ + 1e-6; } -void layer::set_queryable(bool queryable) +void layer::set_queryable(bool _queryable) { - queryable_=queryable; + queryable_ = _queryable; } bool layer::queryable() const @@ -250,9 +250,9 @@ bool layer::clear_label_cache() const return clear_label_cache_; } -void layer::set_cache_features(bool cache_features) +void layer::set_cache_features(bool _cache_features) { - cache_features_ = cache_features; + cache_features_ = _cache_features; } bool layer::cache_features() const diff --git a/src/map.cpp b/src/map.cpp index ec0d9f83e..dc3d53040 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -375,39 +375,39 @@ unsigned Map::height() const return height_; } -void Map::set_width(unsigned width) +void Map::set_width(unsigned _width) { - if (width != width_ && - width >= MIN_MAPSIZE && - width <= MAX_MAPSIZE) + if (_width != width_ && + _width >= MIN_MAPSIZE && + _width <= MAX_MAPSIZE) { - width_=width; + width_=_width; fixAspectRatio(); } } -void Map::set_height(unsigned height) +void Map::set_height(unsigned _height) { - if (height != height_ && - height >= MIN_MAPSIZE && - height <= MAX_MAPSIZE) + if (_height != height_ && + _height >= MIN_MAPSIZE && + _height <= MAX_MAPSIZE) { - height_=height; + height_ = _height; fixAspectRatio(); } } -void Map::resize(unsigned width,unsigned height) +void Map::resize(unsigned _width, unsigned _height) { - if ((width != width_ || - height != height_) && - width >= MIN_MAPSIZE && - width <= MAX_MAPSIZE && - height >= MIN_MAPSIZE && - height <= MAX_MAPSIZE) + if ((_width != width_ || + _height != height_) && + _width >= MIN_MAPSIZE && + _width <= MAX_MAPSIZE && + _height >= MIN_MAPSIZE && + _height <= MAX_MAPSIZE) { - width_=width; - height_=height; + width_ = _width; + height_ = _height; fixAspectRatio(); } } @@ -417,14 +417,14 @@ std::string const& Map::srs() const return srs_; } -void Map::set_srs(std::string const& srs) +void Map::set_srs(std::string const& _srs) { - srs_ = srs; + srs_ = _srs; } -void Map::set_buffer_size( int buffer_size) +void Map::set_buffer_size(int _buffer_size) { - buffer_size_ = buffer_size; + buffer_size_ = _buffer_size; } int Map::buffer_size() const diff --git a/src/memory_datasource.cpp b/src/memory_datasource.cpp index 24238f382..d4a2fdcf5 100644 --- a/src/memory_datasource.cpp +++ b/src/memory_datasource.cpp @@ -68,12 +68,12 @@ const char * memory_datasource::name() return "memory"; } -memory_datasource::memory_datasource(parameters const& params) - : datasource(params), +memory_datasource::memory_datasource(parameters const& _params) + : datasource(_params), desc_(memory_datasource::name(), - *params.get("encoding","utf-8")), + *params_.get("encoding","utf-8")), type_(datasource::Vector), - bbox_check_(*params.get("bbox_check", true)), + bbox_check_(*params_.get("bbox_check", true)), type_set_(false) {} memory_datasource::~memory_datasource() {} diff --git a/src/parse_image_filters.cpp b/src/parse_image_filters.cpp new file mode 100644 index 000000000..e8370e897 --- /dev/null +++ b/src/parse_image_filters.cpp @@ -0,0 +1,54 @@ +/***************************************************************************** + * + * 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 +// stl +#include + +namespace mapnik { + +namespace filter { + +bool parse_image_filters(std::string const& str, std::vector & image_filters) +{ + using namespace boost::spirit::x3::ascii; + auto const& grammar = mapnik::image_filter_grammar(); + auto itr = str.begin(); + auto end = str.end(); + + boost::spirit::x3::ascii::space_type space; + bool r = false; + try + { + r = boost::spirit::x3::phrase_parse(itr, end, grammar, space, image_filters); + } + catch (...) + { + image_filters.clear(); + r = false; + } + return r && itr==end; +} + +}} diff --git a/src/parse_path.cpp b/src/parse_path.cpp index a3d67c2cb..ebf50fbcc 100644 --- a/src/parse_path.cpp +++ b/src/parse_path.cpp @@ -21,26 +21,35 @@ *****************************************************************************/ #include -#include -#include #include #include #include #include +#include +#include + // stl #include -namespace mapnik { +namespace mapnik { namespace grammar { + +namespace x3 = boost::spirit::x3; +using iterator_type = std::string::const_iterator; +using context_type = x3::phrase_parse_context::type; + +BOOST_SPIRIT_INSTANTIATE(path_expression_grammar_type, iterator_type, context_type); + +} path_expression_ptr parse_path(std::string const& str) { - static const path_expression_grammar g; + namespace x3 = boost::spirit::x3; auto path = std::make_shared(); - boost::spirit::standard_wide::space_type space; + using boost::spirit::x3::standard_wide::space; std::string::const_iterator itr = str.begin(); std::string::const_iterator end = str.end(); - bool r = qi::phrase_parse(itr, end, g, space, *path); + bool r = x3::phrase_parse(itr, end, path_expression_grammar(), space, *path); if (r && itr == end) { return path; diff --git a/src/parse_transform.cpp b/src/parse_transform.cpp index e2daaf480..06b189f35 100644 --- a/src/parse_transform.cpp +++ b/src/parse_transform.cpp @@ -21,8 +21,9 @@ *****************************************************************************/ #include -#include - +#include +#include // transcoder_tag +#include // stl #include #include @@ -31,14 +32,28 @@ namespace mapnik { transform_list_ptr parse_transform(std::string const& str, std::string const& encoding) { - static const transform_expression_grammar g; - transform_list_ptr tl = std::make_shared(); + using boost::spirit::x3::ascii::space; + transform_list_ptr trans_list = std::make_shared(); std::string::const_iterator itr = str.begin(); std::string::const_iterator end = str.end(); - bool r = qi::phrase_parse(itr, end, g, space_type(), *tl); - if (r && itr == end) + mapnik::transcoder const tr(encoding); + auto const parser = boost::spirit::x3::with(std::ref(tr)) + [ + mapnik::transform_expression_grammar() + ]; + bool status = false; + try { - return tl; + status = boost::spirit::x3::phrase_parse(itr, end, parser, space, *trans_list); + } + catch (boost::spirit::x3::expectation_failure const& ex) + { + throw config_error("Failed to parse transform expression: \"" + str + "\""); + } + + if (status && itr == end) + { + return trans_list; } else { diff --git a/src/svg/svg_parser.cpp b/src/svg/svg_parser.cpp index 827f557fc..9247eef86 100644 --- a/src/svg/svg_parser.cpp +++ b/src/svg/svg_parser.cpp @@ -41,9 +41,8 @@ #pragma GCC diagnostic push #include -#include -#include -#include +#include +#include #include #include #include @@ -55,6 +54,24 @@ #include #include +namespace mapnik { namespace svg { +struct viewbox +{ + double x0; + double y0; + double x1; + double y1; +}; +}} + +BOOST_FUSION_ADAPT_STRUCT ( + mapnik::svg::viewbox, + (double, x0) + (double, y0) + (double, x1) + (double, y1) + ) + namespace mapnik { namespace svg { namespace rapidxml = boost::property_tree::detail::rapidxml; @@ -77,29 +94,29 @@ void parse_attr(svg_parser & parser,rapidxml::xml_node const* node); void parse_attr(svg_parser & parser,char const * name, char const* value); +namespace grammar { + +namespace x3 = boost::spirit::x3; + using color_lookup_type = std::vector >; -namespace qi = boost::spirit::qi; using pairs_type = std::vector >; -template -struct key_value_sequence_ordered - : qi::grammar -{ - key_value_sequence_ordered() - : key_value_sequence_ordered::base_type(query) - { - qi::lit_type lit; - qi::char_type char_; - query = pair >> *( lit(';') >> pair); - pair = key >> -(':' >> value); - key = char_("a-zA-Z_") >> *char_("a-zA-Z_0-9-"); - value = +(char_ - lit(';')); - } +x3::rule const key_value_sequence_ordered("key_value_sequence_ordered"); +x3::rule > key_value("key_value"); +x3::rule key("key"); +x3::rule value("value"); - qi::rule query; - qi::rule(), SkipType> pair; - qi::rule key, value; -}; +auto const key_def = x3::char_("a-zA-Z_") > *x3::char_("a-zA-Z_0-9-"); +auto const value_def = +(x3::char_ - ';'); +auto const key_value_def = key > -(':' > value); +auto const key_value_sequence_ordered_def = key_value % ';'; + +BOOST_SPIRIT_DEFINE(key); +BOOST_SPIRIT_DEFINE(value); +BOOST_SPIRIT_DEFINE(key_value); +BOOST_SPIRIT_DEFINE(key_value_sequence_ordered); + +} template mapnik::color parse_color(T & error_messages, const char* str) @@ -126,10 +143,9 @@ agg::rgba8 parse_color_agg(T & error_messages, const char* str) template double parse_double(T & error_messages, const char* str) { - using namespace boost::spirit::qi; - double_type double_; + using namespace boost::spirit::x3; double val = 0.0; - if (!parse(str, str + std::strlen(str),double_,val)) + if (!parse(str, str + std::strlen(str), double_, val)) { error_messages.emplace_back("Failed to parse double: \"" + std::string(str) + "\""); } @@ -138,15 +154,11 @@ double parse_double(T & error_messages, const char* str) // https://www.w3.org/TR/SVG/coords.html#Units template -double parse_svg_value(T & error_messages, const char* str, bool & percent) +double parse_svg_value(T & error_messages, const char* str, bool & is_percent) { - using skip_type = boost::spirit::ascii::space_type; - using boost::phoenix::ref; - qi::double_type double_; - qi::lit_type lit; - qi::_1_type _1; + namespace x3 = boost::spirit::x3; double val = 0.0; - qi::symbols units; + x3::symbols units; units.add ("px", 1.0) ("pt", DPI/72.0) @@ -157,12 +169,17 @@ double parse_svg_value(T & error_messages, const char* str, bool & percent) ; const char* cur = str; // phrase_parse modifies the first iterator const char* end = str + std::strlen(str); - if (!qi::phrase_parse(cur, end, - double_[ref(val) = _1][ref(percent) = false] - > - (units[ ref(val) *= _1] - | - lit('%')[ref(val) *= 0.01][ref(percent) = true]), - skip_type())) + + auto apply_value = [&](auto const& ctx) { val = _attr(ctx); is_percent = false; }; + auto apply_units = [&](auto const& ctx) { val *= _attr(ctx); }; + auto apply_percent = [&](auto const& ctx) { val *= 0.01; is_percent = true; }; + + if (!x3::phrase_parse(cur, end, + x3::double_[apply_value] + > - (units[apply_units] + | + x3::lit('%')[apply_percent]), + x3::space)) { error_messages.emplace_back("Failed to parse SVG value: '" + std::string(str) + "'"); } @@ -174,46 +191,35 @@ double parse_svg_value(T & error_messages, const char* str, bool & percent) return val; } -template -bool parse_double_list(T & error_messages, const char* str, double* list) +template +bool parse_viewbox(T & error_messages, const char* str, V & viewbox) { - using namespace boost::spirit::qi; - using boost::phoenix::ref; - _1_type _1; - double_type double_; - lit_type lit; - using skip_type = boost::spirit::ascii::space_type; - - if (!phrase_parse(str, str + std::strlen(str), - double_[ref(list[0])=_1] >> -lit(',') >> - double_[ref(list[1])=_1] >> -lit(',') >> - double_[ref(list[2])=_1] >> -lit(',') >> - double_[ref(list[3])=_1], skip_type())) + namespace x3 = boost::spirit::x3; + if ( !x3::phrase_parse(str, str + std::strlen(str), + x3::double_ > -x3::lit(',') > + x3::double_ > -x3::lit(',') > + x3::double_ > -x3::lit(',') > + x3::double_, x3::space, viewbox)) { - error_messages.emplace_back("failed to parse list of doubles from " + std::string(str)); + error_messages.emplace_back("failed to parse SVG viewbox from " + std::string(str)); return false; } return true; } -bool parse_style (char const* str, pairs_type & v) +bool parse_style (char const* str, grammar::pairs_type & v) { - using namespace boost::spirit::qi; - using skip_type = boost::spirit::ascii::space_type; - key_value_sequence_ordered kv_parser; - return phrase_parse(str, str + std::strlen(str), kv_parser, skip_type(), v); + namespace x3 = boost::spirit::x3; + return x3::phrase_parse(str, str + std::strlen(str), grammar::key_value_sequence_ordered , x3::space, v); } bool parse_id_from_url (char const* str, std::string & id) { - using namespace boost::spirit::qi; - using skip_type = boost::spirit::ascii::space_type; - qi::_1_type _1; - qi::char_type char_; - qi::lit_type lit; - return phrase_parse(str, str + std::strlen(str), - lit("url") > "(" > "#" > *(char_ - lit(')'))[boost::phoenix::ref(id) += _1] > ")", - skip_type()); + namespace x3 = boost::spirit::x3; + auto extract_id = [&](auto const& ctx) { id += _attr(ctx); }; + return x3::phrase_parse(str, str + std::strlen(str), + x3::lit("url") > '(' > '#' > *(x3::char_ - ')')[extract_id] > ')', + x3::space); } bool traverse_tree(svg_parser & parser, rapidxml::xml_node const* node) @@ -517,7 +523,7 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node const* node) double width = 0; double height = 0; double aspect_ratio = 1; - double viewbox[4] = {0,0,0,0}; + viewbox vbox = {0,0,0,0}; bool has_viewbox = false; bool has_percent_height = true; bool has_percent_width = true; @@ -535,23 +541,23 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node const* node) auto const* viewbox_attr = node->first_attribute("viewBox"); if (viewbox_attr) { - has_viewbox = parse_double_list(parser.error_messages_, viewbox_attr->value(), viewbox); + has_viewbox = parse_viewbox(parser.error_messages_, viewbox_attr->value(), vbox); } if (has_percent_width && !has_percent_height && has_viewbox) { - aspect_ratio = viewbox[2] / viewbox[3]; + aspect_ratio = vbox.x1 / vbox.y1; width = aspect_ratio * height; } else if (!has_percent_width && has_percent_height && has_viewbox) { - aspect_ratio = viewbox[2] / viewbox[3]; + aspect_ratio = vbox.x1 / vbox.y1; height = height / aspect_ratio; } else if (has_percent_width && has_percent_height && has_viewbox) { - width = viewbox[2]; - height = viewbox[3]; + width = vbox.x1; + height = vbox.y1; } parser.path_.set_dimensions(width, height); diff --git a/src/text/face.cpp b/src/text/face.cpp index 1d3ad7820..b05f0d169 100644 --- a/src/text/face.cpp +++ b/src/text/face.cpp @@ -93,11 +93,11 @@ void font_face_set::add(face_ptr face) faces_.push_back(face); } -void font_face_set::set_character_sizes(double size) +void font_face_set::set_character_sizes(double _size) { for (face_ptr const& face : faces_) { - face->set_character_sizes(size); + face->set_character_sizes(_size); } } diff --git a/src/text/font_feature_settings.cpp b/src/text/font_feature_settings.cpp index 81a62f9dd..cf70c5d01 100644 --- a/src/text/font_feature_settings.cpp +++ b/src/text/font_feature_settings.cpp @@ -26,11 +26,10 @@ #pragma GCC diagnostic push #include -#include +#include #include #pragma GCC diagnostic pop - // stl #include #include @@ -52,23 +51,14 @@ font_feature_settings::font_feature_settings() void font_feature_settings::from_string(std::string const& features) { features_.clear(); - if (std::all_of(features.begin(), features.end(), isspace)) return; - namespace qi = boost::spirit::qi; - qi::char_type char_; - qi::as_string_type as_string; - -#if BOOST_VERSION <= 104800 - // Call correct overload. - using std::placeholders::_1; - void (font_feature_settings::*append)(std::string const&) = &font_feature_settings::append; - if (!qi::parse(features.begin(), features.end(), as_string[+(char_ - ',')][std::bind(append, this, _1)] % ',')) -#else - auto app = [&](std::string const& s) { append(s); }; - if (!qi::parse(features.begin(), features.end(), as_string[+(char_ - ',')][app] % ',')) -#endif - + namespace x3 = boost::spirit::x3; + auto appender = [&](auto const& ctx) + { + this->append(_attr(ctx)); + }; + if (!x3::parse(features.begin(), features.end(), (+(x3::char_ - ','))[appender] % ',')) { throw config_error("failed to parse font-feature-settings: '" + features + "'"); } diff --git a/src/text/placement_finder.cpp b/src/text/placement_finder.cpp index e4adddf3e..e6ae4d185 100644 --- a/src/text/placement_finder.cpp +++ b/src/text/placement_finder.cpp @@ -35,6 +35,7 @@ // stl #include +#include namespace mapnik { diff --git a/src/text/placements/simple.cpp b/src/text/placements/simple.cpp index 800a3d3e3..766d1381d 100644 --- a/src/text/placements/simple.cpp +++ b/src/text/placements/simple.cpp @@ -32,9 +32,7 @@ #pragma GCC diagnostic push #include -#include -#include -#include +#include #include #pragma GCC diagnostic pop @@ -43,12 +41,9 @@ namespace mapnik { -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; -using phoenix::push_back; -using phoenix::ref; +namespace x3 = boost::spirit::x3; -struct direction_name : qi::symbols +struct direction_name : x3::symbols { direction_name() { @@ -64,8 +59,7 @@ struct direction_name : qi::symbols ("X" , EXACT_POSITION) ; } - -}; +} names; // Position string: [POS][SIZE] // [POS] is any combination of @@ -82,21 +76,15 @@ bool parse_positions(std::string const& evaluated_positions, std::vector & direction, std::vector & text_sizes) { - direction_name names; - boost::spirit::ascii::space_type space; - qi::_1_type _1; - qi::float_type float_; - std::string::const_iterator first = evaluated_positions.begin(); - std::string::const_iterator last = evaluated_positions.end(); - bool r = qi::phrase_parse(first, last, - (names[push_back(phoenix::ref(direction), _1)] % ',') - >> *(',' >> float_[push_back(phoenix::ref(text_sizes), _1)]), - space); - if (first != last) - { - return false; - } - return r; + auto push_back_direction = [&](auto const& ctx) { direction.push_back(_attr(ctx));}; + auto push_back_size = [&](auto const& ctx) { text_sizes.push_back(_attr(ctx));}; + auto const first = evaluated_positions.begin(); + auto const last = evaluated_positions.end(); + bool r = x3::phrase_parse(first, last, + (names[push_back_direction] % ',') + >> *(',' >> x3::float_[push_back_size]), + x3::space); + return (r && first != last); } diff --git a/src/text/text_layout.cpp b/src/text/text_layout.cpp index 3a3818c1f..0846ea8d7 100644 --- a/src/text/text_layout.cpp +++ b/src/text/text_layout.cpp @@ -35,6 +35,7 @@ #pragma GCC diagnostic pop #include +#include namespace mapnik { diff --git a/src/text/text_properties.cpp b/src/text/text_properties.cpp index 73210d109..db37f7e26 100644 --- a/src/text/text_properties.cpp +++ b/src/text/text_properties.cpp @@ -39,6 +39,8 @@ #include #pragma GCC diagnostic pop +#include + namespace mapnik { using boost::optional; diff --git a/src/expression_grammar.cpp b/src/transform_expression_grammar_x3.cpp similarity index 77% rename from src/expression_grammar.cpp rename to src/transform_expression_grammar_x3.cpp index 09234a07f..ab3d6a77b 100644 --- a/src/expression_grammar.cpp +++ b/src/transform_expression_grammar_x3.cpp @@ -20,9 +20,11 @@ * *****************************************************************************/ -// NOTE: we define this here in a cpp because def is needed twice: -// once by src/expression.cpp and once by mapnik/transform_expression_grammar_impl.hpp -#include -#include +#include +#include -template struct mapnik::expression_grammar; +namespace mapnik { namespace grammar { + +BOOST_SPIRIT_INSTANTIATE(transform_expression_grammar_type, iterator_type, context_type); + +}} diff --git a/src/webp_reader.cpp b/src/webp_reader.cpp index ca611aeef..f5fec3416 100644 --- a/src/webp_reader.cpp +++ b/src/webp_reader.cpp @@ -37,6 +37,7 @@ extern "C" // stl #include +#include namespace mapnik { diff --git a/src/wkb.cpp b/src/wkb.cpp index f2e1fce6e..cf2fc9704 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -29,6 +29,8 @@ #include #include +#include + namespace mapnik { diff --git a/src/xml_tree.cpp b/src/xml_tree.cpp index 2e2a7df8e..cd6cdaca3 100644 --- a/src/xml_tree.cpp +++ b/src/xml_tree.cpp @@ -38,6 +38,7 @@ // stl #include +#include namespace mapnik { diff --git a/test/unit/color/css_color.cpp b/test/unit/color/css_color.cpp index f1bc17196..a532cb1cf 100644 --- a/test/unit/color/css_color.cpp +++ b/test/unit/color/css_color.cpp @@ -1,63 +1,113 @@ #include "catch.hpp" -#include -#include + #include +#include +#include +#include + #include -TEST_CASE("css color") { +TEST_CASE("CSS color") { SECTION("conversions") { - mapnik::percent_conv_impl conv; - CHECK( conv(1.0) == 3 ); - CHECK( conv(60.0) == 153 ); + using namespace mapnik::css_color_grammar; + CHECK( percent_converter::call(1.0) == 3 ); + CHECK( percent_converter::call(60.0) == 153 ); // should not overflow on invalid input - CHECK( conv(100000.0) == 255 ); - CHECK( conv(-100000.0) == 0 ); - - mapnik::alpha_conv_impl conv2; - CHECK( conv2(0.5) == 128 ); - CHECK( conv2(1.0) == 255 ); - // should not overflow on invalid input - CHECK( conv2(60.0) == 255 ); - CHECK( conv2(100000.0) == 255 ); - CHECK( conv2(-100000.0) == 0 ); - - mapnik::hsl_conv_impl conv3; - mapnik::color c; - conv3(c, 1.0, 1.0, 1.0); - CHECK( c.alpha() == 255 ); - CHECK( c.red() == 3 ); - CHECK( c.green() == 3 ); - CHECK( c.blue() == 3 ); - // invalid - conv3(c, -1, -1, -1); - CHECK( c.alpha() == 255 ); // should not be touched by hsl converter - CHECK( c.red() == 0 ); - CHECK( c.green() == 0 ); - CHECK( c.blue() == 0 ); + CHECK( percent_converter::call(100000.0) == 255 ); + CHECK( percent_converter::call(-100000.0) == 0 ); } - SECTION("hex colors") + SECTION("CSS colors") { - mapnik::css_color_grammar color_grammar; - boost::spirit::qi::ascii::space_type space; - + auto const& color_grammar = mapnik::color_grammar(); + boost::spirit::x3::ascii::space_type space; + { + // rgb + std::string s("rgb(128,0,255)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0xff ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // rgb (percent) + std::string s("rgb(50%,0%,100%)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0xff ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // rgba + std::string s("rgba(128,0,255,0.5)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0x80 ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // rgba (percent) + std::string s("rgba(50%,0%,100%,0.5)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 0x80 ); + CHECK( c.red() == 0x80 ); + CHECK( c.green() == 0x00 ); + CHECK( c.blue() == 0xff ); + } + { + // named colours + std::string s("darksalmon"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 255 ); + CHECK( c.red() == 233 ); + CHECK( c.green() == 150 ); + CHECK( c.blue() == 122 ); + } + // hsl + { + std::string s("hsl(240,50%,50%)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 255 ); + CHECK( c.red() == 64 ); + CHECK( c.green() == 64 ); + CHECK( c.blue() == 191 ); + } + // hsla + { + std::string s("hsla(240,50%,50%,0.5)"); + mapnik::color c; + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( c.alpha() == 128 ); + CHECK( c.red() == 64 ); + CHECK( c.green() == 64 ); + CHECK( c.blue() == 191 ); + } + // hex colours { std::string s("#abcdef"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); CHECK( c.blue() == 0xef ); } - { std::string s("#abcdef12"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0x12 ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); @@ -67,7 +117,7 @@ TEST_CASE("css color") { { std::string s(" #abcdef"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); @@ -77,7 +127,7 @@ TEST_CASE("css color") { { std::string s(" #abcdef12"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0x12 ); CHECK( c.red() == 0xab ); CHECK( c.green() == 0xcd ); @@ -86,22 +136,26 @@ TEST_CASE("css color") { { std::string s("# abcdef"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("# abcdef12"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#ab cdef"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#ab cdef12"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } // hex_color_small @@ -109,7 +163,7 @@ TEST_CASE("css color") { { std::string s("#abc"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -119,7 +173,7 @@ TEST_CASE("css color") { { std::string s("#abcd"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xdd ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -129,7 +183,7 @@ TEST_CASE("css color") { { std::string s(" #abc"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xff ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -139,7 +193,7 @@ TEST_CASE("css color") { { std::string s(" #abcd"); mapnik::color c; - CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); + CHECK( boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); CHECK( c.alpha() == 0xdd ); CHECK( c.red() == 0xaa ); CHECK( c.green() == 0xbb ); @@ -148,22 +202,26 @@ TEST_CASE("css color") { { std::string s("# abc"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("# abcd"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#a bc"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } { std::string s("#a bcd"); - CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) ); + mapnik::color c; + CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) ); } } SECTION("operator<< / to_string()")